Pierre Barbier de Reuille
5/13/2006 12:45:00 PM
Jeffrey Schwab a écrit :
> Marcin MielżyÅ?ski wrote:
>
>> Hi,
>>
>> I wonder if something like this can be done without giving lambda a name:
>>
>> (l=lambda{|a|a.zero? ? 1: a*l[a-1]})[10]
>>
>> something similar like javascript arguments.callee comes to my mind..
>>
>> lopex
>
>
> Skip the recursion. Instead of storing each successive value on the
> call stack, store it using inject's accumulator.
>
> (lambda {|a| (1..a).inject {|p,n| p * n } })[10]
>
> Btw, for the record, the variable name l is horrid to begin with, and
> interspersing it with the number 1 in a one-liner might make you go
> cross-eyed. :)
Another solution (because the inject method is not *always* possible to
use) is the Y operator, which is very simply defined in Ruby :
def y(&f)
lambda { |*args| f.call f,*args }
end
And used with :
y { |f,a| a.zero? ? 1 : a*f[f,a-1]}[10]
As you can see, the block of the Y operator will get itself as first
argument.
Pierre