Method annotation and anonymous functions

> 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).

I agree. See the thread "Anonymous methods, blocks etc. (Cont.
'default block params')" starting at ruby-talk/160709 for some recent
discussion about this.

[ruby-talk:150709] is what I think you meant. The discussion actually
stems from the ruby-dev summary in [ruby-talk:150581].

> Then we could also have named closures as well:
>
> class Foo
> a = 42
> lambda foo(b, c)
> puts a, b, c
> end
> end

That's an interesting idea. It would certainly be orthogonal. However,
you can already do that with define_method:

  class Foo
    a = 42
    define_method(:foo) do |b, c|
      puts a, b, c
    end
  end

  Foo.new.foo(1,2)
  __END__
  42
  1
  2

define_method takes a block, which currently passes arguments by
multiple assignment. That's not what we want. You are right that we
could use define_method, but I think it would look more like this:

a = 42
l = lambda (b, c=10) { puts a, b, c }
define_method(:foo, &l)

> Currently, the following code works fine:
[snip]
> But I would imagine that if lambda were a keyword this would confuse the
> parser.

Well, I doubt it would break ~much~ code. It would be quite an unusual
thing to define a function named lamdba(), no?

I agree that it would not break much code. But it must be considered,
even if this is the conclusion.

[snip discussion about || vs <> block local syntax]

I think you're on a losing wicket here. It seems that the zeitgeist is
with the semi-colon to introduce block locals.

My point was that the distintion we want to make is between passing
block arguments through multiple assignment and passing block arguments
method style, rather than between anonymous procs and anonymous
functions/closures. The two differ only in how their arguments are
passed; the syntax IMO should reflect that.

I wasn't intending to make a point about block-locals; I thought they
were a side-effect (but perhaps I was wrong).

With argument passing through multiple assignment (|...|), it is okay
for block parameters to not be block-local. The result is that the
variable gets assigned. Matz has previously stated that all block
parameters will be block-local; he may change (or have already changed)
his mind; I pointed it out because it may or may not remain as is.

With passing arguments method-style (what I was using <...> for, though
I know that syntax has some issues), block parameters probably shouldn't
be block-local. My thought was that if you're not going to use multiple
assignment for argument passing, you shouldn't use assignment at all.
The only way around the assignment is to create a new variable that is
block-local.

Paul

···

On Thu, Oct 20, 2005 at 05:33:37AM +0900, Sean O'Halpin wrote:

On 10/19/05, Paul Brannan <pbrannan@atdesk.com> wrote:

Jeff Wood wrote:

Yes it would, but I don't see another way to do attribution of methods
without causing compatibility issues .... do you?

Nitro/Facets annotations system works like so:

  class X
    def foo ; "foo" ; end
    ann :foo, :returns => String
  end

  X.ann :foo, :log => true

  X.ann.foo.returns #=> String
  X.ann.foo.log #=> true

Also,

  class X
    attr :bar, :log => true
  end

Would a special syntax be better? Maybe, but not neccessary.

T.

Hi --

Hi --

Most languages define some token that specifically states method attribute...
Java uses @... since @ isn't a used char otherwise.

for us ... it would need to be something else ...

and it would simply bind to the function its declared in, just like
functions bind to the classes they are declared in.

how 'bout

def method1( a, b )
->visibility = true
->returns = int
# actually do some work...
...
end

just thinking out loud... since it would have a new punctuation it
wouldn't introduce incompatibility.

Worse: it would introduce new punctuation :slight_smile:

Yes it would, but I don't see another way to do attribution of methods
without causing compatibility issues .... do you?

I think I'm coming from a different perspective. I haven't seen any
examples of this that make me think it's worth either incompatibility
or new punctuation. I strongly dislike the idea of having a
specification of the class of the return value (object) of a method,
since that militates against duck typing. But maybe that's just an
example.

David

···

On Thu, 20 Oct 2005, Jeff Wood wrote:

On 10/19/05, David A. Black <dblack@wobblini.net> wrote:

