From: Kent Sibilev Date: 2005-06-30T01:29:34+09:00 Subject: Re: yield does not take a block Yes, but consider this: irb(main):001:0> def display x irb(main):002:1> puts x irb(main):003:1> end => nil irb(main):004:0> (1..5).each &method(:display) 1 2 3 4 5 => 1..5 irb(main):005:0> Kent. On 6/29/05, Adam P. Jenkins wrote: > Eric Mahurin wrote: > > Personally, I don't think having yield as a keyword really adds > > that much value to the language. The only advantages I see > > over explicitly having a &block arg and using block.call are a) > > it looks like smalltalk, and b) rdoc parses it better. I think > > showing the &block on the def line makes the method interface > > clearer up front. I don't use yield at all and haven't missed > > it. > > I completely agree with this. I think closures are one of the most > useful features of Ruby, but I still don't understand what the point of > having blocks and yield is. In all other languages I've used that have > closures, such as Scheme, ML, Haskell, OCaml, and even Javascript, a > closure is just an object like any other object, that happens to have a > special literal syntax for creating them. If you want to pass a closure > to another function, you just pass it like any other argument. > > The way ruby does it with blocks/yield has several disadvantages: > > 1) There's an arbitrary limit of 1 on the number of blocks you can pass > to a function. If you want to pass more than 1, you need to convert all > but the last block to a proc. > > 2) The block argument can be implicit, so you can't see from the > function signature that there is a block argument. > > 3) You get a problem akin to Java's primitive/Object separation, where > in some contexts you need a block, and have to convert another callable > object to a block, and in other contexts you need a proc, and have to > convert a block to a proc. > > Let me expand on the last item. In functional languages like Scheme, > ML, or Haskell, all functions are closures, whether they're named or > anonymous, and can be used interchangeably. So, say I wanted to apply a > function to each element of a list, I'd write something like this in ML: > > for_each myArray print > > for_each takes a list as its first argument, and a function with 1 > parameter as its second argument, and applies the function to each > element of the list. In Ruby, since there's a distinction between > blocks, closures, and functions, I can't just pass print, even though > it's a function of 1 parameter. Rather I have to wrap print in a block: > > myArray.each { |elem| print elem } > > Wouldn't it have been cool to just be able to write: > > myArray.each print > > Overall, it's not a big problem, but I do think the fact that there's a > distinction between blocks, procs, and functions is one of the main > warts in the Ruby language. > > Adam > >