On Tue, Apr 23, 2002 at 12:19:43AM +0900, Nat Pryce wrote:
> E.g. in Ruby a user defined control structure if-then-else block would look
> like this, which is more awkward than the built in if statement:
> 
> if some_test proc do
>     something
> end, else proc do
>     something_else
> end

This seems very awkward to me, much more so than passing two procs to a
single method.  I didn't even realize this syntax was legal.

> While in Smalltalk it would be:
> 
> some_test ifTrue: [
>     something.
> ]
> ifFalse: [
>     something_else.
> ].

If syntax is what you are after, consider this (just for fun; I don't
know if this is reasonable for production code):

  class Object
    def ifTrue; IfProxy.new(yield); end
    def ifFalse; self; end
    def endIf; self; end
  end

  class FalseClass
    def ifTrue; self; end
    def ifFalse; IfProxy.new(yield); end
  end

  class NilClass
    def ifTrue; self; end
    def ifFalse; IfProxy.new(yield); end
  end

  class IfProxy
    def initialize(x); @x = x; end
    def ifTrue(&b); @x.ifTrue(&b); end
    def ifFalse(&b); @x.ifFalse(&b); end
    def endIf; @x; end
  end

  def foo(x)
    (x == 42).ifTrue {
      puts "x == 42"
      1
    }.ifFalse {
      puts "x != 42"
      -1
    }.endIf
  end

  p foo(0)  #=> x != 42
            #=> -1
  p foo(42) #=> x == 42
            #=> 1

It seems to me that this would be much slower than the standard
if/then/else/end, since so many method calls are involved.  In
Smalltalk, it looks like only one method call, but it still looks like a
method call.  How does Smalltalk make its ifTrue:/iFalse: work at a
reasonable speed?

Paul