On Thu, 20 Oct 2005, Jeff Wood wrote:

--
David A. Black
dblack@wobblini.net

Hi --

Jeff Wood wrote:

Yes it would, but I don't see another way to do attribution of methods
without causing compatibility issues .... do you?

Nitro/Facets annotations system works like so:

class X
   def foo ; "foo" ; end
   ann :foo, :returns => String
end

X.ann :foo, :log => true

X.ann.foo.returns #=> String

Ugh, if I may permit myself the expression That means goodbye to
things like:

   def meth(thing)
     thing[some_thing_else]
   end

Pinning down the class of return values is similar to pinning down the
class of arguments -- arguably even more duck-typing-unfriendly, since
you're specifying not only what a given object has to be but,
potentially, what *its* methods have to return.

David

···

On Thu, 20 Oct 2005, Trans wrote:

--
David A. Black
dblack@wobblini.net

It's useful for documentation.

I like that ri Array#+ tells me that + returns an array. If ri told me
that it returned an object that supports the and = operations, I
would possibly convert the return value to an array before using it.

IMO what a method expects from the user should be as minimal as
possible, to make the method as reuseable as possible, but what the user
can expect from a method (both what the method does and what it returns)
should be very precisely specified. If the type or meaning of the
return value of a method changes, there will often be an
incompatibility; such changes should be made with caution.

Paul

···

On Thu, Oct 20, 2005 at 09:40:21AM +0900, David A. Black wrote:

I think I'm coming from a different perspective. I haven't seen any
examples of this that make me think it's worth either incompatibility
or new punctuation. I strongly dislike the idea of having a
specification of the class of the return value (object) of a method,
since that militates against duck typing. But maybe that's just an
example.

... the attributes have NOTHING to do with duck typing... that was
simply an example chosen by somebody else.

I would be using the attributes for testing ...

def mytest_of_doom()
  ann :doc "This function does some blah with blah."
  ann :test
  ann :group :working, :ui
  # do stuff
end

then you can do things like, I want a list of all functions that are
tests. or all functions that are part of group <x> ... or, even
better, run-time functionality for getting information on a function
while in irb ... ( think about the help() function in python ).

Those would all be killer uses of attributed functions.

the type thing was simply an example. and notice it had nothing to do
with input params ( still whatever you want ). but, it does let you
know what the function will spit ( and that helps ides and editors
since now they can provide you with a list of methods after the
chain... )

It's really a VERY cool idea. I really hope it makes it in. I know
most people seem to hate adding a little punctuation ... but sometimes
it can be a good thing.

j.

···

On 10/19/05, David A. Black <dblack@wobblini.net> wrote:

Hi --

On Thu, 20 Oct 2005, Trans wrote:

>
> Jeff Wood wrote:
>> Yes it would, but I don't see another way to do attribution of methods
>> without causing compatibility issues .... do you?
>
> Nitro/Facets annotations system works like so:
>
> class X
> def foo ; "foo" ; end
> ann :foo, :returns => String
> end
>
> X.ann :foo, :log => true
>
> X.ann.foo.returns #=> String

Ugh, if I may permit myself the expression That means goodbye to
things like:

   def meth(thing)
     thing[some_thing_else]
   end

Pinning down the class of return values is similar to pinning down the
class of arguments -- arguably even more duck-typing-unfriendly, since
you're specifying not only what a given object has to be but,
potentially, what *its* methods have to return.

David

--
David A. Black
dblack@wobblini.net

--
"http://ruby-lang.org -- do you ruby?"

Jeff Wood

I'll be the devil's advocate... A good use of something like
this would be if we had a VM that had type inference (like the
self VM). Where it had trouble inferring the type (pretty much
a class - to get the exact methods at compile time), giving the
class of the args and return value would help it.

But of course the best solution is to improve the type
inference engine (if we had one). Ruby is a dynamically typed
language and I think it should stay that way. Let the VM guys
continually do optimizations instead of dirting the language
with static-type hints. I'd be afraid of too many people
abusing it and disabling the power and beauty of duck-typing.

