Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > Anonymous methods, blocks etc. (Cont. 'default block params')

Reply
Thread Tools

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

 
 
ES
Guest
Posts: n/a
 
      10-15-2005
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

E


 
Reply With Quote
 
 
 
 
robertj
Guest
Posts: n/a
 
      10-16-2005
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

 
Reply With Quote
 
 
 
 
Wilson Bilkovich
Guest
Posts: n/a
 
      10-16-2005
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 <(E-Mail Removed)> 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 =3D &anInstance.method
>
> and then of course
> aproc()
>
> ciao robertj
>
>
>



 
Reply With Quote
 
ES
Guest
Posts: n/a
 
      10-16-2005
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.
>
> On 10/16/05, robertj <(E-Mail Removed)> 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


E



 
Reply With Quote
 
Sean O'Halpin
Guest
Posts: n/a
 
      10-18-2005
On 10/15/05, ES <(E-Mail Removed)> 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.

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


 
Reply With Quote
 
Austin Ziegler
Guest
Posts: n/a
 
      10-18-2005
On 10/18/05, Sean O'Halpin <(E-Mail Removed)> wrote:
> On 10/15/05, ES <(E-Mail Removed)> 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 =3D def(x =3D 5)
# implementation of anon
end

I then suggested:

anon =3D lambda(x =3D 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 =3D ->(x =3D 5) { ... }

-austin
--
Austin Ziegler * http://www.velocityreviews.com/forums/(E-Mail Removed)
* Alternate: (E-Mail Removed)


 
Reply With Quote
 
Trans
Guest
Posts: n/a
 
      10-18-2005

Austin Ziegler wrote:
> On 10/18/05, Sean O'Halpin <(E-Mail Removed)> wrote:
> > On 10/15/05, ES <(E-Mail Removed)> 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.

 
Reply With Quote
 
Sean O'Halpin
Guest
Posts: n/a
 
      10-18-2005
On 10/18/05, Austin Ziegler <(E-Mail Removed)> wrote:
> Except that Matz still plans on making anonymous functions have closure
> capabilities.

Hmmm. I must have missed that. What does "closure capabilities" mean exactl=
y?

> This is why, after Dave Thomas suggested:
>
> anon =3D def(x =3D 5)
> # implementation of anon
> end
>
> I then suggested:
>
> anon =3D lambda(x =3D 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 =3D def(x =3D 5) ... end

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

block =3D lambda(x =3D 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


 
Reply With Quote
 
Sean O'Halpin
Guest
Posts: n/a
 
      10-18-2005
On 10/18/05, Trans <(E-Mail Removed)> wrote:

> 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


 
Reply With Quote
 
Austin Ziegler
Guest
Posts: n/a
 
      10-18-2005
On 10/18/05, Sean O'Halpin <(E-Mail Removed)> wrote:
> On 10/18/05, Austin Ziegler <(E-Mail Removed)> 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?


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

>> This is why, after Dave Thomas suggested:
>>
>> anon =3D def(x =3D 5)
>> # implementation of anon
>> end
>>
>> I then suggested:
>>
>> anon =3D lambda(x =3D 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 =3D def(x =3D 5) ... end
>
> for def style semantics (i.e. 'true' anonymous function, opaque scope,
> etc.) and
>
> block =3D lambda(x =3D 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 =3D ->(x =3D 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.


> On 10/18/05, Trans <(E-Mail Removed)> wrote:
>> 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
--
Austin Ziegler * (E-Mail Removed)
* Alternate: (E-Mail Removed)


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Is this a local anonymous class or a member anonymous class Reporter Java 3 05-12-2007 05:23 AM
Fo:Block can you check to see if a block contains any text by using the block id? morrell XML 1 10-10-2006 07:18 PM
procs/blocks - blocks with procs, blocks with blocks? matt Ruby 1 08-06-2004 01:33 AM



Advertisments