Règles de portée lexicale
Comprenez comment R trouve les variables en parcourant les environnements parents.
Règles de portée lexicale est une leçon R Academy gratuite sur CoddyKit. Ceci est la leçon 2 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage R Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours R Academy comprend 4 leçons au total.
Qu’est-ce que la portée lexicale ?
La portée lexicale signifie qu’une fonction recherche les variables là où elle a été définie, et non là où elle est appelée. R utilise la portée lexicale. Ce comportement est prévisible : l’environnement dans lequel une fonction effectue ses recherches est fixé lors de sa création, et non lors de son appel.
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
})Portée lexicale et portée dynamique
Avec la portée dynamique (utilisée dans certains autres langages), une fonction trouverait la variable dans l’environnement appelant. R utilise plutôt la portée lexicale : l’environnement englobant au moment de la définition est toujours prioritaire. Les fonctions se comportent ainsi de manière cohérente, quel que soit l’endroit depuis lequel elles sont appelées.
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 definitionVariables libres et fermetures
Une variable utilisée dans une fonction qui n’est ni un paramètre ni une affectation locale est une variable libre. R la recherche dans l’environnement englobant. Une fonction qui capture des variables libres est appelée une fermeture.
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')Les fermetures capturent les environnements
Chaque fois qu’une fonction génératrice est appelée, la fonction renvoyée (la fermeture) capture un instantané de l’environnement englobant. Des appels différents produisent des fermetures avec des valeurs capturées différentes — c’est le fondement des générateurs de fonctions.
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')L’opérateur <<-
<<- (affectation à double flèche) remonte la chaîne des parents à la recherche d’une liaison existante et la modifie sur place. Si aucune liaison n’est trouvée, il en crée une dans l’environnement global. C’est l’outil permettant de modifier, depuis l’intérieur d’une fonction, une variable située dans une portée englobante.
count <- 0
increment <- function() {
count <<- count + 1
}
increment()
increment()
increment()
cat('count:', count, '\n')<<- avec les fermetures
L’utilisation la plus idiomatique de <<- se fait dans les fermetures qui doivent mettre à jour un état dans leur environnement englobant. Cela crée des fonctions avec état — des fonctions dotées d’une mémoire persistante entre les appels.
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')Portée dans les fonctions imbriquées
Lorsque des fonctions sont imbriquées, la fonction interne peut voir les variables définies dans la fonction externe. L’environnement de la fonction externe devient l’environnement englobant de la fonction interne, ce qui forme une chaîne.
outer <- function() {
greeting <- 'Hello'
inner <- function(name) {
# greeting comes from outer's environment
paste(greeting, name)
}
inner('World')
}
cat(outer(), '\n')Parcourir la chaîne des portées
Lorsqu’il recherche une variable, R parcourt les environnements dans cet ordre : propre à la fonction → englobant → englobant de l’englobant → ... → global → chemin de recherche → base → vide. La première correspondance est retenue.
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() d’une fonction
Vous pouvez examiner l’environnement englobant de n’importe quelle fonction avec environment(f). Vous pouvez même le définir avec environment(f) <- e, ce qui modifie l’endroit où la fonction recherche les variables libres — une technique puissante, mais avancée.
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')Fermeture en pratique : mémorisation
La portée lexicale et <<- permettent la mémorisation : mettez en cache les résultats coûteux d’une fonction dans l’environnement de la fermeture. Le cache est privé à la fermeture et persiste entre les appels.
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')Piège de la portée lexicale : variables de boucle
Un piège classique consiste à créer des fermetures dans une boucle. Toutes les fermetures capturent le même environnement, et non un instantané de la valeur. Lorsqu’elles sont finalement appelées, la variable de boucle contient sa valeur finale.
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')Vérification rapide
Dans la portée lexicale de R, où une fonction recherche-t-elle une variable libre (qui n’est pas définie dans la fonction elle-même) ?
Portée lexicale : points essentiels
Points essentiels concernant la portée lexicale :
- R utilise la portée lexicale — les fonctions recherchent les variables là où elles ont été définies
- Une fonction capture son environnement englobant sous forme de fermeture
- Les variables libres sont résolues au moment de la définition, et non de l’appel
<<-modifie une liaison dans la chaîne des parents (ou dans l’environnement global si elle n’est pas trouvée)- Fermetures +
<<-= fonctions avec état et état privé persistant - Piège des fermetures dans les boucles : utilisez
local()pour imposer un nouvel environnement à chaque itération
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')Apprends R avec un tuteur IA — gratuit
Écris et exécute du vrai code dans ton navigateur, obtiens de l'aide instantanée d'un tuteur IA disponible 24h/24, et reprends là où tu t'es arrêté sur le web ou dans l'app.
- Cours
- 43
- Leçons
- 159
Questions Fréquemment Posées
La leçon « Règles de portée lexicale » est-elle gratuite ?
Oui — le texte complet de « Règles de portée lexicale » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours R Academy, passe à CoddyKit PRO. Le cours R Academy comprend 4 leçons au total.
Qu'est-ce que j'apprendrai dans « Règles de portée lexicale » ?
Comprenez comment R trouve les variables en parcourant les environnements parents. Tu pratiques R Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.
Dois-je avoir de l'expérience pour commencer R Academy ?
Aucune expérience préalable n'est requise. R Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 2 sur 4.
Combien de temps prend la leçon « Règles de portée lexicale » ?
La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.
Peux-tu écrire et exécuter du code dans cette leçon R Academy ?
Oui. Chaque leçon R Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.
Toutes les leçons de ce cours
- Qu’est-ce qu’un environnement dans R ?
- Règles de portée lexicale
- Portée globale ou locale
- Créer et inspecter des environnements