Dear All:
I have a question regarding the behavior of functions.
Say I define a function that returns another function :
A <- function(parameters) {
# calculations w/ parameters returning 'y'
tmpf <- function(x) { # function of 'y' }
return(tmpf)
}
The value of the parameters are stored in an environment local to the
function. Then I call
x<- something
B<-A(x)
When R executes this last statement, does it perform all the
calculations inside function A again (i.e., all the calculations that
yield 'y')
or the value of 'y' is already stored in the function's local environment ?
Many thanks.
Paulo Gustavo Grahl, CFA
Functions returning functions
6 messages · Paulo Grahl, Romain Francois, Wacek Kusnierczyk +2 more
Paulo Grahl wrote:
Dear All:
I have a question regarding the behavior of functions.
Say I define a function that returns another function :
A <- function(parameters) {
# calculations w/ parameters returning 'y'
tmpf <- function(x) { # function of 'y' }
return(tmpf)
}
The value of the parameters are stored in an environment local to the
function. Then I call
x<- something
B<-A(x)
When R executes this last statement, does it perform all the
calculations inside function A again
no, see this:
> f <- function( x = 3){
+ function( ){}
+ }
> g <- f()
> ls.str( environment(g) )
x : num 3
> h <- f(6)
> ls.str( environment(h) )
x : num 6
> ls.str( environment(g) )
x : num 3
See also colorRampPalette which uses this feature:
> colorRampPalette
function (colors, ...)
{
ramp <- colorRamp(colors, ...)
function(n) {
x <- ramp(seq.int(0, 1, length.out = n))
rgb(x[, 1], x[, 2], x[, 3], maxColorValue = 255)
}
}
<environment: namespace:grDevices>
> pal <- colorRampPalette( c("blue", "white", "red") )
> pal
function (n)
{
x <- ramp(seq.int(0, 1, length.out = n))
rgb(x[, 1], x[, 2], x[, 3], maxColorValue = 255)
}
<environment: 0x99aba4c>
> ls.str( environment( pal ) )
colors : chr [1:3] "blue" "white" "red"
ramp : function (x)
(i.e., all the calculations that yield 'y') or the value of 'y' is already stored in the function's local environment ? Many thanks. Paulo Gustavo Grahl, CFA
Romain Francois Independent R Consultant +33(0) 6 28 91 30 30 http://romainfrancois.blog.free.fr
Paulo Grahl wrote:
Dear All:
I have a question regarding the behavior of functions.
Say I define a function that returns another function :
A <- function(parameters) {
# calculations w/ parameters returning 'y'
tmpf <- function(x) { # function of 'y' }
return(tmpf)
}
The value of the parameters are stored in an environment local to the
function.
consider this example:
foo = function(a, b)
function(c)
if (c) a else b
x = 1
y = 2
bar = foo(x, y)
bar(TRUE)
# 1
x = 0
bar(TRUE)
# 1, not 0
y = 0
bar(FALSE)
# 0, not 2
vQ
On Wed, May 20, 2009 at 7:48 AM, Wacek Kusnierczyk
<Waclaw.Marcin.Kusnierczyk at idi.ntnu.no> wrote:
Paulo Grahl wrote:
Dear All:
I have a question regarding the behavior of functions.
Say I define a function that returns another function :
A <- function(parameters) {
? ? ?# calculations w/ parameters returning 'y'
? ? ?tmpf <- function(x) { # function of 'y' }
? ? ?return(tmpf)
}
The value of the parameters are stored in an environment local to the
function.
consider this example: ? ?foo = function(a, b) ? ? ? function(c) ? ? ? ? ?if (c) a else b ? ?x = 1 ? ?y = 2 ? ?bar = foo(x, y) ? ?bar(TRUE) ? ?# 1 ? ?x = 0 ? ?bar(TRUE) ? ?# 1, not 0 ? ?y = 0 ? ?bar(FALSE) ? ?# 0, not 2
The last one is due to lazy evaluation. Try
repeating it with this variation:
foo2 = function(a, b) {
force(a); force(b)
function(c) if (c) a else b
}
which forces a and b to be evaluated right away.
Romain Francois wrote:
Paulo Grahl wrote:
Dear All:
I have a question regarding the behavior of functions.
Say I define a function that returns another function :
A <- function(parameters) {
# calculations w/ parameters returning 'y'
tmpf <- function(x) { # function of 'y' }
return(tmpf)
}
The value of the parameters are stored in an environment local to the
function. Then I call
x<- something
B<-A(x)
When R executes this last statement, does it perform all the
calculations inside function A again
no
... but there are ways around it
f <- function( x = 3 ){
# y will be get a value the first time
# the function created below is called
delayedAssign( "y", {
cat( "\nevaluating `y` right now\n" )
x + 5
} )
# z will get a new value each time the function
# created below is called
makeActiveBinding( "z", function( data ){
if( missing(data) ){
cat( "\nevaluating `z` right now\n" )
rnorm(x)
}
}, environment() )
function( ){
list( y, z )
}
}
> h <- f()
> h()
evaluating `y` right now
evaluating `z` right now
[[1]]
[1] 8
[[2]]
[1] 1.0991189 -1.1033016 -0.5410733
> h()
evaluating `z` right now
[[1]]
[1] 8
[[2]]
[1] 0.7102276 -0.6371956 -0.7703179
> environment(h)[["z"]]
evaluating `z` right now
[1] -0.6713595 2.2006114 0.9335674
> environment(h)[["z"]]
evaluating `z` right now
[1] 0.1243523 0.6178176 -0.9043380
see this:
f <- function( x = 3){
+ function( ){}
+ }
g <- f() ls.str( environment(g) )
x : num 3
h <- f(6) ls.str( environment(h) )
x : num 6
ls.str( environment(g) )
x : num 3 See also colorRampPalette which uses this feature:
colorRampPalette
function (colors, ...)
{
ramp <- colorRamp(colors, ...)
function(n) {
x <- ramp(seq.int(0, 1, length.out = n))
rgb(x[, 1], x[, 2], x[, 3], maxColorValue = 255)
}
}
<environment: namespace:grDevices>
pal <- colorRampPalette( c("blue", "white", "red") )
pal
function (n)
{
x <- ramp(seq.int(0, 1, length.out = n))
rgb(x[, 1], x[, 2], x[, 3], maxColorValue = 255)
}
<environment: 0x99aba4c>
ls.str( environment( pal ) )
colors : chr [1:3] "blue" "white" "red" ramp : function (x)
(i.e., all the calculations that yield 'y') or the value of 'y' is already stored in the function's local environment ? Many thanks. Paulo Gustavo Grahl, CFA
Romain Francois Independent R Consultant +33(0) 6 28 91 30 30 http://romainfrancois.blog.free.fr
An embedded and charset-unspecified text was scrubbed... Name: not available URL: <https://stat.ethz.ch/pipermail/r-help/attachments/20090520/1bde59fb/attachment-0001.pl>