From: "Adam P. Jenkins" Date: 2005-06-30T01:00:42+09:00 Subject: Re: yield does not take a block 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