# Proc vs lambda vs proc

**URL:** <https://rubytalk.org/t/proc-vs-lambda-vs-proc/35064>\
**Category:** ruby-talk\
**Created:** [4 February 2007 04:00 UTC](https://rubytalk.org/t/proc-vs-lambda-vs-proc/35064 "2007-02-04T04:00:05Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Minkoo](https://avatars.discourse-cdn.com/v4/letter/m/db5fbb/32.png) [@Minkoo](https://rubytalk.org/u/Minkoo)\
**Post date:** [4 February 2007 04:00 UTC](https://rubytalk.org/t/proc-vs-lambda-vs-proc/35064/1 "2007-02-04T04:00:05Z")

</div>

Hi group(and probably ruby-talk list - is it running btw?).

I got a question on Proc.new and lambda { ... }. AFAIK, there's two  
differences between Proc.new(=proc) and lambda. The first one is that  
Proc.new does not check the number of arguments passed to it while  
lambda does. The secondis that lambda returns as we expect, i.e., it  
returns value, while Proc.new does not.

Though Proc.new lacks several advantages that lambda has, I guess  
there might be some situation where Proc.new is more suitable than  
lambda. As an example, some code blocks that have to executed  
thousands times might run more faster than lambda because it does not  
have to check the # of arguments, thereby decreasing computational  
overhead.

What is your opinion?

Sincerely,  
Minkoo Seo

---

<div class="post-metadata">

**Author:** ![Robert\_K1](https://yyz1.discourse-cdn.com/flex029/user_avatar/rubytalk.org/robert_k1/32/1830_2.png) [@Robert\_K1](https://rubytalk.org/u/Robert_K1)\
**Post date:** [4 February 2007 11:20 UTC](https://rubytalk.org/t/proc-vs-lambda-vs-proc/35064/2 "2007-02-04T11:20:06Z")

</div>

> I got a question on Proc.new and lambda { ... }. AFAIK, there's two  
> differences between Proc.new(=proc) and lambda.

I think you have it slightly wrong: "proc" and "lambda" are aliases while "Proc.new" works different.

\> The first one is that

> Proc.new does not check the number of arguments passed to it while  
> lambda does.

Correct:

irb(main):001:0\> f1 = Proc.new {|a,b|a+b}  
=\> #\<Proc:0x003bb2d0@(irb):1\>  
irb(main):002:0\> f2 = proc {|a,b|a+b}  
=\> #\<Proc:0x003b1690@(irb):2\>  
irb(main):003:0\> f3 = lambda {|a,b|a+b}  
=\> #\<Proc:0x003a4d3c@(irb):3\>  
irb(main):004:0\> f1[1,2]  
=\> 3  
irb(main):005:0\> f1[1,2,3]  
=\> 3  
irb(main):006:0\> f2[1,2,3]  
ArgumentError: wrong number of arguments (3 for 2)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from (irb):2  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from (irb):6:in `'  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from (irb):6  
irb(main):007:0\> f3[1,2,3]  
ArgumentError: wrong number of arguments (3 for 2)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from (irb):3  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from (irb):7:in `'  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from (irb):7  
irb(main):008:0\> f2[1,2]  
=\> 3  
irb(main):009:0\> f3[1,2]  
=\> 3

\> The secondis that lambda returns as we expect, i.e., it

> returns value, while Proc.new does not.

I do not understand what you mean here. All three return what you expect (apart from an exception in the case of wrong # of arguments.

> Though Proc.new lacks several advantages that lambda has,

Which advantages do you refer to?

\> I guess

> there might be some situation where Proc.new is more suitable than  
> lambda. As an example, some code blocks that have to executed  
> thousands times might run more faster than lambda because it does not  
> have to check the # of arguments, thereby decreasing computational  
> overhead.

I suggest to benchmark a concrete example if you are interested in timings. My guess is that the parameter checking overhead is negligible.

> What is your opinion?

I usually use lambda because it most resembles the term "lambda expression". But I guess this is just a matter of taste / personal preference.

Kind regards

&nbsp;&nbsp;robert

> **···**
>
> On 04.02.2007 04:55, Minkoo Seo wrote:  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from :0

---

<div class="post-metadata">

**Author:** ![Jim\_Weirich1](https://avatars.discourse-cdn.com/v4/letter/j/73ab20/32.png) [@Jim\_Weirich1](https://rubytalk.org/u/Jim_Weirich1)\
**Post date:** [4 February 2007 19:37 UTC](https://rubytalk.org/t/proc-vs-lambda-vs-proc/35064/3 "2007-02-04T19:37:57Z")

</div>

Minkoo Seo wrote:

> [...]  
> The secondis that lambda returns as we expect, i.e., it  
> returns value, while Proc.new does not.
> 
> [...] I guess  
> there might be some situation where Proc.new is more suitable than  
> lambda. [...]

lambda and Proc.new do handle the return statement in different ways.  
Return in lambda returns from the lambda, treating the lambda as an  
anonymous function.

Return in Proc.new returns from the enclosing method, treating the block  
as an inline piece of code.

The Proc.new behavior is useful where the block is simply a bit the  
algorithm. For example:

&nbsp;&nbsp;def member?(target, list)  
&nbsp;&nbsp;&nbsp;&nbsp;list.each do |item|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return true if target == item  
&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;false  
&nbsp;&nbsp;end

The explicit return should return from the member? method, not just from  
the loop.

-- Jim Weirich

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).

---

<div class="post-metadata">

**Author:** ![Kalman\_Noel](https://avatars.discourse-cdn.com/v4/letter/k/ad7895/32.png) [@Kalman\_Noel](https://rubytalk.org/u/Kalman_Noel)\
**Post date:** [4 February 2007 12:25 UTC](https://rubytalk.org/t/proc-vs-lambda-vs-proc/35064/4 "2007-02-04T12:25:06Z")

</div>

Robert Klemme:

> **···**
>
> > On 04.02.2007 04:55, Minkoo Seo wrote:
> > 
> > > I got a question on Proc.new and lambda { ... }. AFAIK, there's two  
> > > differences between Proc.new(=proc) and lambda.
> > 
> > I think you have it slightly wrong: "proc" and "lambda" are aliases  
> > while "Proc.new" works different.
> 
> This is true for Ruby 1.8, but was changed in Ruby 1.9. The decision was  
> taken because proc and Proc.new are lexically too similar to have different  
> meanings, IIRC.
> 
> Kalman

---

<div class="post-metadata">

**Author:** ![Minkoo](https://avatars.discourse-cdn.com/v4/letter/m/db5fbb/32.png) [@Minkoo](https://rubytalk.org/u/Minkoo)\
**Post date:** [5 February 2007 07:00 UTC](https://rubytalk.org/t/proc-vs-lambda-vs-proc/35064/5 "2007-02-05T07:00:06Z")

</div>

Okay. The problem is that I am writing a ruby tutorial for people from  
other langauges (like C++ or Java), but there are three seemingly same  
things: block, proc, and lambda. So I need to write about not only the  
differences but also the simple but effective rule for choosing one  
out of three.

To make it worse, the functionality provided by proc and lambda is  
quite similar except for the differences in parameter checking and  
return statement handling. And many people suggest to use lambda  
instead of proc if one does not have any particular reason. So what  
I'd like to do is to verify whether the preference for lambda is  
correct or not.

So, my intention is to find out whether there are people who prefer  
Proc to lambda whatever the reason is. Up to now, I see none. Any one?

Sincerely,  
Minkoo Seo

> **···**
>
> On Feb 4, 8:18 pm, Robert Klemme \<shortcut...@googlemail.com\> wrote:
> 
> > On 04.02.2007 04:55, Minkoo Seo wrote:  
> > \> there might be some situation where Proc.new is more suitable than  
> > \> lambda. As an example, some code blocks that have to executed  
> > \> thousands times might run more faster than lambda because it does not  
> > \> have to check the # of arguments, thereby decreasing computational  
> > \> overhead.
> > 
> > I usually use lambda because it most resembles the term "lambda  
> > expression". But I guess this is just a matter of taste / personal  
> > preference.
> > 
> > Kind regards
> > 
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;robert

---

<div class="post-metadata">

**Author:** ![Minkoo](https://avatars.discourse-cdn.com/v4/letter/m/db5fbb/32.png) [@Minkoo](https://rubytalk.org/u/Minkoo)\
**Post date:** [5 February 2007 07:05 UTC](https://rubytalk.org/t/proc-vs-lambda-vs-proc/35064/6 "2007-02-05T07:05:05Z")

</div>

> Minkoo Seo wrote:  
> \> [...]  
> \> The secondis that lambda returns as we expect, i.e., it  
> \> returns value, while Proc.new does not.
> 
> lambda and Proc.new do handle the return statement in different ways.  
> Return in lambda returns from the lambda, treating the lambda as an  
> anonymous function.
> 
> Return in Proc.new returns from the enclosing method, treating the block  
> as an inline piece of code.
> 
> The Proc.new behavior is useful where the block is simply a bit the  
> algorithm. For example:

I guess the following block (do |item| ... end)

> &nbsp;&nbsp;def member?(target, list)  
> &nbsp;&nbsp;&nbsp;&nbsp;list.each do |item|  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return true if target == item  
> &nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;&nbsp;&nbsp;false  
> &nbsp;&nbsp;end  
> The explicit return should return from the member? method, not just from  
> the loop.
> 
> -- Jim Weirich

is block and not a proc.

AFAIK, block is not converted to proc unless the block is captured by  
parameter like &blk. Am I wrong?

Sincerely,  
Minkoo Seo

> **···**
>
> On Feb 5, 4:37 am, Jim Weirich \<j...@weirichhouse.org\> wrote:

---

<div class="post-metadata">

**Author:** ![David\_A\_Black3](https://avatars.discourse-cdn.com/v4/letter/d/6a8cbe/32.png) [@David\_A\_Black3](https://rubytalk.org/u/David_A_Black3)\
**Post date:** [4 February 2007 13:01 UTC](https://rubytalk.org/t/proc-vs-lambda-vs-proc/35064/7 "2007-02-04T13:01:37Z")

</div>

Hi --

> **···**
>
> On Sun, 4 Feb 2007, Kalman Noel wrote:
> 
> > Robert Klemme:
> > 
> > > On 04.02.2007 04:55, Minkoo Seo wrote:
> > > 
> > > > I got a question on Proc.new and lambda { ... }. AFAIK, there's two  
> > > > differences between Proc.new(=proc) and lambda.
> > > 
> > > I think you have it slightly wrong: "proc" and "lambda" are aliases  
> > > while "Proc.new" works different.
> > 
> > This is true for Ruby 1.8, but was changed in Ruby 1.9. The decision was  
> > taken because proc and Proc.new are lexically too similar to have different  
> > meanings, IIRC.
> 
> Yes -- this was something that was raised at RubyConf in 2002 or 2003,  
> and Matz agreed that having proc != Proc.new, while proc == lambda,  
> was confusing.
> 
> David
> 
> --  
> Q. What is THE Ruby book for Rails developers?  
> A. RUBY FOR RAILS by David A. Black ([http://www.manning.com/black\](http://www.manning.com/black%5C))  
> &nbsp;&nbsp;&nbsp;&nbsp;(See what readers are saying! [http://www.rubypal.com/r4rrevs.pdf\](http://www.rubypal.com/r4rrevs.pdf%5C))  
> Q. Where can I get Ruby/Rails on-site training, consulting, coaching?  
> A. Ruby Power and Light, LLC ([http://www.rubypal.com](http://www.rubypal.com))

---

<div class="post-metadata">

**Author:** ![Robert\_K1](https://yyz1.discourse-cdn.com/flex029/user_avatar/rubytalk.org/robert_k1/32/1830_2.png) [@Robert\_K1](https://rubytalk.org/u/Robert_K1)\
**Post date:** [4 February 2007 13:05 UTC](https://rubytalk.org/t/proc-vs-lambda-vs-proc/35064/8 "2007-02-04T13:05:07Z")

</div>

Thanks for the heads up! Me not being an early adopter tested with 1.8 only. At least I don't have to change my habit of using "lambda". 🙂

Kind regards

&nbsp;&nbsp;robert

> **···**
>
> On 04.02.2007 12:28, Kalman Noel wrote:
> 
> > Robert Klemme:
> > 
> > > On 04.02.2007 04:55, Minkoo Seo wrote:
> > > 
> > > > I got a question on Proc.new and lambda { ... }. AFAIK, there's two  
> > > > differences between Proc.new(=proc) and lambda.
> > > 
> > > I think you have it slightly wrong: "proc" and "lambda" are aliases while "Proc.new" works different.
> > 
> > This is true for Ruby 1.8, but was changed in Ruby 1.9. The decision was  
> > taken because proc and Proc.new are lexically too similar to have different  
> > meanings, IIRC.

---

<div class="post-metadata">

**Author:** ![Patrick\_Fernie](https://avatars.discourse-cdn.com/v4/letter/p/65b543/32.png) [@Patrick\_Fernie](https://rubytalk.org/u/Patrick_Fernie)\
**Post date:** [5 February 2007 15:29 UTC](https://rubytalk.org/t/proc-vs-lambda-vs-proc/35064/9 "2007-02-05T15:29:42Z")

</div>

I found the following:  
[http://innig.net/software/ruby/closures-in-ruby.rb](http://innig.net/software/ruby/closures-in-ruby.rb)  
to be an interesting read on the different flavors of closures in  
ruby; I think it takes into account some of the 1.9 changes, but it  
may be slightly outdated...

-P

> **···**
>
> On 2/5/07, Minkoo Seo \<minkoo.seo@gmail.com\> wrote:
> 
> > On Feb 5, 4:37 am, Jim Weirich \<j...@weirichhouse.org\> wrote:  
> > \> Minkoo Seo wrote:  
> > \> \> [...]  
> > \> \> The secondis that lambda returns as we expect, i.e., it  
> > \> \> returns value, while Proc.new does not.  
> > \>  
> > \> lambda and Proc.new do handle the return statement in different ways.  
> > \> Return in lambda returns from the lambda, treating the lambda as an  
> > \> anonymous function.  
> > \>  
> > \> Return in Proc.new returns from the enclosing method, treating the block  
> > \> as an inline piece of code.  
> > \>  
> > \> The Proc.new behavior is useful where the block is simply a bit the  
> > \> algorithm. For example:  
> > \>
> > 
> > I guess the following block (do |item| ... end)
> > 
> > \> def member?(target, list)  
> > \> list.each do |item|  
> > \> return true if target == item  
> > \> end  
> > \> false  
> > \> end  
> > \> The explicit return should return from the member? method, not just from  
> > \> the loop.  
> > \>  
> > \> -- Jim Weirich
> > 
> > is block and not a proc.
> > 
> > AFAIK, block is not converted to proc unless the block is captured by  
> > parameter like &blk. Am I wrong?
> > 
> > Sincerely,  
> > Minkoo Seo

---

<div class="post-metadata">

**Author:** ![Gary\_Wright](https://avatars.discourse-cdn.com/v4/letter/g/58956e/32.png) [@Gary\_Wright](https://rubytalk.org/u/Gary_Wright)\
**Post date:** [5 February 2007 17:15 UTC](https://rubytalk.org/t/proc-vs-lambda-vs-proc/35064/10 "2007-02-05T17:15:48Z")

</div>

This thread caused me to do some experimenting and I came across some  
Proc semantics that I hadn't seen discussed before and that might  
be useful in a DSL context. Consider:

class A  
&nbsp;&nbsp;&nbsp;Foo = define\_method(:foo) { |x|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p "self: #{self}"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return 'positive' if x \> 0  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'negative'  
&nbsp;&nbsp;&nbsp;}  
end

p A::Foo # #\<Proc:0x00026520@proc.question:6\>  
p A::Foo.call(0) # "self: A" "negative"  
p A::Foo.call(1) # "self: A" "positive"  
p A.new.foo(0) # "self: #\<A:0x25ecc\>" "negative"  
p A.new.foo(1) # "self: #\<A:0x25e2c\>" "positive"

I was unaware that define\_method returned a proc. I was even more  
surprised that it appears to be of the lambda "flavor". That is to  
say that a 'return' within the block is relative to the block and not  
to the scope where the block is defined.

Previously I thought that only Kernel#proc and Kernel#lambda had  
the 'magic' property of altering the return semantics of a block.  
I understand why this is also necessary for define\_method to be  
useful, I was just not aware that the resulting proc was accessible  
as the return value of define\_method.

I was going to ask if there was any way to write a method like  
'define\_method' that forces any provided blocks to be interpreted  
as lambda vs. 'regular' procs. Then I did some more experimenting:

a = Proc.new { return 42 }  
a.call # LocalJumpError

b = lambda &a  
a.call # 42

This was another surprise for me as I figured that when lambda was  
used, the first proc would be 'wrapped' in a new proc with  
lambda semantics, something like:

c = lambda { a.call }

But that isn't the case. If you try 'c.call' you'll get the  
LocalJumpError again.

I hadn't see this type of transformation before. It might be  
useful in some DSL situations:

&nbsp;&nbsp;&nbsp;class A  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;filter {|x| x.to\_s } # ok  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;filter {|x| return x.to\_s } # potential LocalJumpError  
&nbsp;&nbsp;&nbsp;end

If you wrote filter as:

&nbsp;&nbsp;&nbsp;def A.filter(&b)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lambda(&b).call(42)  
&nbsp;&nbsp;&nbsp;end

you can avoid the LocalJumpError.

Gary Wright

---

<div class="post-metadata">

**Author:** ![David\_A\_Black3](https://avatars.discourse-cdn.com/v4/letter/d/6a8cbe/32.png) [@David\_A\_Black3](https://rubytalk.org/u/David_A_Black3)\
**Post date:** [4 February 2007 13:25 UTC](https://rubytalk.org/t/proc-vs-lambda-vs-proc/35064/11 "2007-02-04T13:25:47Z")

</div>

Hi --

> **···**
>
> On Sun, 4 Feb 2007, Robert Klemme wrote:
> 
> > On 04.02.2007 12:28, Kalman Noel wrote:
> > 
> > > Robert Klemme:
> > > 
> > > > On 04.02.2007 04:55, Minkoo Seo wrote:
> > > > 
> > > > > I got a question on Proc.new and lambda { ... }. AFAIK, there's two  
> > > > > differences between Proc.new(=proc) and lambda.
> > > > 
> > > > I think you have it slightly wrong: "proc" and "lambda" are aliases while "Proc.new" works different.
> > > 
> > > This is true for Ruby 1.8, but was changed in Ruby 1.9. The decision was  
> > > taken because proc and Proc.new are lexically too similar to have different  
> > > meanings, IIRC.
> > 
> > Thanks for the heads up! Me not being an early adopter tested with 1.8 only. At least I don't have to change my habit of using "lambda". 🙂
> 
> Originally, I think the decision was to deprecate 'proc' entirely --  
> which would be fine with me, though as long as it's not different from  
> Proc.new that's OK too.
> 
> David
> 
> --  
> Q. What is THE Ruby book for Rails developers?  
> A. RUBY FOR RAILS by David A. Black ([http://www.manning.com/black\](http://www.manning.com/black%5C))  
> &nbsp;&nbsp;&nbsp;&nbsp;(See what readers are saying! [http://www.rubypal.com/r4rrevs.pdf\](http://www.rubypal.com/r4rrevs.pdf%5C))  
> Q. Where can I get Ruby/Rails on-site training, consulting, coaching?  
> A. Ruby Power and Light, LLC ([http://www.rubypal.com](http://www.rubypal.com))

---

<div class="post-metadata">

**Author:** ![Gavin\_Kistner2](https://avatars.discourse-cdn.com/v4/letter/g/b9e5f3/32.png) [@Gavin\_Kistner2](https://rubytalk.org/u/Gavin_Kistner2)\
**Post date:** [5 February 2007 16:30 UTC](https://rubytalk.org/t/proc-vs-lambda-vs-proc/35064/12 "2007-02-05T16:30:13Z")

</div>

Although certainly interesting, the author seems to have a slightly  
too-broad definition of the term closure. He seems to think that  
closures must be first-class functions in addition to providing  
lexical binding to the environment they were defined in. That's simply  
not so.

Further, he seems to be confusing the syntax of Ruby with features.  
For example, in a function:  
&nbsp;&nbsp;def foo( \*a ); end  
You refer to array of values by the variable 'a', not by '\*a'; just  
so, of course you refer to a block in a function  
&nbsp;&nbsp;def foo( &b ); end  
simply as 'b'...he seems hung up that you can't use &b directly.

> **···**
>
> On Feb 5, 8:29 am, "Patrick Fernie" \<patrick.fer...@gmail.com\> wrote:
> 
> > I found the following:[http://innig.net/software/ruby/closures-in-ruby.rb](http://innig.net/software/ruby/closures-in-ruby.rb)  
> > to be an interesting read on the different flavors of closures in  
> > ruby; I think it takes into account some of the 1.9 changes, but it  
> > may be slightly outdated...

---

<div class="post-metadata">

**Author:** ![Pit](https://avatars.discourse-cdn.com/v4/letter/p/f14d63/32.png) [@Pit](https://rubytalk.org/u/Pit)\
**Post date:** [5 February 2007 19:00 UTC](https://rubytalk.org/t/proc-vs-lambda-vs-proc/35064/13 "2007-02-05T19:00:44Z")

</div>

gwtmp01@mac.com schrieb:

> (... useful infos about procs ...)

Very interesting! Thanks for sharing your experiments.

Regards,  
Pit

---

<div class="post-metadata">

**Author:** ![Thomas\_Hafner1](https://avatars.discourse-cdn.com/v4/letter/t/f1d935/32.png) [@Thomas\_Hafner1](https://rubytalk.org/u/Thomas_Hafner1)\
**Post date:** [5 February 2007 22:15 UTC](https://rubytalk.org/t/proc-vs-lambda-vs-proc/35064/14 "2007-02-05T22:15:05Z")

</div>

"Patrick Fernie" \<patrick.fernie@gmail.com\> wrote/schrieb \<240187340702050729x57c3c6bcp1431daa7967ce49d@mail.gmail.com\>:

> I found the following:  
> [http://innig.net/software/ruby/closures-in-ruby.rb](http://innig.net/software/ruby/closures-in-ruby.rb) to be an  
> interesting read on the different flavors of closures in ruby;

Very interesting, indeed. BTW, in article  
\<g1ae84-d67.ln1@faun.hafner.nl.eu.org\> I did the same, i.e. defining a  
data structure containing \*all\* of the Fibonacci numbers:  
&nbsp;&nbsp;s = Stream.delay {  
&nbsp;&nbsp;&nbsp;&nbsp;Stream.cons(0, Stream.delay {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Stream.cons(1, Stream.map(lambda{|x,y| x+y}, s, s.cdr))})}  
(It uses methods posted in article \<9oib84-sf6.ln1@faun.hafner.nl.eu.org\>.)

Regards  
&nbsp;&nbsp;Thomas

---

<div class="post-metadata">

**Author:** ![Brian\_Candler](https://avatars.discourse-cdn.com/v4/letter/b/5f9b8f/32.png) [@Brian\_Candler](https://rubytalk.org/u/Brian_Candler)\
**Post date:** [5 February 2007 21:28 UTC](https://rubytalk.org/t/proc-vs-lambda-vs-proc/35064/15 "2007-02-05T21:28:48Z")

</div>

Yes, it's interesting to be reminded of all this again.

Much as I love Ruby, I hate having multiple versions of essentially the same  
concept which differ in subtle ways. I would find it more aesthetically  
pleasing if a tiny Ruby core could bootstrap the whole language - and it  
might make it easier to port (and understand).

Now, I wonder why you couldn't approach this problem from the other  
direction: instead of having two or more different types of lambda, which  
handle 'return' semantics differently, have a single type of lambda and two  
different return statements. For example:

&nbsp;&nbsp;&nbsp;return val # return from enclosing method  
&nbsp;&nbsp;&nbsp;result val # return from this block only

Internally, you could implement 'return' semantics using catch and throw:

&nbsp;&nbsp;def foo  
&nbsp;&nbsp;&nbsp;&nbsp;... some code  
&nbsp;&nbsp;end

&nbsp;&nbsp;# could be implemented as something like this:

&nbsp;&nbsp;define\_method(:foo) do  
&nbsp;&nbsp;&nbsp;&nbsp;catch(:return) do  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;... some code  
&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;end

&nbsp;&nbsp;module Kernel  
&nbsp;&nbsp;&nbsp;&nbsp;def return(rc=nil)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw(:return, rc)  
&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;end

The other difference concerns arity. I don't see why argument checking can't  
be done everywhere, as long as you have the option of explicitly allowing  
variable arguments where you want them:

&nbsp;&nbsp;p1 = Proc.new { |x=nil,y=nil| ... } # accept 2 or fewer args  
&nbsp;&nbsp;p2 = Proc.new { |x, y, \*z| ... } # accept 2 or more args  
&nbsp;&nbsp;p3 = Proc.new { |\*x| ... } # no more single-arg special case!

That is, use the same argument list handling for a 'def' method definition,  
a block, and a Proc/proc/lambda.

Anyway, that's just a couple of random thoughts. No doubt it's only when you  
implement such a cut-down language that you'd find out what the pitfalls are  
in practice ☹

Regards,

Brian.

> **···**
>
> On Tue, Feb 06, 2007 at 04:00:44AM +0900, Pit Capitain wrote:
> 
> > gwtmp01@mac.com schrieb:  
> > \>(... useful infos about procs ...)
> > 
> > Very interesting! Thanks for sharing your experiments.

---

<div class="post-metadata">

**Author:** ![David\_A\_Black3](https://avatars.discourse-cdn.com/v4/letter/d/6a8cbe/32.png) [@David\_A\_Black3](https://rubytalk.org/u/David_A_Black3)\
**Post date:** [5 February 2007 22:33 UTC](https://rubytalk.org/t/proc-vs-lambda-vs-proc/35064/16 "2007-02-05T22:33:20Z")

</div>

Hi --

> > gwtmp01@mac.com schrieb:
> > 
> > > (... useful infos about procs ...)
> > 
> > Very interesting! Thanks for sharing your experiments.
> 
> Yes, it's interesting to be reminded of all this again.
> 
> Much as I love Ruby, I hate having multiple versions of essentially the same  
> concept which differ in subtle ways. I would find it more aesthetically  
> pleasing if a tiny Ruby core could bootstrap the whole language - and it  
> might make it easier to port (and understand).
> 
> Now, I wonder why you couldn't approach this problem from the other  
> direction: instead of having two or more different types of lambda, which  
> handle 'return' semantics differently, have a single type of lambda and two  
> different return statements. For example:
> 
> &nbsp;&nbsp;return val # return from enclosing method  
> &nbsp;&nbsp;result val # return from this block only
> 
> Internally, you could implement 'return' semantics using catch and throw:
> 
> def foo  
> &nbsp;&nbsp;&nbsp;... some code  
> end
> 
> # could be implemented as something like this:
> 
> define\_method(:foo) do  
> &nbsp;&nbsp;&nbsp;catch(:return) do  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;... some code  
> &nbsp;&nbsp;&nbsp;end  
> end
> 
> module Kernel  
> &nbsp;&nbsp;&nbsp;def return(rc=nil)  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw(:return, rc)  
> &nbsp;&nbsp;&nbsp;end  
> end
> 
> The other difference concerns arity. I don't see why argument checking can't  
> be done everywhere, as long as you have the option of explicitly allowing  
> variable arguments where you want them:
> 
> p1 = Proc.new { |x=nil,y=nil| ... } # accept 2 or fewer args  
> p2 = Proc.new { |x, y, \*z| ... } # accept 2 or more args  
> p3 = Proc.new { |\*x| ... } # no more single-arg special case!
> 
> That is, use the same argument list handling for a 'def' method definition,  
> a block, and a Proc/proc/lambda.

I think the reason for there not being default arguments in code  
blocks is the ambiguity of the pipe character:

&nbsp;&nbsp;&nbsp;{| x=1 | 2 | 3 } # {(x=1) 2 | 3 } or {(x=1|2) 3 } ?

Dave Thomas suggested something at RubyConf 2005 along the lines of:

&nbsp;&nbsp;&nbsp;def m(a,b,c) # method  
&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;def (a,b,c) # anonymous function  
&nbsp;&nbsp;&nbsp;end

I'm not sure what happened to that; I haven't seen it mentioned much  
in discussions of this stuff.

David

> **···**
>
> On Tue, 6 Feb 2007, Brian Candler wrote:
> 
> > On Tue, Feb 06, 2007 at 04:00:44AM +0900, Pit Capitain wrote:
> 
> --  
> Q. What is THE Ruby book for Rails developers?  
> A. RUBY FOR RAILS by David A. Black ([http://www.manning.com/black\](http://www.manning.com/black%5C))  
> &nbsp;&nbsp;&nbsp;&nbsp;(See what readers are saying! [http://www.rubypal.com/r4rrevs.pdf\](http://www.rubypal.com/r4rrevs.pdf%5C))  
> Q. Where can I get Ruby/Rails on-site training, consulting, coaching?  
> A. Ruby Power and Light, LLC ([http://www.rubypal.com](http://www.rubypal.com))

---

<div class="post-metadata">

**Author:** ![Gary\_Wright](https://avatars.discourse-cdn.com/v4/letter/g/58956e/32.png) [@Gary\_Wright](https://rubytalk.org/u/Gary_Wright)\
**Post date:** [5 February 2007 23:20 UTC](https://rubytalk.org/t/proc-vs-lambda-vs-proc/35064/17 "2007-02-05T23:20:49Z")

</div>

> Now, I wonder why you couldn't approach this problem from the other  
> direction: instead of having two or more different types of lambda, which  
> handle 'return' semantics differently, have a single type of lambda and two  
> different return statements. For example:
> 
> &nbsp;&nbsp;&nbsp;return val # return from enclosing method  
> &nbsp;&nbsp;&nbsp;result val # return from this block only

I think Ruby already has this via 'break'. Also, the default behavior  
of returning the last expression evaluated in a block is an implicit  
'break' in Proc.new procs.

Sometimes you want a Proc to behave like the body of a method (the lambda flavor of procs) and sometimes you want it to behave like the body of  
an iterator (the Proc.new flavor of procs).

> That is, use the same argument list handling for a 'def' method definition,  
> a block, and a Proc/proc/lambda.

That seems to be a goal of the 1.9/2.0 line of Ruby as part of 'cleaning up'  
the semantics of block argument scope.

I wish there was some better terminology for the two different types  
of procs (rather than 'lambda type' and 'Proc.new type'). I think Pickaxe  
uses 'raw proc' but I can never remember which type of proc is being  
referenced by that phrase.

Gary Wright

> **···**
>
> On Feb 5, 2007, at 4:28 PM, Brian Candler wrote:

---

<div class="post-metadata">

**Author:** ![Brian\_Candler](https://avatars.discourse-cdn.com/v4/letter/b/5f9b8f/32.png) [@Brian\_Candler](https://rubytalk.org/u/Brian_Candler)\
**Post date:** [6 February 2007 10:45 UTC](https://rubytalk.org/t/proc-vs-lambda-vs-proc/35064/18 "2007-02-06T10:45:26Z")

</div>

But make this into block syntax and you still have potential ambiguities:

&nbsp;&nbsp;&nbsp;3.times { (i=nil) puts i }

&nbsp;&nbsp;&nbsp;3.times do (i=nil)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts i  
&nbsp;&nbsp;&nbsp;end

(i=nil) is a valid expression/statement in its own right, so you'd need some  
more lexical rules to disambiguate this from an argument list. I'd hate more  
whitespace-sensitive rules to be added, e.g.

&nbsp;&nbsp;&nbsp;{(i) ... } # block args  
&nbsp;&nbsp;&nbsp;{ (i) ... } # expression ☹

Perhaps you use parentheses, and if a block starts with an open-parenthesis  
then it's always an argument list. If you want it otherwise, you have to  
explicitly avoid it:

&nbsp;&nbsp;&nbsp;3.times { nil, (a=b, c=d) }

It seems the rest of the ASCII set has been used already; e.g.  
angle-brackets would have the same problem.

&nbsp;&nbsp;&nbsp;3.times { \< i = j \> 4 \> puts i }

Incidentally, I do see a reason for not doing full argument-checking in  
blocks: there are methods which pass block arguments which it's convenient  
for the block to ignore if it doesn't want them.

&nbsp;&nbsp;&nbsp;3.times { puts "hello" }  
&nbsp;&nbsp;&nbsp;3.times { |x| puts "hello #{x}" }

You could get around this by:

(a) having different methods which pass or do not pass arguments:

&nbsp;&nbsp;&nbsp;3.times { puts "hello" }  
&nbsp;&nbsp;&nbsp;3.times\_i { |x| puts "hello #{x}" }

(b) making such arguments explicitly ignorable at the caller side, which I  
think I prefer. At worst:

&nbsp;&nbsp;&nbsp;class Integer  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def times(&blk)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if blk.arity == 1  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;... loop, yield with index  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;... loop, yield without index  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;end

Regards,

Brian.

> **···**
>
> On Tue, Feb 06, 2007 at 07:33:20AM +0900, dblack@wobblini.net wrote:
> 
> > \> p1 = Proc.new { |x=nil,y=nil| ... } # accept 2 or fewer args  
> > \> p2 = Proc.new { |x, y, \*z| ... } # accept 2 or more args  
> > \> p3 = Proc.new { |\*x| ... } # no more single-arg special case!  
> > \>  
> > \>That is, use the same argument list handling for a 'def' method  
> > \>definition,  
> > \>a block, and a Proc/proc/lambda.
> > 
> > I think the reason for there not being default arguments in code  
> > blocks is the ambiguity of the pipe character:
> > 
> > &nbsp;&nbsp;{| x=1 | 2 | 3 } # {(x=1) 2 | 3 } or {(x=1|2) 3 } ?
> > 
> > Dave Thomas suggested something at RubyConf 2005 along the lines of:
> > 
> > &nbsp;&nbsp;def m(a,b,c) # method  
> > &nbsp;&nbsp;end
> > 
> > &nbsp;&nbsp;def (a,b,c) # anonymous function  
> > &nbsp;&nbsp;end
> > 
> > I'm not sure what happened to that; I haven't seen it mentioned much  
> > in discussions of this stuff.

---

<div class="post-metadata">

**Author:** ![Brian\_Candler](https://avatars.discourse-cdn.com/v4/letter/b/5f9b8f/32.png) [@Brian\_Candler](https://rubytalk.org/u/Brian_Candler)\
**Post date:** [6 February 2007 11:01 UTC](https://rubytalk.org/t/proc-vs-lambda-vs-proc/35064/19 "2007-02-06T11:01:02Z")

</div>

What are those different behaviours?  
1. Handling of 'return'  
2. Handling of arity  
3. Anything else?

If it's just (1) and (2), then I just wonder if you could get the different  
behaviours using different keywords, so that there's only a single  
underlying proc-like object.

As another idea, if we really need different behaviours, it could be an  
explicit attribute of the object:

&nbsp;&nbsp;&nbsp;&nbsp;a = Proc.new(:iterator) { ... }  
&nbsp;&nbsp;&nbsp;&nbsp;b = Proc.new(:method\_body) { ... }

&nbsp;&nbsp;&nbsp;&nbsp;def proc(opt = :iterator)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Proc.new(opt)  
&nbsp;&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;&nbsp;def lambda(opt = :method\_body)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Proc.new(opt)  
&nbsp;&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;&nbsp;# or is it the other way round??

Regards,

Brian.

> **···**
>
> On Tue, Feb 06, 2007 at 08:20:49AM +0900, gwtmp01@mac.com wrote:
> 
> > Sometimes you want a Proc to behave like the body of a method (the  
> > lambda flavor of procs) and sometimes you want it to behave like the  
> > body of  
> > an iterator (the Proc.new flavor of procs).

---

<div class="post-metadata">

**Author:** ![Brian\_Candler](https://avatars.discourse-cdn.com/v4/letter/b/5f9b8f/32.png) [@Brian\_Candler](https://rubytalk.org/u/Brian_Candler)\
**Post date:** [6 February 2007 11:13 UTC](https://rubytalk.org/t/proc-vs-lambda-vs-proc/35064/20 "2007-02-06T11:13:31Z")

</div>

> (b) making such arguments explicitly ignorable at the caller side, which I  
> think I prefer. At worst:
> 
> &nbsp;&nbsp;&nbsp;class Integer  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def times(&blk)  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if blk.arity == 1  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;... loop, yield with index  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;... loop, yield without index  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;&nbsp;end

or have a "yieldopt" statement, which does something like

&nbsp;&nbsp;def yieldopt(\*a, &blk)  
&nbsp;&nbsp;&nbsp;&nbsp;blk.arity == 0 ? blk.call() : blk.call(\*a)  
&nbsp;&nbsp;end

so the caller is saying that the callee can either have all of the  
arguments, or ignore them all.

I can't think of any useful cases where an iterator calls a block with (say)  
three arguments, but the block only accepts two and is happy for the third  
to be silently ignored.

If the block only accepts one argument, but yield passes more than one, this  
is currently treated as another special case:

irb(main):001:0\> h = {1=\>"one", 2=\>"two", 3=\>"three"}  
=\> {1=\>"one", 2=\>"two", 3=\>"three"}  
irb(main):002:0\> h.each { |k| puts k.inspect }  
[1, "one"]  
[2, "two"]  
[3, "three"]  
=\> {1=\>"one", 2=\>"two", 3=\>"three"}  
irb(main):003:0\>

This could be eliminated if people wrote

&nbsp;&nbsp;&nbsp;&nbsp;h.each { |\*k| .. I want an array .. }  
&nbsp;&nbsp;&nbsp;&nbsp;h.each { |k,v| .. I want separate items .. }

which I think makes the intention very clear. Maybe this is already  
considered for 1.9

Cheers,

Brian.
