I want to be able to call an anonymous lambda from within itself using Ruby. Consider the following recursive block (returns a factorial). I know I can assign it to a variab
In addition to KL-7's comment, here's a Y combinator solution:
lambda { |f|
lambda { |x| x.call(x) }.call(
lambda { |x| f.call( lambda { |v| x.call(x).call(v) } ) } )
}.call(
lambda { |f|
lambda { |n| n == 0 ? 1 : n * f.call(n - 1) }
}
).call(5) #=> 120
You would normally split these:
y = lambda { |f|
lambda { |x| x.call(x) }.call(
lambda { |x| f.call( lambda { |v| x.call(x).call(v) } ) } )
}
fac = y.call(
lambda { |f| lambda { |n| n == 0 ? 1 : n * f.call(n - 1) } }
)
fac.call(5) #=> 120
Note that although fac is being assigned, it is not used within the lambda.
I'd use Ruby's -> syntax and .() instead of .call():
y = ->(f) {
->(x) { x.(x) }.(
->(x) { f.(->(v) { x.(x).(v) }) } )
}
fac = y.(->(f) {
->(n) { n == 0 ? 1 : n * f.(n - 1) }
})
fac.(5) #=> 120
The y invocation can be simplified a bit by using curry:
y = ->(f) {
->(x) { x.(x) }.(
->(x) { f.curry.(->(v) { x.(x).(v) }) } )
}
fac = y.(
->(f, n) { n == 0 ? 1 : n * f.(n - 1) }
)
fac.(5) #=> 120