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