Given the following function
f <- function(x) {
g <- function(y) {
y + z
}
z <- 4
x + g(x)
}
If one runs the following code in R why is the answer 10? I'm a little confused about how y plays into this question.
z <- 10
f(3)
The scoping rules of the language define how value is assigned to free variables. R uses lexical scoping, which says the value for z is searched for in the environment where the function was defined. Note: Lexical scoping is also referred to as statical scoping.
What are scope functions? In Kotlin, scope functions are used to execute a block of code within the scope of an object. Generally, you can use scope functions to wrap a variable or a set of logic and return an object literal as your result. Therefore, we can access these objects without their names.
options() function examines a variety of global options which affect the way in which R computes and displays its results. ... : any options can be defined, using name = value. However, only the ones below are used in base R. Options can also be passed by giving a single unnamed argument which is a named list.
To sum up, in static scoping the compiler first searches in the current block, then in global variables, then in successively smaller scopes. Dynamic Scoping: With dynamic scope, a global identifier refers to the identifier associated with the most recent environment and is uncommon in modern languages.
R uses lexical scoping which means that if an object is referenced but not defined in a function then it is looked for in the environment in which the function is defined, not the environment from which it was called.
z is referenced in g but is not defined in g so it looks to the environment in which g is defined and that is the environment within f so g uses z = 4.
Actually in this case the environment that g is defined in is the same as the environment from which g is called so any way you look at it z = 4 must be used. If functions defaulted to the global environment to look for objects not defined in the function then it would use z = 10 but that is not how R works.
If for some reason you wanted to force g to look for z in the environment in which f is called then you could do this (where parent.frame()
refers to the environment from which f is called).
f2 <- function(x, envir = parent.frame()) {
g <- function(y) {
y + with(envir, z)
}
z <- 4
x + g(x)
}
z <- 10
f2(3)
## [1] 16
or we could use y + envir$z
except that that would only look in the parent frame and not in its ancestors whereas with
will look in ancestors of the parent frame if not found in the parent frame.
An alternative is to change g's environment like this so that it looks into envir
for objects not found in g:
f3 <- function(x, envir = parent.frame()) {
g <- function(y) {
y + z
}
environment(g) <- envir
z <- 4
x + g(x)
}
z <- 10
f3(3)
## [1] 16
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With