Re: [Rd] delayedAssign

From: Luke Tierney <luke_at_stat.uiowa.edu>
Date: Thu, 27 Sep 2007 08:54:51 -0500 (CDT)

On Thu, 27 Sep 2007, Gabor Grothendieck wrote:

> Thanks for the explanation.
>
> For lists either: (a) promises should be evaluated as they
> enter the list or (b) promises evaluated as they exit the
> list (i.e. as they are compared, inspected, etc.).

What makes you conclude that this is what "should" happen?

Again, promises are internal. We could, and maybe will, eliminate promises in favor of a mark on bindings in environments that indicates that they need to be evaluated. At the R level this woud produce the same behavior as we currently (intend to) have.

If we allowed lazy structures outside of bindings then I still don't see how (b) "should" happen. With Scheme-like semantics we would definitely NOT want this to happen; with Haskell-like semantics any attempt to look at the value (including priting) would result in evaluation (and replacing the promise/thunk/whatever by its value).

> I gather
> the intent was (a) but it does not happen that way due to
> a bug in R. Originally I thought (b) would then occur but
> my surprise was that it does not occur either which is why
> I feel its more serious than I had originally thought.
>
> I think its ok if promises only exist in environments and not
> lists. Items that would be on my wishlist would be to be able
> to do at R level the two mentioned previously
>
> https://stat.ethz.ch/pipermail/r-devel/2007-September/046943.html

I am still not persuaded that tools for inspecting environments are worth the time and effort required but I am prepared to be.

Best,

luke

