Create, modify, and inspect environments
Recognize special environments
Understand how environments power lexical scoping and namespaces
Generally, an environment is similar to a named list, with four important exceptions:
Every name must be unique.
The names in an environment are not ordered.
An environment has a parent.
Environments are not copied when modified.
{rlang}{rlang}#> <environment: 0x55e71594cdd0>
#> Parent: <environment: global>
#> Bindings:
#> • a: <lgl>
#> • b: <chr>
#> • c: <dbl>
#> • d: <int>
The current environment is where code is currently executing
The global environment is your current environment when working interactively
#> <environment: 0x55e71992c5f0>
#> [[1]] <env: 0x55e71992c5f0>
#> [[2]] $ <env: global>

#> [[1]] <env: 0x55e71992c5f0>
#> [[2]] $ <env: global>
#> [[3]] $ <env: package:stats>
#> [[4]] $ <env: package:graphics>
#> [[5]] $ <env: package:grDevices>
#> [[6]] $ <env: package:utils>
#> [[7]] $ <env: package:datasets>
#> [[8]] $ <env: package:methods>
#> [[9]] $ <env: Autoloads>
#> [[10]] $ <env: package:base>
#> [[11]] $ <env: empty>
<<-Regular assignment (<-) always creates a variable in the current environment
Super assignment (<<-) does a few things:
modifies the variable if it exists in a parent environment
creates the variable in the global environment if it does not exist
$, [[, or {rlang} functions$, [[, or {rlang} functions`rlang::env_bind_lazy() creates delayed bindings
rlang::env_bind_active() creates active bindings
The search path is the order in which R will look through environments for objects
Attached packages become a parent of the global environment
The immediate parent of the global environment is that last package attached
#> [[1]] $ <env: global>
#> [[2]] $ <env: package:stats>
#> [[3]] $ <env: package:graphics>
#> [[4]] $ <env: package:grDevices>
#> [[5]] $ <env: package:utils>
#> [[6]] $ <env: package:datasets>
#> [[7]] $ <env: package:methods>
#> [[8]] $ <env: Autoloads>
#> [[9]] $ <env: package:base>
#> [[1]] $ <env: global>
#> [[2]] $ <env: package:rlang>
#> [[3]] $ <env: package:stats>
#> [[4]] $ <env: package:graphics>
#> [[5]] $ <env: package:grDevices>
#> [[6]] $ <env: package:utils>
#> [[7]] $ <env: package:datasets>
#> [[8]] $ <env: package:methods>
#> [[9]] $ <env: Autoloads>
#> [[10]] $ <env: package:base>
g() is being bound by the environment e but binds the global environment
The function environment is the global environment but the binding environment is e
Every package has an underlying namespace
Every function is associated with a package environment and namespace environment
Package environments contain exported objects
Namespace environments contain exported and internal objects
Functions create a new environment to use whenever executed
The execution environment is a child of the function environment
Execution environments are garbage collected on function exit
The caller environment is the environment from which the function was called
Accessed with rlang::caller_env()
The call stack is created within the caller environment
R uses lexical scoping: it looks up the values of names based on how a function is defined, not how it is called. “Lexical” here is not the English adjective that means relating to words or a vocabulary. It’s a technical CS term that tells us that the scoping rules use a parse-time, rather than a run-time structure. - Chapter 6 - functions
Usecase include:
Avoiding copies of large data
Managing state within a package
As a hashmap