···

--- "David A. Black" <dblack@wobblini.net> wrote:

Hi --

On Thu, 20 Oct 2005, Trans wrote:

>
> Jeff Wood wrote:
>> Yes it would, but I don't see another way to do
attribution of methods
>> without causing compatibility issues .... do you?
>
> Nitro/Facets annotations system works like so:
>
> class X
> def foo ; "foo" ; end
> ann :foo, :returns => String
> end
>
> X.ann :foo, :log => true
>
> X.ann.foo.returns #=> String

Ugh, if I may permit myself the expression That means
goodbye to
things like:

   def meth(thing)
     thing[some_thing_else]
   end

Pinning down the class of return values is similar to pinning
down the
class of arguments -- arguably even more
duck-typing-unfriendly, since
you're specifying not only what a given object has to be but,
potentially, what *its* methods have to return.

__________________________________
Yahoo! Music Unlimited
Access over 1 million songs. Try it free.
http://music.yahoo.com/unlimited/

David A. Black wrote:

Hi --

>
> Jeff Wood wrote:
>> Yes it would, but I don't see another way to do attribution of methods
>> without causing compatibility issues .... do you?
>
> Nitro/Facets annotations system works like so:
>
> class X
> def foo ; "foo" ; end
> ann :foo, :returns => String
> end
>
> X.ann :foo, :log => true
>
> X.ann.foo.returns #=> String

Ugh, if I may permit myself the expression That means goodbye to
things like:

   def meth(thing)
     thing[some_thing_else]
   end

Pinning down the class of return values is similar to pinning down the
class of arguments -- arguably even more duck-typing-unfriendly, since
you're specifying not only what a given object has to be but,
potentially, what *its* methods have to return.

Perhaps a bad example, b/c as Jeff said, it has no actual effect on
anything. Annotations are just notes. Nothing more. They only become
more when people use them to do particular stuff. For instance Og uses
them to determine how to map objects to a sql/database.

In fact I would like to add annotation namespaces. So that Og can
separate it's annotations from other's. But I'm not yet sure how that
will effect the interface.

T.

···

On Thu, 20 Oct 2005, Trans wrote:

Attributes don't do a whole lot of good unless there is a
standard set of them. And attributes that have to do with
static-typing (in a dynamically typed language) shouldn't be in
that set. If the attributes are completely arbitrary and have
no effect, then they should just be in the comments.

···

--- Jeff Wood <jeff.darklight@gmail.com> wrote:

... the attributes have NOTHING to do with duck typing...
that was
simply an example chosen by somebody else.

I would be using the attributes for testing ...

__________________________________________________
Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around

Seriously ....

It's not about the type stuff ... that was a bad example cause it set
everybody off ... and you're using it as a Red Herring ... "It sucks
because it's for return types! It breaks duck typing ! " .... It
doesn't change anything, it simply gives you information you can later
query about a method.

It's for whatever people want to say about the method ( like maybe a
warning that the function modifies it's object, or a documentation
string available during runtime? or whatever else, like maybe a flag
to say that a functions already been modified by some aspect-oriented
code or meta-programming hook or something, in case somebody makes a
cyclic reference... )

Matz surely wouldn't let people try to get him to hardcode a list of
available attributes or something... and, there's no mandate that you
have to use them when they do exist.

This would be a useful thing. Why not let methods be objects too?

Anyways, please disregard the return annotation, it's simply a
meaningless example ( but that's something that should be confirmed by
the OP ).

j.

···

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

--- "David A. Black" <dblack@wobblini.net> wrote:

