# Closures and Letrec - Ruby

Is there a way to create recursive anonymous closures in ruby? For instance if I write even = proc {|x| x == 0 ? true : odd(x-1)} odd = proc {|x| x == 1 ? true : even(x-1)} In this case even definitely doesn't know about odd, and actually doesn't even know about even. Odd is aware of even though. At least that's how I have interpreted how ruby works. We get recursion with full methods, just not with anonymous procs. Is there any intention for support for this with anonymous procs? Perhaps though a different syntax? procrec or something? ...

1. ## Closures and Letrec

Is there a way to create recursive anonymous closures in ruby? For instance
if I write
even = proc {|x| x == 0 ? true : odd(x-1)}
odd = proc {|x| x == 1 ? true : even(x-1)}

In this case even definitely doesn't know about odd, and actually doesn't even
know about even. Odd is aware of even though. At least that's how I have
interpreted how ruby works. We get recursion with full methods, just not with
anonymous procs. Is there any intention for support for this with anonymous
procs? Perhaps though a different syntax? procrec or something?

Charlie
Charles Guest

2. ## Re: Closures and Letrec

Charles Comstock wrote:

Actually, even does know about even because Ruby sees an assignment to
even. To let even know about odd, do this ...

odd = nil
even = proc {|x| x == 0 ? true : odd.call(x-1) }
odd = proc {|x| x == 0 ? false : even.call(x-1)}

By assigning to odd, ruby now knows that "odd" is a variable, not a
method name. (Notice I changed the definition of odd to avoid infinite
recursion for the false case.)

--
-- Jim Weirich net http://onestepback.org
-----------------------------------------------------------------
"Beware of bugs in the above code; I have only proved it correct,
not tried it." -- Donald Knuth (in a memo to Peter van Emde Boas)

Jim Guest

3. ## Re: Closures and Letrec

In article <cec.wustl.edu>,
Charles Comstock <wustl.edu> wrote:
: Is there a way to create recursive anonymous closures in ruby? For instance
: if I write
: even = proc {|x| x == 0 ? true : odd(x-1)}
: odd = proc {|x| x == 1 ? true : even(x-1)}
:
: In this case even definitely doesn't know about odd, and actually doesn't even
: know about even. Odd is aware of even though.

Sure, you just have to remember about The Miracle Of Duck Typing, and
make sure that both your variables are visible to each other.

Since a proc is a method, you can call it. Since an object is an
object, you can send messages to it. One such message is [] (which is
an alias for Proc#call).

Also, I found a bug in your code. :-)

\$even = proc { |x|
case x
when 0 then true
when 1 then false
else \$odd[x-1]
end
}

\$odd = proc { |x|
case x
when 0 then false
when 1 then true
else \$even[x-1]
end
}

p \$odd[3]
p \$even[4]
p \$odd[4]
p \$even[3]

\$odd isn't even defined when \$even is set, but that doesn't stop
Ruby: it doesn't worry about things like that until you're
actually trying to call methods. By the time it actually gets
around to trying to call methods against odd, odd is defined and
you can call [] with no problems.

--Dave
Dave Guest

#### Posting Permissions

• You may not post new threads
• You may not post replies
• You may not post attachments
• You may not edit your posts
•