Regras de escopo léxico
Entenda como R encontra variáveis pesquisando ambientes-pai.
Regras de escopo léxico é uma aula grátis de R Academy no CoddyKit. Esta é a aula 2 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de R Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de R Academy inclui 4 aulas no total.
O que é escopo léxico
Escopo léxico significa que uma função procura variáveis onde foi definida, não onde é chamada. O R usa escopo léxico. Isso é previsível: o ambiente pesquisado por uma função é fixado no momento de sua criação, não no momento da chamada.
x <- 'global'
f <- function() {
cat('x =', x, '\n') # looks where f was defined (global)
}
local({
x <- 'local to local block'
f() # still prints global x, not the local one
})Escopo léxico versus dinâmico
No escopo dinâmico (usado em algumas outras linguagens), uma função encontraria a variável no ambiente de chamada. O R usa escopo léxico: o ambiente envolvente no momento da definição sempre prevalece. Isso faz com que as funções se comportem de maneira consistente, independentemente de onde sejam chamadas.
val <- 100
make_adder <- function(n) {
# n is captured from the definition environment
function(x) x + n
}
add10 <- make_adder(10)
add20 <- make_adder(20)
cat(add10(5), '\n') # 15 — n=10 from definition
cat(add20(5), '\n') # 25 — n=20 from definitionVariáveis livres e fechamentos
Uma variável dentro de uma função que não é um parâmetro nem uma atribuição local é uma variável livre. O R a procura no ambiente envolvente. Uma função que captura variáveis livres é chamada de fechamento.
base_rate <- 0.05 # free variable captured by f
f <- function(principal, years) {
principal * (1 + base_rate) ^ years
}
cat('5 yr return:', f(1000, 5), '\n')
# Even if we change base_rate later:
base_rate <- 0.08
cat('New rate return:', f(1000, 5), '\n')Fechamentos capturam ambientes
Cada vez que uma função fábrica é chamada, a função retornada (fechamento) captura uma imagem do ambiente envolvente. Chamadas diferentes produzem fechamentos com valores capturados diferentes — essa é a base das fábricas de funções.
power_fn <- function(exp) {
function(x) x ^ exp
}
square <- power_fn(2)
cube <- power_fn(3)
cat('square(4) =', square(4), '\n')
cat('cube(3) =', cube(3), '\n')O operador <<-
<<- (atribuição com seta dupla) procura na cadeia de pais um vínculo existente e o modifica no próprio lugar. Se nenhum vínculo for encontrado, ele cria um no ambiente global. Essa é a ferramenta para modificar uma variável em um escopo envolvente a partir de dentro de uma função.
count <- 0
increment <- function() {
count <<- count + 1
}
increment()
increment()
increment()
cat('count:', count, '\n')<<- com fechamentos
O uso mais idiomático de <<- é dentro de fechamentos que precisam atualizar o estado em seu ambiente envolvente. Isso cria funções com estado — funções com memória persistente entre chamadas.
make_counter <- function() {
n <- 0
list(
increment = function() n <<- n + 1,
get = function() n,
reset = function() n <<- 0
)
}
ctr <- make_counter()
ctr$increment()
ctr$increment()
cat('Count:', ctr$get(), '\n')
ctr$reset()
cat('After reset:', ctr$get(), '\n')Escopo em funções aninhadas
Quando as funções são aninhadas, a função interna pode acessar variáveis definidas na função externa. O ambiente da função externa se torna o ambiente envolvente da função interna, formando uma cadeia.
outer <- function() {
greeting <- 'Hello'
inner <- function(name) {
# greeting comes from outer's environment
paste(greeting, name)
}
inner('World')
}
cat(outer(), '\n')Pesquisando a cadeia de escopos
Quando o R procura uma variável, ele pesquisa os ambientes nesta ordem: próprio da função → envolvente → envolvente do envolvente → ... → global → caminho de pesquisa → base → vazio. A primeira correspondência prevalece.
x <- 'global'
f <- function() {
x <- 'local to f'
g <- function() {
# g has no x, so looks in f's env
cat('g sees x =', x, '\n')
}
g()
}
f()environment() de uma função
Você pode inspecionar o ambiente envolvente de qualquer função com environment(f). Também pode defini-lo com environment(f) <- e, alterando onde a função procurará variáveis livres — uma técnica poderosa, porém avançada.
x <- 'global_x'
f <- function() x
cat('f sees:', f(), '\n')
# Change f's enclosing environment
my_env <- new.env(parent = emptyenv())
my_env$x <- 'env_x'
environment(f) <- my_env
cat('f now sees:', f(), '\n')Fechamento prático: memoização
O escopo léxico + <<- permite fazer memoização: armazene resultados dispendiosos da função no ambiente do fechamento. O cache é privado ao fechamento e persiste entre chamadas.
make_memoized_fib <- function() {
cache <- c()
function(n) {
if (!is.null(cache[n])) return(cache[n])
if (n <= 1) { cache[n] <<- n; return(n) }
result <- Recall(n-1) + Recall(n-2)
cache[n] <<- result
result
}
}
fib <- make_memoized_fib()
cat(sapply(0:8, fib), '\n')Armadilha do escopo léxico: variáveis de laço
Uma armadilha clássica é criar fechamentos dentro de um laço. Todos os fechamentos capturam o mesmo ambiente, não uma imagem do valor. Quando forem chamados, a variável do laço já terá seu valor final.
fns <- vector('list', 3)
for (i in 1:3) {
local({
captured_i <- i
fns[[captured_i]] <<- function() captured_i
})
}
cat(fns[[1]](), fns[[2]](), fns[[3]](), '\n')Verificação rápida
Com o escopo léxico do R, onde uma função procura uma variável livre (que não foi definida na própria função)?
Escopo léxico: principais conclusões
Principais conclusões sobre escopo léxico:
- O R usa escopo léxico — as funções procuram variáveis onde foram definidas
- Uma função captura seu ambiente envolvente como um fechamento
- As variáveis livres são resolvidas no momento da definição, não da chamada
<<-modifica um vínculo na cadeia de pais (ou no ambiente global, se não for encontrado)- Fechamentos +
<<-= funções com estado privado persistente - Armadilha de fechamentos em laços: use
local()para forçar um novo ambiente a cada iteração
make_multiplier <- function(factor) {
function(x) x * factor
}
double <- make_multiplier(2)
triple <- make_multiplier(3)
cat('double(7):', double(7), '\n')
cat('triple(7):', triple(7), '\n')
cat('double env factor:', get('factor', envir = environment(double)), '\n')Perguntas Frequentes
A aula “Regras de escopo léxico” é grátis?
Sim — o texto completo de “Regras de escopo léxico” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de R Academy, atualize para CoddyKit PRO. O curso de R Academy inclui 4 aulas no total.
O que vou aprender em “Regras de escopo léxico”?
Entenda como R encontra variáveis pesquisando ambientes-pai. Você pratica R Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar R Academy?
Nenhuma experiência prévia é necessária. R Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 2 de 4.
Quanto tempo leva a aula “Regras de escopo léxico”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de R Academy?
Sim. Cada aula de R Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- O que é um ambiente em R?
- Regras de escopo léxico
- Escopo global versus local
- Criando e inspecionando ambientes