On 2/15/07, Levi Pearson <[EMAIL PROTECTED]> wrote:
"Bryan Sant" <[EMAIL PROTECTED]> writes:
> What's wrong with blocks being the last arg?  How would you prefer it
> (don't know how smalltalk does it)?

Well, Smalltalk allows a block in any argument place, giving them
first-class status.

For a clarification, Ruby does have first-class code blocks. They can
be created various ways. These "procs", as they're known in Ruby, can
be assigned to variables, passed as arguments (any position), etc.

"Blocks", which are (mostly[1]) as subset of procs, *are* relegated to
the last argument however. Blocks are a special code block that
immediately follows a method invocation. They do not need the "proc"
or "lambda" keywords, which makes their appearance a bit cleaner. They
are also the target of the "yield" keyword invoked in the method body.
These traits raise them up to a special status beyond that of normal
procs. A proc can be converted to a block and vice versa. For example,
the following are equivalent:

 # the curly braces delimit the block
 collection.each{ |element| ... }

and

 # the unary-& converts the proc to a block
 block = proc{ |element| ... }
 collection.each(&block)

These blocks are relegated, as Levi said, to the final position for
practical considerations: 1) without named parameters (I agree with
Levi that they would be nice to have), any syntax for multiple blocks
becomes confusing and/or ambiguous; 2) the "yield" keyword is intended
to be as simple as possible and requiring a block-distinguishing
parameter would clutter it.

So, to come back to Levi's example about Smalltalk's ifTrue:ifFalse, a
similar construct is *technically* possible in Ruby:

 class TrueClass
   def branch(true_proc, false_proc)
     true_proc.call
   end
 end

 class FalseClass
   def branch(true_proc, false_proc)
     false_proc.call
   end
 end

 (x < 1).branch(
   proc{ puts "x is less than 1" },
   proc{ puts "x is greather than 1" }
 )

The beauty that Smalltalk affords just isn't there however, due to the
extra noise of the proc keyword and the lack of named parameters.

Jacob Fugal

[1] I say "mostly" because the current implementation of Ruby actually
treats blocks and procs (and even amongst procs, depending on which
creation method was used) differently in some subtle ways. One is in
how mismatches in definition vs. call arities is handled. This is an
acknowledged wart and the multiple variations of "proc" are being
unified in the development going on for Ruby 1.9/2.0.

/*
PLUG: http://plug.org, #utah on irc.freenode.net
Unsubscribe: http://plug.org/mailman/options/plug
Don't fear the penguin.
*/

Reply via email to