> Hi --
>
> On Thu, 20 Oct 2005, Trans wrote:
>
> >
> > Jeff Wood wrote:
> >> Yes it would, but I don't see another way to do
> attribution of methods
> >> without causing compatibility issues .... do you?
> >
> > Nitro/Facets annotations system works like so:
> >
> > class X
> > def foo ; "foo" ; end
> > ann :foo, :returns => String
> > end
> >
> > X.ann :foo, :log => true
> >
> > X.ann.foo.returns #=> String
>
> Ugh, if I may permit myself the expression That means
> goodbye to
> things like:
>
> def meth(thing)
> thing[some_thing_else]
> end
>
> Pinning down the class of return values is similar to pinning
> down the
> class of arguments -- arguably even more
> duck-typing-unfriendly, since
> you're specifying not only what a given object has to be but,
> potentially, what *its* methods have to return.

I'll be the devil's advocate... A good use of something like
this would be if we had a VM that had type inference (like the
self VM). Where it had trouble inferring the type (pretty much
a class - to get the exact methods at compile time), giving the
class of the args and return value would help it.

But of course the best solution is to improve the type
inference engine (if we had one). Ruby is a dynamically typed
language and I think it should stay that way. Let the VM guys
continually do optimizations instead of dirting the language
with static-type hints. I'd be afraid of too many people
abusing it and disabling the power and beauty of duck-typing.

__________________________________
Yahoo! Music Unlimited
Access over 1 million songs. Try it free.
http://music.yahoo.com/unlimited/

--
"http://ruby-lang.org -- do you ruby?"

Jeff Wood

Hi --

It's really a VERY cool idea. I really hope it makes it in. I know
most people seem to hate adding a little punctuation ... but sometimes
it can be a good thing.

The thing is, I've spent literally years watching literally dozens and
dozens of things being suggested, *all* of which involve new
punctuation and all of which someone thinks are good ideas. If even a
tenth of them were adopted, Ruby would be about 90% of the way to
being in the Perl bracket of punctuation intensity.

