I am not sure I can see exactly how the parameters are changing at all, regardless of which of the versions I am using. Nowhere in the code do I ever modify assign to a variable (except for defining the global-level functions).
I think my problem is that I don’t really understand ... here. I would expect these two cases, with and without a thunk, to give me the same output, but they clearly do not. x <- function(...) eval(substitute(alist(...))) x(a = 2, b = 3) x(c = 4, d = 5) xx <- function(...) function() eval(substitute(alist(...))) xx(a = 2, b = 3)() xx(c = 4, d = 5)() The first gives me the parameters and the second just … back. How is the thunk actually seeing ... and why does it work with do.call and not with direct call? library(pryr) xxx <- function(...) function() do.call(eval %.% substitute %.% alist, list(...)) xxx(a = 2, b = 3)() xxx(c = 4, d = 5)() gives me the same results as the xx case, so it is not the do.call that does it, even though that works in my examples. With xxxx <- function(...) { list(...) ; function() eval(substitute(alist(...))) } xxxx(a = 2, b = 3)() xxxx(c = 4, d = 5)() it is the same. Explicitly naming the parameters, of course works fine y <- function( ...) { params <- list(...) ; function() params } y(a = 2, b = 3)() y(c = 4, d = 5)() Here I get the expected lists out. I guess I just shouldn’t be using ... in an inner function that refers to the parameters in an outer function. I’m not even sure what that should be expected to do and I certainly do not understand what is happening :) Explicitly remembering the parameters seems to work fine, though. Cheers Thomas On 10 August 2016 at 19:28:43, Duncan Murdoch (murdoch.dun...@gmail.com(mailto:murdoch.dun...@gmail.com)) wrote: > 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 wrote: > > > > > > On 10/08/2016 12:53 PM, Thomas Mailund wrote: > > >> > On 10 Aug 2016, at 13:56, Thomas Mailund 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 > > > > > > > > > ______________________________________________ R-help@r-project.org mailing list -- To UNSUBSCRIBE and more, see https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.