From: Robert Klemme Date: 2004-08-05T19:16:29+09:00 Subject: Re: Macros in Ruby "Kristof Bastiaensen" schrieb im Newsbeitrag news:pan.2004.08.05.09.55.29.582255@vleeuwen.org... > 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!" } I don't know what exactly you mean by this. Argument passing is the same for blocks and procs IMHO. Can you explain the difference? > - 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. Ah, thanks for reminding me! That's IMHO the single most crucial difference between blocks and procs created from blocks vs. stand alone lambdas / procs. And it's a really important difference! Kind regards robert > > > > >> 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