Hi,

On Thu, 05 Aug 2004 03:30:33 +0000, Jesse Jones wrote:
>> Which do you prefer?
>> 
>>    (1..10).map { |n| n ** 2 }
>> 
>>    (1..10).map( lambda { |n| n ** 2 } )

shouldn't that be '(1..10).map( &lambda { |n| n ** 2 } )'?

> 
> I prefer a light-weight syntax for something as commonly used as anonymous
> functions. On the other hand, I still don't know why {|n| n ** 2} can't
> simply create a proc object.

It can! Wether or not a proc object gets created depends on the
called method.  If that method uses yield, then no object is
created.  If however it captures a block using the '&' operator,
then a Proc object gets created.  

On the other hand, a Proc created this way is different from one 
created using Proc.new or lambda.

The difference which I can think of are:
- Argument passing, a block isn't strict about the arguments
  it gets passed, (i.e. it can take any argument).  A Proc 
  object in contrast is strict (like methods).  The reason I
  can think of is that it is often usefull not to get all arguments
  in a block, i.e. 3.times{ puts "Hi, world!" }

- The place where return goes to: in a block 'return' returns
  from the method in which it is defined.  In a lambda (Proc)
  it returns from the lambda expression.

> 
>> Please remember Joel's "percent-case" solution, extensively using
>> blocks.  That was nothing if not expressive.
> 
> Yes, a beautiful example of the flexibility of Ruby. But I don't see how
> having both blocks and proc objects improves Ruby's expressiveness.
> 
> 

Well, it is very expressive to be able to 'return' from a block.
That 's one of those thing I find uncomfortable in lisp and
scheme.  Sure, there is a good reason there is no 'return' in 
scheme: every statement is an expression, it wouldn't know where
to return from.  
I find it much more practical in Ruby, (with some gotha's, like
LocalJumpError).

Also block make it possible to do 3.times { puts "hello"} as 
explained above.  That's more expressive than having to type
3.times { |i| puts "hello"}

> Sure, it's a good word to describe what the interpreter will do when it
> hits that line, but it completely fails to describe the more important
> semantic behavior. And if the language already has proc objects why
> bother supporting yield?
> 
>   -- Jesse

I believe yield is there historically.  In early versions of Ruby
yield used to be the only way to pass arguments to blocks.  Then
in was unified with Proc objects.  I may be totally mistaken about
this.

The other thing is performance.  Creating a proc object is quite
expensive.

Also, but perhaps less important, it is a little easier to 
type yield, than to create block, and use block.call every
time.

I hope this explains a little why I find Ruby's way very 
expressive.  I believe Ruby isn't semantically as clean as
Scheme or SmallTalk.  (I don't think lisp is semantically very
clean).  However for me it has the right mix of being consistent 
and being practical.

Regards,
KB