Anonymous methods, blocks etc. (Cont. 'default block params')

Listening in on the Roundtable (thanks to the brave recording crew and
Ezra Zygmuntowicz), it seems as if we were somewhat sidetracked in the
'default block parameters' discussion; the -> notation is to specifically
allow anonymous methods and the block syntax would still be allowed for,
well, blocks.

Multiple assignment was also mentioned; I am not quite sure how this plays
in, perhaps someone could clarify on that. (I always assume it is the
difference between a, b, c = 1, 2, 3 vs. a, b, c = [1,2,3].)

So here are some points I have pondered.

  1. Blocks vs. Procs. I think the desire has long been to make any
     differences between these two (and also Proc.new vs. Kernel.proc)
     disappear.

  2. Blocks/Procs versus anonymous methods. Should these be actually
     *different* or should

  3. Anonymous methods vs. methods. More aptly, should methods just be
     special instances of anonymous methods in that they are tied to
     a particular class?

  4. Methods vs. Procs. Should these two be different beasts or can
     the differences be implemented with context rather than content?

Now, based on my cursory YACC knowledge (and much input from a gentleman
on #ruby-lang), all these would be possible to implement with varying degrees
of difficulty. Even using the traditional block syntax with default arguments
would be

   # 1. New syntax, 'easy' to implement
   anon = -> (x = 'Hello') { puts x }

   # 2. Also 'new' syntax though using def for this
   # would require changes in, well, 'def'.
   anon = def(x = 'Hello') { puts x }

   # 3. Using 'lambda' (or something else) would be simpler than above.
   anon = lambda(x = 'Hello') { puts x }

   # 4. Implicit conversion is possible with = not being a method.
   anon = {|x = 'Hello'| puts x }

   # 5. The 'traditional' style.
   anon = lambda {|x = 'Hello'| puts x } # Sub 'lambda' with 'def'

   # 6. More? The : or . seems not necessary in this context of blocks?

Personally I would like to see the complete unification of Blocks, Anons
and Methods with the Block being the basic element of which the two others
are merely contextually created special cases; this combined with either
the def/lambda() syntax or the plain block syntax (#4 above).

Er, well, yeah. Just felt the urge to write something :slight_smile:

E

hi,

are there any non obvious issue why blocks, anonymous methods and
methods could or should not be unified?

i find it very ugly that i have to call a proc like this
aproc.call or aproc[] instead of aproc(). unification of all those
constructs would be really great.

btw will be possible to get a handle on a instance method in ruby
1.9/2.0

something like this:
aproc = &anInstance.method

and then of course
aproc()

ciao robertj

Short answer - yes. An anonymous function would mean you're not
carrying around a whole heap of baggage when no closure is required
and gives you a clean scope to help prevent accidental aliasing
errors.

In general, I would expect to use an anonymous function unless I
specifically required the extra features of a closure. Ruby makes it
so easy to use closures that I suspect many people don't realise the
consequences of using such a powerful construct.

Regards,

Sean

···

On 10/15/05, ES <ruby-ml@magical-cat.org> wrote:

2. Blocks/Procs versus anonymous methods. Should these be actually
    *different*

I agree. It seems to me that once Ruby has 'real deal' anonymous
methods, then that's a primitive that could be used to implement the
other constructs, like Proc.

Also, I've been trying not to comment on the arrow thing, but my
biggest complaint is this:
In functional notation, an 'f arrow x' means apply the f function to
the x argument. The example Ruby syntax is reversing that, and using
the arrow for specifying a function, rather than using it.

--Wilson.

···

On 10/16/05, robertj <robert_kuzelj@yahoo.com> wrote:

hi,

are there any non obvious issue why blocks, anonymous methods and
methods could or should not be unified?

i find it very ugly that i have to call a proc like this
aproc.call or aproc instead of aproc(). unification of all those
constructs would be really great.

btw will be possible to get a handle on a instance method in ruby
1.9/2.0

something like this:
aproc = &anInstance.method

and then of course
aproc()

ciao robertj

"robertj" <robert_kuzelj@yahoo.com> writes:

hi,

are there any non obvious issue why blocks, anonymous methods and
methods could or should not be unified?

i find it very ugly that i have to call a proc like this
aproc.call or aproc instead of aproc(). unification of all those
constructs would be really great.

btw will be possible to get a handle on a instance method in ruby
1.9/2.0

something like this:
aproc = &anInstance.method

myproc = myobj.method :mymethod

myproc = MyClass.instance_method(:mymethod).bind(myobj)

and then of course
aproc()

This had been in CVS for some time, but I think it was removed
again(?). I think the unification of blocks (objects) and methods
(non-objects) is a bad idea, though I can see the quest for
unification.

There have been long threads about this on the list, look them up if
you are interested.

···

ciao robertj

--
Christian Neukirchen <chneukirchen@gmail.com> http://chneukirchen.org

Except that Matz still plans on making anonymous functions have closure
capabilities. This is why, after Dave Thomas suggested:

  anon = def(x = 5)
    # implementation of anon
  end

I then suggested:

  anon = lambda(x = 5)
    # implementation of anon
  end

To me, this is clearer than any of the other options that have been so
far suggested for anonymous functions. I don't know that I'll be using
anonymous functions for most of what I do in Ruby, but I can see the
point of them and how they *are* subtly different than blocks. I just
don't particularly care for the proposed syntax:

  anon = ->(x = 5) { ... }

-austin

···

On 10/18/05, Sean O'Halpin <sean.ohalpin@gmail.com> wrote:

On 10/15/05, ES <ruby-ml@magical-cat.org> wrote:

2. Blocks/Procs versus anonymous methods. Should these be actually
*different*

Short answer - yes. An anonymous function would mean you're not
carrying around a whole heap of baggage when no closure is required
and gives you a clean scope to help prevent accidental aliasing
errors.

--
Austin Ziegler * halostatue@gmail.com
               * Alternate: austin@halostatue.ca

Wilson Bilkovich wrote:

I agree. It seems to me that once Ruby has 'real deal' anonymous
methods, then that's a primitive that could be used to implement the
other constructs, like Proc.

The hurdle for this, I assume (apart from having to rewrite a lot of
code and another important thing addressed below), is that the closure
feature does not play nice with the current semantics:

   # Pseudosyntax to clarify
   class Foo
     @quux = 42

     def :foo {|x, y, z|
       do_something_with x, y, z
     }

     def :do_something {...}
   end

The closure would grab the environment; @quux would be available and
the implicit 'self' would refer to the Class object, not the instance.
This means that all messages to a given object would invoke some sort
of an #instance_eval on the method's code.

(Please correct me and voice other *technical* issues if any!)

These are by no means unsurmountable but there is quite a bit of work
involved in rewriting.

One big thing, though: one may wish to intentionally make a distinction
between a 'behaviour' of an object and a 'function' which these anons
(and to an extent Procs) can be seen as. I have made my peace by just
thinking of this as a different way of defining those behaviours (it is
not like they actually spawn to life by themselves now) but I can, sort
of, see how the thought might seem unappealing.

Also, I've been trying not to comment on the arrow thing, but my
biggest complaint is this:
In functional notation, an 'f arrow x' means apply the f function to
the x argument. The example Ruby syntax is reversing that, and using
the arrow for specifying a function, rather than using it.

--Wilson.

hi,

are there any non obvious issue why blocks, anonymous methods and
methods could or should not be unified?

i find it very ugly that i have to call a proc like this
aproc.call or aproc instead of aproc(). unification of all those
constructs would be really great.

btw will be possible to get a handle on a instance method in ruby
1.9/2.0

something like this:
aproc = &anInstance.method

and then of course
aproc()

ciao robertj

E

···

On 10/16/05, robertj <robert_kuzelj@yahoo.com> wrote:

Austin Ziegler wrote:

>> 2. Blocks/Procs versus anonymous methods. Should these be actually
>> *different*
> Short answer - yes. An anonymous function would mean you're not
> carrying around a whole heap of baggage when no closure is required
> and gives you a clean scope to help prevent accidental aliasing
> errors.

Except that Matz still plans on making anonymous functions have closure
capabilities. This is why, after Dave Thomas suggested:

  anon = def(x = 5)
    # implementation of anon
  end

I then suggested:

  anon = lambda(x = 5)
    # implementation of anon
  end

I agree that a *true* anonymous function is needed, but also think it
would be nice if one could selectively "pull down" elements of closure
somehow.

Alos, there are other places in which non-closure can be helpful, such
a Class.new{ }, so, please, we should not restrict this to functions.

It has been suggestd before that using 'do...end' not provide closure
while '{...}' would, but this has some issues, not the least of which
is back(ward-compatability)-breaking. But perhaps if parenthesis were
used on the 'do'?

  lambda do |x|
    # ... has closure
  end

  lambda do(x)
    # ... does not have closure
  end

Just a thought.

T.

···

On 10/18/05, Sean O'Halpin <sean.ohalpin@gmail.com> wrote:
> On 10/15/05, ES <ruby-ml@magical-cat.org> wrote:

Except that Matz still plans on making anonymous functions have closure
capabilities.

Hmmm. I must have missed that. What does "closure capabilities" mean exactly?

This is why, after Dave Thomas suggested:

anon = def(x = 5)
   # implementation of anon
end

I then suggested:

anon = lambda(x = 5)
   # implementation of anon
end

To me, this is clearer than any of the other options that have been so
far suggested for anonymous functions.

I was under the impression that it was

  anon = def(x = 5) ... end

for def style semantics (i.e. 'true' anonymous function, opaque scope, etc.) and

  block = lambda(x = 5) ... end

for closures. If so, then I would endorse these suggestions.

Otherwise, I have to confess, I'm a little confused as to what the
proposal for anonymous functions actually means.

Regards,

Sean

···

On 10/18/05, Austin Ziegler <halostatue@gmail.com> wrote:

Austin Ziegler wrote:

[snip]

I just
don't particularly care for the proposed syntax:

  anon = ->(x = 5) { ... }

Was there an RCR for this syntax? If so what is it's name, I do not see it on rcrchive.net ?

Zach

I agree that a *true* anonymous function is needed,

I'm surprised more people don't seem to think real anonymous functions
would be useful. I'm pretty sure they'd be applicable in the majority
of cases where we use blocks now, especially with map, inject, select,
grep, etc. They would surely be more efficient (no need to set up
binding, no lookup outside current scope, lower memory usage).

but also think it
would be nice if one could selectively "pull down" elements of closure
somehow.

What do you mean by 'elements of closure'?

lambda do |x|
   # ... has closure
end

lambda do(x)
   # ... does not have closure
end

I quite like that. While we're at it, how about

  lambda {|x| .. }

for closure and

  lambda [|x| ... ]

for anonymous functions (on analogy with hashes vs arrays, i.e. more
complex vs simpler).

However, the absence of this as an option makes me think it has
already been suggested and shot down.

Regards,

Sean

···

On 10/18/05, Trans <transfire@gmail.com> wrote:

v1.9 already has the ability to do the opposite which kind of
allows you to get the same effect. You can explicitly tell it
what variables are local to the block by putting them after the
arguments and a ";". Matz described it on a previous thread or
maybe it was this one when it was "default block params".

If Matz optimizes out all of the unused variables out of the
closure (he mentioned doing it after "eval" becomes a keyword)
and you use the above ;-specified local variables, maybe you
don't need non-closure blocks/lambdas. But, I kind of still
wish we had a syntax where the variables in a block/lambda were
local (non-closure) by default.

···

--- Trans <transfire@gmail.com> wrote:

I agree that a *true* anonymous function is needed, but also
think it
would be nice if one could selectively "pull down" elements
of closure
somehow.

__________________________________
Yahoo! Mail - PC Magazine Editors' Choice 2005

Zach Dennis wrote:

> I just
> don't particularly care for the proposed syntax:
>
> anon = ->(x = 5) { ... }
>

Was there an RCR for this syntax? If so what is it's name, I do not see
it on rcrchive.net ?

It's Matz' baby; borrwoed from Perl. So no RCR required.

T.

Except that Matz still plans on making anonymous functions have
closure capabilities.

Hmmm. I must have missed that. What does "closure capabilities" mean
exactly?

Keeps local scope at the time that the closure is created.

This is why, after Dave Thomas suggested:

anon = def(x = 5)
   # implementation of anon
end

I then suggested:

anon = lambda(x = 5)
   # implementation of anon
end

To me, this is clearer than any of the other options that have been
so far suggested for anonymous functions.

I was under the impression that it was

  anon = def(x = 5) ... end

for def style semantics (i.e. 'true' anonymous function, opaque scope,
etc.) and

  block = lambda(x = 5) ... end

for closures. If so, then I would endorse these suggestions.

This is not what was discussed on Friday during the roundtable or on
Saturday during the keynote. Both were suggested to solve the same
problem -- that is, the same problem that is currently solved in 1.9
with:

  anon = ->(x = 5) { ... }

I think that a *lot* of people really don't like that notation. Too many
symbols, lack of a left-side for the arrow, etc. But my sense of the
room was that either using def() or lambda() was generally felt to be
cleaner and as meaningful. Using def(), however, means that "def" is
contextually closure/non-closure depending on the presence of a name. It
also seemed to me that Matz wasn't fond of the reuse of "def".

Otherwise, I have to confess, I'm a little confused as to what the
proposal for anonymous functions actually means.

There is a difference between anonymous functions (lambdas) and blocks
in that blocks are considered -- after a fashion -- to be an extension
of the using/calling method. So parameters are passed to blocks in
parallel-assignment fashion and are passed to lambdas as actual
parameter lists. Also, "return" in a block will return from the yielding
function; in a lambda, it will return from the lambda only.

I agree that a *true* anonymous function is needed,

I'm surprised more people don't seem to think real anonymous functions
would be useful. I'm pretty sure they'd be applicable in the majority
of cases where we use blocks now, especially with map, inject, select,
grep, etc. They would surely be more efficient (no need to set up
binding, no lookup outside current scope, lower memory usage).

I have yet to need one (an anonymous function). I personally don't
believe that it would necessarily be more efficient, either. Indeed,
with my use of #map, etc., I tend to liberally use the fact that no new
scope is introduced and that the block is a closure. I think that your
estimation of which would be more useful flies contrary to current use
and likely continued future use of Ruby.

Indeed, I don't think that I'd ever use the lambda() keyword that has
been proposed to replace ->() in 1.9. I could be wrong, but that's just
not my programming style. I almost certainly wouldn't use one that gives
me an anonymous non-closure function. I don't think that that's an
important enough use case, where a named method would work just as well.

Others may find it more useful, but I haven't had a need yet.

[...]

lambda do |x|
   # ... has closure
end

lambda do(x)
   # ... does not have closure
end

I quite like that. While we're at it, how about

I can't stand it. It's entirely too contextual and "magic". If you
really *must* have non-closure anonymous functions, propose a keyword.
Magic punctuation doesn't do it for me. IMO, there's just a little too
much magic punctuation in Ruby as it stands now. (Not much, but I'm not
really comfortable with **kwargs.)

  lambda {|x| .. }

for closure and

  lambda [|x| ... ]

No. That's even uglier than the first.

-austin

···

On 10/18/05, Sean O'Halpin <sean.ohalpin@gmail.com> wrote:

On 10/18/05, Austin Ziegler <halostatue@gmail.com> wrote:
On 10/18/05, Trans <transfire@gmail.com> wrote:

--
Austin Ziegler * halostatue@gmail.com
               * Alternate: austin@halostatue.ca

Maybe if we say it often enough? :wink:

Sean

···

On 10/18/05, Eric Mahurin <eric_mahurin@yahoo.com> wrote:

But, I kind of still
wish we had a syntax where the variables in a block/lambda were
local (non-closure) by default.

Trans wrote:

Zach Dennis wrote:

I just
don't particularly care for the proposed syntax:

anon = ->(x = 5) { ... }

Was there an RCR for this syntax? If so what is it's name, I do not see
it on rcrchive.net ?

It's Matz' baby; borrwoed from Perl. So no RCR required.

Is the -> syntax still open for debate Matz? I agree with Austin on this. The syntax here is just ugly.

Zach

There is a difference between anonymous functions (lambdas) and blocks
in that blocks are considered -- after a fashion -- to be an extension
of the using/calling method.

I see that there is a difference in what either of us means by an
"anonymous function".

I mean something like the body of a def method without a name - what
you get when you use the method() function (i.e. opaque scope, no
closure) - you mean lambda (i.e. closure).

I personally don't believe that it would necessarily be more efficient

Yes, I hadn't thought of the cost of setting up a new scope (silly
considering that is one of the main reasons I would like to see
anonymous functions). I guess the only real way to find out would be
to try it.

It also seemed to me that Matz wasn't fond of the reuse of "def".

Shame - I thought the lambda/def distinction was a good one.

>
> lambda [|x| ... ]

No. That's even uglier than the first.

Ah well. Different eyes I guess :slight_smile:

Sean

···

On 10/18/05, Austin Ziegler <halostatue@gmail.com> wrote:

Austin Ziegler wrote:

This is not what was discussed on Friday during the roundtable or on
Saturday during the keynote. Both were suggested to solve the same
problem -- that is, the same problem that is currently solved in 1.9
with:

  anon = ->(x = 5) { ... }

I think that a *lot* of people really don't like that notation. Too many
symbols, lack of a left-side for the arrow, etc. But my sense of the
room was that either using def() or lambda() was generally felt to be
cleaner and as meaningful. Using def(), however, means that "def" is
contextually closure/non-closure depending on the presence of a name. It
also seemed to me that Matz wasn't fond of the reuse of "def".

I would have to agree with matz actually.

I have yet to need one (an anonymous function). I personally don't
believe that it would necessarily be more efficient, either. Indeed,
with my use of #map, etc., I tend to liberally use the fact that no new
scope is introduced and that the block is a closure. I think that your
estimation of which would be more useful flies contrary to current use
and likely continued future use of Ruby.

Indeed, I don't think that I'd ever use the lambda() keyword that has
been proposed to replace ->() in 1.9. I could be wrong, but that's just
not my programming style. I almost certainly wouldn't use one that gives
me an anonymous non-closure function. I don't think that that's an
important enough use case, where a named method would work just as well.

Others may find it more useful, but I haven't had a need yet.

In many cases I don't think it would matter which was used. So if
non-closure is at all more efficient that's agood thing. Either way I
have come across situations where I NEED non-closure, but there is
currently no reasonable way to do it.

[...]
>> lambda do |x|
>> # ... has closure
>> end
>>
>> lambda do(x)
>> # ... does not have closure
>> end
> I quite like that. While we're at it, how about

I can't stand it. It's entirely too contextual and "magic". If you
really *must* have non-closure anonymous functions, propose a keyword.
Magic punctuation doesn't do it for me. IMO, there's just a little too
much magic punctuation in Ruby as it stands now. (Not much, but I'm not
really comfortable with **kwargs.)

I agree with you on both accounts. I don;' think it's a good idea, but
perhaps it might stimulate some better ideas. And I concur **kwargs is
stinky.

> lambda {|x| .. }
>
> for closure and
>
> lambda [|x| ... ]

No. That's even uglier than the first.

When you consider all the other proposals, this really stands out as
the *least* ugly way it could be done, and have suggested it too.
Unfortuantely it has one major problem. It is ambigious with #
method. To overcome you'd either have to always use a space before the
block or always incldue the bars ||. Both suck. Of course with Matz'
perly notation,

  ->(x=4)[ ... ]

That problem goes away too :wink:

T.

Doubtful. I think to convince matz, real examples would need to be
presented (as an RCR!) as to why this is necessary. IANM, but IMO
theoretical need and wish ain't sufficient.

-austin

···

On 10/18/05, Sean O'Halpin <sean.ohalpin@gmail.com> wrote:

On 10/18/05, Eric Mahurin <eric_mahurin@yahoo.com> wrote:
> But, I kind of still
> wish we had a syntax where the variables in a block/lambda were
> local (non-closure) by default.
Maybe if we say it often enough? :wink:

--
Austin Ziegler * halostatue@gmail.com
               * Alternate: austin@halostatue.ca

Zach Dennis wrote:

Trans wrote:

Zach Dennis wrote:

I just
don't particularly care for the proposed syntax:

anon = ->(x = 5) { ... }

Was there an RCR for this syntax? If so what is it's name, I do not see
it on rcrchive.net ?

It's Matz' baby; borrwoed from Perl. So no RCR required.

Is the -> syntax still open for debate Matz? I agree with Austin on this. The syntax here is just ugly.

I wanted to partially rephrase this last comment in case it comes across the wrong way. Is the syntax open for debate at all? If not then I respectfully withdraw any further arguments on my behalf on this topic. If it is open for debate, then I'd like to voice my opinion as others have already, that I would rather prefer a more elegant syntax.

Thanks,

Zach