问题
(define get-first
(lambda (l)
(call-with-current-continuation
(lambda (here)
(set! leave here)
(waddle l)
(leave (quote ()))))))
(define get-first
(lambda (l)
(call-with-current-continuation
(lambda (here)
(set! leave here)
(leave (waddle l))))))
For anybody not familiar with the book "The Seasoned Schemer", get-first
, get-next
, and waddle
(last two not defined here) are procedures to apparently model coroutines to iterate through a tree passed to waddle
that yields leaves only. Just prior to waddle
's yield on its second-to-last re-entry, it sets the re-entry point to where it will only ever return the pure value '()
i.e. instead of yielding '()
, the actual value of waddle
is '()
, as if it were a pure function all along.
With this in mind, we can see what get-first
sets up... When waddle
returns "for real", it will be inside the call/cc
in get-first
and then (leave (quote ()))
is the value of get-first
(and, in turn, this leave
is intended to return to get-next
on the last iteration, therefore it is get-next
that does the "actual" return of '()
).
So why is the second version not equivalent, where waddle
's value of '()
would be the argument to leave
?
回答1:
The confusion is because "leave
" is not the function I want it to be, but the function it evaluates to when it's evaluated, which appears to be left-to-right and thus before "waddle
". That means it evaluates to what it was just set to, in the statement prior.
Moral: beware when using functions that are subject to redefining WITHIN the call to the function! If this was on a right-to-left interpreter, waddle
would be evaluated before the symbol leave
was looked up as the function that "leaves" to wherever, during which time it would be set to a DIFFERENT function.
来源:https://stackoverflow.com/questions/11043704/seasoned-schemers-get-first-get-next-and-waddle-functions