Escopo (computação): diferenças entre revisões

Conteúdo apagado Conteúdo adicionado
Linha 87:
Com escopo dinâmico, cada identificador tem uma [[Pilha (informática)|pilha]] global de [[vinculação (computação)|vinculações]]. Introduzindo uma variável local com o nome de ''x'' empilha uma vinculação na pilha global ''x'' (que pode estar vazia), que estará desempilhada quando o fluxo de controle deixar o escopo. Avaliar ''x'' em qualquer contexto sempre produz a vinculação mais ao topo. Em outras palavras, um identificador global refere-se ao identificador associado com o ambiente mais recente. Note-se que isso não pode ser feito em tempo de compilação, porque a pilha de vinculação só existe em tempo de execução, razão pela qual este tipo de delimitação é chamado de ''escopo dinâmico''.
 
Geralmente, alguns [[Bloco (computação)|blocos]] são definidos para criar vinculações cujo tempo de vida útil é o tempo de execução do bloco; isso adiciona algumas funcionalidades do escopo estático para o processo de escopo dinâmico. No entanto, como uma seção de código pode ser chamada de diferentes locais e situações, pode ser difícil determinar desde o início quais vinculações serão aplicadas quando uma variável for utilizada (ou se a sua existência naquele contexto).
<!--
 
<!--
Generally, certain [[block (programming)|block]]s are defined to create bindings whose lifetime is the execution time of the block; this adds some features of static scoping to the dynamic scoping process. However, since a section of code can be called from many different locations and situations, it can be difficult to determine at the outset what bindings will apply when a variable is used (or if one exists at all). .This can be beneficial; application of the [[principle of least knowledge]] suggests that code avoid depending on the ''reasons'' for (or circumstances of) a variable's value, but simply use the value according to the variable's definition. This narrow interpretation of shared data can provide a very flexible system for adapting the behavior of a function to the current state (or policy) of the system. However, this benefit relies on careful documentation of all variables used this way as well as on careful avoidance of assumptions about a variable's behavior, and does not provide any mechanism to detect interference between different parts of a program. As such, dynamic scoping can be dangerous and few modern languages use it. Some languages, like [[Perl]] and [[Common Lisp]], allow the programmer to choose static or dynamic scoping when defining or redefining a variable. [[Logo (programming language)|Logo]] and [[Emacs lisp]] are examples of languages that use dynamic scoping.
 
Dynamic scoping is fairly easy to implement. To find an identifier's value, the program could traverse the runtime stack, checking each activation record (each function's stack frame) for a value for the identifier. In practice, this is made more efficient via the use of an [[association list]], which is a stack of name/value pairs. Pairs are pushed onto this stack whenever declarations are made, and popped whenever variables go out of scope.<ref>Scott 2006, p. 135</ref> An alternate strategy that is considerably faster is to make use of a ''central reference table'', which associates each name with its current meaning. This avoids a linear search during runtime to find a particular name, but maintaining this table is more complex.<ref>Scott 2006, p. 135</ref> Note that both of these strategies assume a last-in-first-out (LIFO) ordering to bindings for any one variable; in practice all bindings are so ordered.