Interesting.
Anyone care to comment on the analysis of 'retry' there? He presents the
following code for a do-it-yourself while loop:
def my_while(cond)
break unless cond
yield
retry
end
i = 0 my_while i < 10 do print i i += 1 end
# output: 0123456789
And offers this analysis:
"This is where the Pickaxe II let me down. It said, "retry will
reevaluate
any arguments to the iterator before restarting it." Yes, clearly, that
is what is happening. But how is it happening and what exactly does that
simple English statement really mean?
So, after thinking about it, I concluded that what is going on is that a
function call in Ruby works like this. Given a function f, a block b, and
arguments xs, the call f(xs){b} means this:
1. let k be the current continuation (i.e., just before the call)
2. bind xs to f's formal arguments
3. bind b internally to the current block
4. evaluate the body of f
Now, if inside of f's body we encounter a retry, the evaluator basically
calls k (with a nil argument, I expect). This jumps back to step 2, from
which evaluation continues. Any side effects up to this point are
retained (so we could have previously incremented i, for example), which
is what allows the code within the function body eventually to choose an
execution path which does not contain a retry expression, and thus avoid
looping forever."
Phil