[R] Continuation-parsing / trampoline / infinite recursion problem

Duncan Murdoch
Wed, 10 Aug 2016 17:28:31 -0000

On 10/08/2016 1:10 PM, Thomas Mailund wrote:
> That did the trick!
>
> I was so focused on not evaluating the continuation that I completely
forgot that the thunk could hold an unevaluated value? now it seems to be
working for all the various implementations I have been playing around with.
>
> I think I still need to wrap my head around *why* the forced evaluation is
necessary there, but I will figure that out when my tired brain has had a little
rest.

The original version

make_thunk <- function(f, ...) function() f(?)

says to construct a new function whose body evaluates the expression
f(...).  It never evaluates f nor ... , so they don't get evaluated
until the first time you evaluate that new function.

My version containing list(...) forces evaluation of ... .  It would
have been even better to use

make_thunk <- function(f, ...) { list(f, ...); function() f(?) }

because that forces evaluation of both arguments.

I suspect you would have problems with

make_thunk <- function(f, ...) function() do.call(f, list(...))

for exactly the same reasons as the original; I'm surprised that you
found it appears to work.

Duncan Murdoch

>
> Thanks a lot!
>
> 	Thomas
>
>
> > On 10 Aug 2016, at 19:04, Duncan Murdoch <murdoch.duncan at
gmail.com> wrote:
> >
> > On 10/08/2016 12:53 PM, Thomas Mailund wrote:
> >> > On 10 Aug 2016, at 13:56, Thomas Mailund <mailund at
birc.au.dk> wrote:
> >> >
> >> > make_thunk <- function(f, ...) f(...)
> >>
> >> Doh!  It is of course this one:
> >>
> >> make_thunk <- function(f, ...) function() f(?)
> >>
> >> It just binds a function call into a thunk so I can delay its
evaluation.
> >
> > I haven't looked closely at the full set of functions, but this
comment:
> >
> > force(continuation) # if I remove this line I get an error
> >
> > makes it sound as though you're being caught by lazy evaluation.
The "make_thunk" doesn't appear to evaluate ..., so its value can
change between the time you make the thunk and the time you evaluate it.  I
think you could force the evaluation within make_thunk by changing it to
> >
> > make_thunk <- function(f, ...) { list(...); function() f(?) }
> >
> > and then would be able to skip the force() in your thunk_factorial
function.
> >
> > Duncan Murdoch
> >
> >
>