>
> and thirdly an ability to get the evaluation environment, not just the
> expression,
> associated with a promise -- substitute only gets the expression.
> Originally I thought I would need some or all of these wish items
> and then thought not but am back to the original situation again as I use
> them more and realize that they are at least important
> for debugging (its very difficult to debug situations involving promises as
> there is no way to inspect the evaluation environment so you are never sure
> which environment a given promise is evaluating in) and possibly
> for writing programs as well.
>
> On 9/27/07, Luke Tierney <luke_at_stat.uiowa.edu> wrote:
>> On Wed, 26 Sep 2007, Gabor Grothendieck wrote:
>>
>>> I thought that perhaps the behavior in the previous post,
>>> while inconsistent with the documentation, was not all that
>>> harmful but I think its related to the following which is a potentially
>>> serious bug.
>>
>> The previous discussion already established that as.list of an
>> environment should not return a list with promises in as promises
>> should not be visible at the R level. (Another loophole that needs
>> closing is $ for environments). So behavior of results that should not
>> exist is undefined and I cannot see how any such behavior is a further
>> bug, serious or otherwise.
>>
>>> z is a list with a single numeric component,
>>> as the dput output verifies,
>>
>> Except it isn't, as print or str verify, which might be a problem if z
>> was an input these functions should expect, but it isn't.
>>
>>> yet we cannot compare its first element
>>> to 7 without getting an error message.
>>>
>>> Later on we see that its because it thinks that z[[1]] is of type "promise"
>>
>> As z[[1]] is in fact of type promise that would seem a fairly
>> reasonable thing to think at this point ...
>>
>>> and even force(z[[1]]) is of type "promise".
>>
>> which is consistent with what force is documented to do. The
>> documentation is quite explicit that force does not do what you seem
>> to be expecting. That documentation is from a time when delay()
>> existed to produce promises at the R level, which was a nightmare
>> because of all the peculiarities it introduced, which is why it was
>> removed.
>>
>> force is intended for one thing only -- replacing code like this:
>>
>> # I know the following line look really stupid and you will be
>> # tempted to remove it for efficiency but DO NOT: it is needed
>> # to make sure that the formal argument y is evaluated at this
>> # point.
>> y <- y
>>
>> with this:
>>
>> force(y)
>>
>> which seems much clearer -- at least it suggest you look at the help
>> page for force to see what it does.
>>
>> At this point promises should only ever exist in bindings in
>> environments. If we wanted lazy evaluation constructs more widely
>> there are really only two sensible options:
>>
>> The Scheme option where a special function delay creates a deferred
>> evaluation and another, called force in Scheme, forces the evaluation
>> but there is no implicit forcing
>>
>> or
>>
>> The Haskell option where data structurs are created lazily so
>>
>> z <- list(f(x))
>>
>> would create a list with a deferred evaluation, but any attempt to
>> access the value of z would force the evaluation. So printing z,
>> for example, would force the evaluation but
>>
>> y <- z[[1]]
>>
>> would not.
>>
>> It is easy enough to create a Delay/Force pair that behaves like
>> Scheme's with the tools available in R if that is what you want.
>> Haskell, and other fully lazy functional languages, are very
>> interesting but very different animals from R. For some reason you
>> seem to be expecting some combination of Scheme and Haskell behavior.
>>
>> Best,
>>
>> luke
>>
>>>
>>>> f <- function(x) environment()
>>>> z <- as.list(f(7))
>>>> dput(z)
>>> structure(list(x = 7), .Names = "x")
>>>> z[[1]] == 7
>>> Error in z[[1]] == 7 :
>>> comparison (1) is possible only for atomic and list types
>>>> force(z[[1]]) == 7
>>> Error in force(z[[1]]) == 7 :
>>> comparison (1) is possible only for atomic and list types
>>>>
>>>> typeof(z)
>>> [1] "list"
>>>> typeof(z[[1]])
>>> [1] "promise"
>>>> typeof(force(z[[1]]))
>>> [1] "promise"
>>>> R.version.string # Vista
>>> [1] "R version 2.6.0 beta (2007-09-23 r42958)"
>>>
>>>
>>> On 9/19/07, Gabor Grothendieck <ggrothendieck_at_gmail.com> wrote:
>>>> The last two lines of example(delayedAssign) give this:
>>>>
>>>>> e <- (function(x, y = 1, z) environment())(1+2, "y", {cat(" HO! "); pi+2})
>>>>> (le <- as.list(e)) # evaluates the promises
>>>> $x
>>>> <promise: 0x032b31f8>
>>>> $y
>>>> <promise: 0x032b3230>
>>>> $z
>>>> <promise: 0x032b3268>
>>>>
>>>> which contrary to the comment appears unevaluated. Is the comment
>>>> wrong or is it supposed to return an evaluated result but doesn't?
>>>>
>>>>> R.version.string # Vista
>>>> [1] "R version 2.6.0 alpha (2007-09-06 r42791)"
>>>>
>>>
>>> ______________________________________________
>>> R-devel_at_r-project.org mailing list
>>> https://stat.ethz.ch/mailman/listinfo/r-devel
>>>
>>
>> --
>> Luke Tierney
>> Chair, Statistics and Actuarial Science
>> Ralph E. Wareham Professor of Mathematical Sciences
>> University of Iowa Phone: 319-335-3386
>> Department of Statistics and Fax: 319-335-3017
>> Actuarial Science
>> 241 Schaeffer Hall email: luke_at_stat.uiowa.edu
>> Iowa City, IA 52242 WWW: http://www.stat.uiowa.edu
>>
>

-- 
Luke Tierney
Chair, Statistics and Actuarial Science
Ralph E. Wareham Professor of Mathematical Sciences
University of Iowa                  Phone:             319-335-3386
Department of Statistics and        Fax:               319-335-3017
    Actuarial Science
241 Schaeffer Hall                  email:      luke_at_stat.uiowa.edu
Iowa City, IA 52242                 WWW:  http://www.stat.uiowa.edu

______________________________________________
R-devel_at_r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Received on Thu 27 Sep 2007 - 13:59:40 GMT

Archive maintained by Robert King, hosted by the discipline of statistics at the University of Newcastle, Australia.
Archive generated by hypermail 2.2.0, at Thu 27 Sep 2007 - 15:11:24 GMT.

Mailing list information is available at https://stat.ethz.ch/mailman/listinfo/r-devel. Please read the posting guide before posting to the list.