From: Robert Klemme Date: 2005-03-27T03:34:48+09:00 Subject: Re: Evaluator for a mini-Ruby in Haskell "Phil Tomson" schrieb im Newsbeitrag news:d22ob001uag@enews1.newsguy.com... > In article <1111806229.622292.217680@l41g2000cwc.googlegroups.com>, > Daniel Berger wrote: >>Maybe I need to rethink my view of Haskell after all: >> >>http://community.moertel.com/ss/space/start/2005-03-25/1#Writing_a_simple_Ruby_evaluator >> > > 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." I'm surprised about "retry", too. His analysis sounds all very resonable - only that "break" does not work for me but "return" does: >> def my_while(cond) >> break unless cond >> yield >> retry >> end => nil >> i = 0 => 0 >> my_while i < 10 do ?> puts i >> i += 1 >> end 0 1 2 3 4 5 6 7 8 9 LocalJumpError: unexpected break from (irb):2:in `my_while' from (irb):7 >> def my_while(cond) >> return unless cond >> yield >> retry >> end => nil >> i = 0 => 0 >> my_while i < 10 do ?> puts i >> i += 1 >> end 0 1 2 3 4 5 6 7 8 9 => nil ruby 1.8.1 Btw, can anybody think of a way to make my_while return the result of the last block evaluation? It seems impossible because the return occurs before the yield... Kind regards robert