andrewH
andrewH

Reputation: 2321

R: Where are formals for a function stored in memory?

When a function has been defined but has not yet been called, do the formals that do not have default values exist? If they do, do they exist in the execution environment, or in the environment where the function definition is located, or somewhere else?

If a function has been defined but not yet called, and a formal has been assigned a default value, does that value exist? If it does, in what environment does it exist? If the default expression evaluates to a constant, has the formal been assigned to that value, to be overwritten when the function is called if a value is supplied? If not, in what environment is that (fixed) default value located between the moment of definition and the time the function is called?

After the function has been called and actual or default values have been assigned to the formals, passed into the body, and if necessary scoped and/or evaluated, do the formals continue to exist? If so, in what environment do they then exist?

Upvotes: 4

Views: 233

Answers (1)

Len Greski
Len Greski

Reputation: 10875

The formals for a function exist as objects within the environment of a function once an instance of the function is loaded into memory by being called. In Advanced R, Hadley Wickham calls this environment the execution environment. The memory locations of the objects can be accessed via pryr::address().

As an example I'll use a modified version of code that I previously wrote to illustrate memory locations in the makeVector() function from the second programming assignment for the Johns Hopkins R Programming course on coursera.org.

makeVector <- function(x = 200) {
     library(pryr)
     message(paste("Address of x argument is:",address(x)))
     message(paste("Number of references to x is:",refs(x)))
     m <- NULL
     set <- function(y) {
          x <<- y
          message(paste("set() address of x is:",address(x)))
          message(paste("Number of references to x is:",refs(x)))
          m <<- NULL
     }
     get <- function() x
     setmean <- function(mean) m <<- mean
     getmean <- function() m
     list(set = set, get = get,
          setmean = setmean,
          getmean = getmean)
}

As coded above, makeVector() is an S3 object, which means we can access objects within its environment via getters and setters, also known as mutator methods.

We can load an instance of the makeVector() object into memory and query the address and value of x with the following code.

makeVector()$get()

...and the result:

> makeVector()$get()
Address of x argument is: 0x1103df4e0
Number of references to x is: 0
[1] 200
> 

As we can see from the output, x does have a memory location, but there are no other objects that contain references to it. Also, x was set to its default value of a vector of length 1 with the value 200.

I provide a detailed walkthrough of the objects in the makeVector() environment in my answer to Caching the Mean of a Vector in R.

Regarding the question about how long the formals exist in memory, they exist as long as the environment created to store the called instance of the function is in memory. Since the garbage collector operates on objects that have no external references, if the function instance is not saved to an object, it is eligible for garbage collection as soon as the function call returns a result to the parent environment.

Upvotes: 4

Related Questions