I know it sounds strange, but I actually consider the clean line of
Ruby a "feature" (albeit an optional one, as to its use :slight_smile: which
counts for more than almost every RCR imaginable to me.

David

···

On Thu, 20 Oct 2005, Jeff Wood wrote:

--
David A. Black
dblack@wobblini.net

David A. Black wrote:

I know it sounds strange, but I actually consider the clean line of
Ruby a "feature" (albeit an optional one, as to its use :slight_smile: which
counts for more than almost every RCR imaginable to me.

+1

Hi --

It's really a VERY cool idea. I really hope it makes it in. I know
most people seem to hate adding a little punctuation ... but sometimes
it can be a good thing.

What punctuation has to be added? I like the way it is done in the example.

The thing is, I've spent literally years watching literally dozens and
dozens of things being suggested, *all* of which involve new
punctuation and all of which someone thinks are good ideas. If even a
tenth of them were adopted, Ruby would be about 90% of the way to
being in the Perl bracket of punctuation intensity.

I know it sounds strange, but I actually consider the clean line of
Ruby a "feature" (albeit an optional one, as to its use :slight_smile: which
counts for more than almost every RCR imaginable to me.

I agree about the syntax. The example that Tran provided doesn't require new syntax, it works, and it does something that I think is *very* useful. I'll reproduce his example here:

class X
   def foo ; "foo" ; end
   ann :foo, :returns => String
end

X.ann :foo, :log => true

X.ann.foo.returns #=> String

This is simple and so unexpected, to me at least, that it seems brilliant (forget the :returns bit, it is irrelevant). I think I'm still not used to what can be done with the mixing of compilation and runtime in ruby.

I tried writing a toy implementation of this last night to see if it'll solve a problem that I'm going to have to deal with soon. I'm working on a system that automatically augments class definitions and this is a great way for a programmer to provide additional hints and fine-tuning control -- in fact, this opens up a lot of possibilities. The implementation I came up with requires that include/extend trick that Robert Klemme mentioned in the "class method aliasing" thread the other day, but still. I'll soon cheat and look at what nitro and facets did.

Cheers,
Bob

···

On Oct 20, 2005, at 7:47 AM, David A. Black wrote:

On Thu, 20 Oct 2005, Jeff Wood wrote:

David

--
David A. Black
dblack@wobblini.net

----
Bob Hutchison -- blogs at <http://www.recursive.ca/hutch/&gt;
Recursive Design Inc. -- <http://www.recursive.ca/&gt;
Raconteur -- <http://www.raconteur.info/&gt;

Selon Tim Hunter <sastph@sas.com>:

David A. Black wrote:
> I know it sounds strange, but I actually consider the clean line of
> Ruby a "feature" (albeit an optional one, as to its use :slight_smile: which
> counts for more than almost every RCR imaginable to me.

+1

+100 (or is that not allowed to add so many points at once? :wink: )

···

--
Christophe Grandsire.

http://rainbow.conlang.free.fr

It takes a straight mind to create a twisted conlang.

I agree with you that it is nice and clean, and to me punctuation, methods,
keywords ... all the same ...

so, yeah if somebody wants ann or attrib or whatever, that's fine ... but,
having to pass a symbol for the wrapping function is bogus. You are inside
the declaration of the function, that should be enough. ... There are
methods in Kernel to tell what method you are inside ... Use those inside
your attrb or whatever function so that people don't have to deal with that
...

It's just another source of confusion when somebody forgets to update a
symbol on their attributes.

anyways. I agree, I absolutely love ruby's syntax ... I wouldn't trade it
... and if there's a method that'll do the attributes cleanly, then I'm all
for it ... I don't *want* the punctuation, I just figured it was cleaner (
but cleaner doesn't mean clearer ) ... but, matz is *almost* :wink: always right
in his decisions ( all respect intended ).

j.

···

On 10/20/05, Bob Hutchison <hutch@recursive.ca> wrote:

On Oct 20, 2005, at 7:47 AM, David A. Black wrote:

> Hi --
>
> On Thu, 20 Oct 2005, Jeff Wood wrote:
>
>
>> It's really a VERY cool idea. I really hope it makes it in. I know
>> most people seem to hate adding a little punctuation ... but
>> sometimes
>> it can be a good thing.

What punctuation has to be added? I like the way it is done in the
example.

>>
>
> The thing is, I've spent literally years watching literally dozens and
> dozens of things being suggested, *all* of which involve new
> punctuation and all of which someone thinks are good ideas. If even a
> tenth of them were adopted, Ruby would be about 90% of the way to
> being in the Perl bracket of punctuation intensity.
>
> I know it sounds strange, but I actually consider the clean line of
> Ruby a "feature" (albeit an optional one, as to its use :slight_smile: which
> counts for more than almost every RCR imaginable to me.

I agree about the syntax. The example that Tran provided doesn't
require new syntax, it works, and it does something that I think is
*very* useful. I'll reproduce his example here:

>> class X
>> def foo ; "foo" ; end
>> ann :foo, :returns => String
>> end
>>
>> X.ann :foo, :log => true
>>
>> X.ann.foo.returns #=> String

This is simple and so unexpected, to me at least, that it seems
brilliant (forget the :returns bit, it is irrelevant). I think I'm
still not used to what can be done with the mixing of compilation and
runtime in ruby.

I tried writing a toy implementation of this last night to see if
it'll solve a problem that I'm going to have to deal with soon. I'm
working on a system that automatically augments class definitions and
this is a great way for a programmer to provide additional hints and
fine-tuning control -- in fact, this opens up a lot of possibilities.
The implementation I came up with requires that include/extend trick
that Robert Klemme mentioned in the "class method aliasing" thread
the other day, but still. I'll soon cheat and look at what nitro and
facets did.

Cheers,
Bob

>
>
> David
>
> --
> David A. Black
> dblack@wobblini.net
>
>

----
Bob Hutchison -- blogs at <http://www.recursive.ca/hutch/&gt;
Recursive Design Inc. -- <http://www.recursive.ca/&gt;
Raconteur -- <http://www.raconteur.info/&gt;

--
"http://ruby-lang.org -- do you ruby?"

Jeff Wood