On Thu, Oct 20, 2005 at 04:09:52AM +0900, David A. Black wrote:
> I don't think either of those is exactly what Dave suggested:
> 
>   x = def (a=1,b=2)
>         ...
>       end
> 
> without the braces, and without 'begin', just like a method
> definition.
> 
> I actually like the second iteration of the idea more:
> 
>   x = lambda (a=1,b=2)
>         ...
>       end

I like this too.  And there's no reason IMO why we can't have both
anonymous functions and anonymous closures (so def and lambda could have
the same syntax but lambda would create a closure, while def would not).

Then we could also have named closures as well:

  class Foo
    a = 42
    lambda foo(b, c)
      puts a, b, c
    end
  end

The only problem I have with this is that currently lambda is not a
keyword; it is a method that takes a block and returns a Proc object.
Creating new keywords, especially out of existing non-keywords, should
always be done with caution.  Currently, the following code works fine:

  def lambda(article)
    puts "Hello from [ruby-talk:#{article}]"
  end

  article = 161640
  lambda(article) #=> Hello from [ruby-talk:161460]

But I would imagine that if lambda were a keyword this would confuse the
parser.

IMO the real issue is that we want to distinguish between blocks that
take arguments by multiple assignment and blocks that take arguments the
"usual" way.  One way to do this, then, is to use similar syntax for
both kinds of blocks.  For example, consider:

  foo do |a, b|
    # arguments passed by multiple assignment.  matz has previously
    # indicated that in the future a and b will also be block-local.
  end

vs:

  foo do <a, b>
    # arguments passed as a function.  a and b are block-local
    # regardless of whether they have been previously defined.
  end

  p = proc { <a, b> ... a and b are not passed by MI here ... }

  foo do <&block>
    # an anonymous function that takes a block.  you can pass the block
    # from inside foo() with:
    #   yield { ... }
  end

This is actually the same syntax that matz proposed in
[ruby-talk:12289] for declaring paramters to be block-local; I'm
extending the idea by suggesting that the angle brackets also change how
the arguments are passed.  IIRC there was much controversy over the
<...> syntax at that time, so please don't get too hung up on the syntax
here; consider instead the idea of differentiating between how the
parameters are passed based on some specification of the parameter list
rather than the function itself.

Paul