[R] functional (?) programming in r

Wacek Kusnierczyk Waclaw.Marcin.Kusnierczyk at idi.ntnu.no
Tue Nov 18 09:41:18 CET 2008


jim holtman wrote:
> You can use the 'local' function to make sure you create a value of
> 'i' that is defined when the function is defined:
>
>   
>> funcs = lapply(1:5, function(i)local({i; function(){ i}}))
>> funcs[[3]]()
>>     
> [1] 3
>   
>> funcs[[2]]()
>>     
> [1] 2
>   


ok, but that's all ways to go around the promise mechanism.

following gabor's suggestion, i read sec. 4.3 in the r language manual,
where it is explained that actual arguments are received as promises, to
be forced when their values are needed.  that's what i knew already, and
what i needed to learn i haven't, because it is left underspecified:
what it means for a promise to be *needed*.

in the pursued example, i think what causes me to think the design
should (from my r-naive point of view) be changed is when a promise is
forced, i.e., the notion of need.

in the following:

lapply(1:2, function(i) i)
# c(1,2)

the result is as expected, because the function, when called, creates a
new syntactic environment in which i is bound to a promise, and since
the function returns i, i is needed, the promise is forced, and the
current (in the sense of the loop iteration) value looked-up in the
enclosing environment is returned.

in the following:

sapply(lapply(1:2, function(i) function() i), function(f) f())
#c(2,2)

the result is not as expected (by me), because the function (the
leftmost one), when called, creates a new syntactic environment in which
i is bound to a promise, and then returns a closure whose closure
environment contains i as an unevaluated promise.  that is, for r,
creating a function that returns (or uses in any way) the value of a
non-local promise does not force the promise.  that is, for r, embedding
a promise in a closure environment does not constitute a need for the value:

f = function(var) function() var
x = 1
g = f(x)
# g has a var in its closure environment, and var is a still unforced
promise
x = 2
g() 
# forcing the promise now


thinking functionally, it would be enough to modify the semantics of
need so that thomas' suggestion:

sapply(lapply(1:2, function(i) { force(i); function() i }), function(f) f())
# c(1,2)

could actually be semantically equivalent to the version above (without
explicit force).  that is, the promise mechanism would not interfere
with functional semantics if embedding a promise in a closure
constituted a need for its value.

i thought (based on some sections in one of the r manuals) that promises
are intended to spare unnecessary computations without making the user
aware of the mechanism.  thomas' solution above forces a user to
explicitly operate on promises to achieve functional behaviour;  if the
correction is not used, the promise mechanism becomes visible by the
result.  in both ways, the mechanism is exposed, which seems (to me) to
contradict the idea.

i'd like someone to kindly point me to a section in an r manual where
the notion of need is explained to the last gory detail.  or perhaps i
should reach the code.


vQ

---
disclaimer: this post contains only my personal views and opinions, and
any positive or negative correlation with the views and opinions of
other r users and the r team is purely incidental.  where terms such as
"should" are used, they should be read as "should, in waceks view,".



More information about the R-help mailing list