From: Trans Date: 2005-08-07T10:46:07+09:00 Subject: Re: new block notation (was: Re: ruby-dev summary 26468-26661) gabriele renzi wrote: > Florian Gro� ha scritto: > > > > def might not totally fit (it doesn't bind anything to a name), but it > > might still be the best choice if no new semi-keywords should be > > introduced. There's also undef, of course, but that is a more evil > > choice. :) > > maybe with should go the Oz route, which provide a > make-named-thing-unnamed special symbol (but I think the real concept is > "make a statement an expression) > i.e. > > def foo(x,y) #defines a method foo > end > > foo= def $(x,y) .. end #defines an unnamed method and assigns to foo You have no idea what this means to me :-) Here in lies the all the insanity. If we were to allow def to return a value it would have to be an UnboundMethod b/c the context of a def is the instance, not the class-level, which is what the context would be for a lambda. class Baz a = "class" foo = def bar a #=> ? end boo = lambda do a #=> "class" end end So then there are regular bound Methods. First lets define #a for the instance: class Baz def a; "instance"; end end Now b = Baz.new moo = b.method( bar ) moo.call #=> "instance" Now that is certainly different form an UnboundMethod. And it seems also quite different froma a lambda, but loo = b.instance_eval { lambda do a end } loo.call #=> "instance" Having already dicussed blocks, the structure of all this seems to follow: class UnboundMethod : @args @func @name @restclass* class Lambda : @args @func @context class Method : @args @func @name @context @restclass* The last thing, the @restclass stems from the fact that UnboundMethods are restricted to their class/module (try binding them to something that is not an instance of the class/module it was defined in). But that's a disadvantage and if that could be be overcome it would be really good for Ruby. If we could do this, and also give a lambda/block the optional name I suggest previously (a handle solely for internal use), then: class UnboundMethod : @args @func @name class Lambda : @args @func @name @context class Method : @args @func @name @context Notice Lambda and Method are one and the same now. So we are down to two distinct entities. Now we can talk about four or five entities base on _usage_, but were really just a breath away from this two-fold simplicity. So why not let it be? umethod = def foo(x,y) ... end bmethod = do bar(x,y) ... end 'bmound' is the lambda. Notice the local name bar. bar can only be used within the block as a refernce to it. (it would be cool if regular methods could somehow do the same) I think 'do' works well here, though 'fun' is an option. If we did not want the local name, as is typical: bmethod = do(x,y) ... end It all works well. Now the thorns come when we use { } instead since do => { and end => } doesn't work b/c of possible ambiguity. But considering also the overlap with hashes, it's tempting to simply deprecate the { } block form altogether :-) I know, its a well used syntax. So to keep it, the best way seems just to use it to replace the 'end': bmethod = do(x,y) { ... } This would alow it to be used for def to, btw: def bar(a,b) { ... } T.