7

I'd like to specify functions in a flexible way. How can I make sure that the environment of a given function does not change when I create another function just after it.

To illustrate, this works properly:

make.fn2 <- function(a, b) {
    fn2 <- function(x) {
        return( x + a + b )
    }
    return( fn2 )
}

a <- 2; b <- 3
fn2.1 <- make.fn2(a, b)
fn2.1(3)    # 8
fn2.1(4)    # 9

a <- 4
fn2.2 <- make.fn2(a, b)
fn2.2(3)    # 10
fn2.1(3)    # 8

This does not

make.fn2 <- function(a, b) {
fn2 <- function(x) {
    return( x + a + b )
}
return( fn2 )
}

a <- 2; b <- 3
fn2.1 <- make.fn2(a, b)

a <- 4
fn2.2 <- make.fn2(a, b)

fn2.1(3)    # 10
fn2.1(4)    # 11
fn2.2(3)    # 10
fn2.1(3)    # 10

1 Answer 1

8

This is due to lazy evaluation. The function is not actually constructed until it is called. So, in the second case, both times the new version of a is picked up. See also this other question.

You can solve this issue by using force:

make.fn2 <- function(a, b) {
    force(a)
    force(b)
    fn2 <- function(x) {
        return( x + a + b )
    }
    return( fn2 )
}

This forces the function to pick up the values of a and b when the function is created, not when the function is called. It produces the correct output:

> a <- 2; b <- 3
> fn2.1 <- make.fn2(a, b)
> 
> a <- 4
> fn2.2 <- make.fn2(a, b)
> 
> fn2.1(3)    # 10
[1] 8
> fn2.1(4)    # 11
[1] 9
> fn2.2(3)    # 10
[1] 10
> fn2.1(3)    # 10
[1] 8
> 
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.