Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Rules for method resolution?

6 views
Skip to first unread message

Dan Sugalski

unread,
Feb 13, 2004, 11:38:07 AM2/13/04
to perl6-i...@perl.org
So, as I dive into PDD15 as promised and get objects spec'd out so
they can finally be implemented, I've come across the problem of
method resolution.

We've got, or will have, two ways to invoke methods. The first is a simple:

callmethod "methodname"

which calls the named method on the object in the object slot, does
all the funky lookups and whatnot, and slams the method PMC into the
. That's fine. May even mandate a:

callmethod Pobject, "methodname"

which'll move the object to the object slot. Or not. But that's
beside the point.

We also have to have a way to fetch the method PMC for a named method
for later use, which is where the interesting bits come in.

This is required for a number of reasons, including Python, so we
have to have it. The question is... *When* is the name resolved? That
is, if we do:

findmethod P4, Pobject, "methodname"

does the method PMC that gets stuck in P4 represent the method
"methodname" for the object *at that point in time* or does it
represent the method *at the time it is invoked*? That is, do we
defer actual lookup until invocation, or do we resolve at method find
time?

This has some implications for when methods are overridden and
namespaces swapped in and out, so it's (unfortunately) not an
academic exercise.
--
Dan

--------------------------------------"it's like this"-------------------
Dan Sugalski even samurai
d...@sidhe.org have teddy bears and even
teddy bears get drunk

Dan Sugalski

unread,
Feb 13, 2004, 12:06:52 PM2/13/04
to perl6-i...@perl.org
At 11:38 AM -0500 2/13/04, Dan Sugalski wrote:
>which calls the named method on the object in the object slot, does
>all the funky lookups and whatnot, and slams the method PMC into the
>.

That sentence should end "into the appropriate register."

Jerry Gay

unread,
Feb 13, 2004, 12:32:51 PM2/13/04
to Dan Sugalski, perl6-i...@perl.org
> We also have to have a way to fetch the method PMC for a named method
> for later use, which is where the interesting bits come in.
>
> This is required for a number of reasons, including Python, so we
> have to have it. The question is... *When* is the name resolved? That
> is, if we do:
>
> findmethod P4, Pobject, "methodname"
>
> does the method PMC that gets stuck in P4 represent the method
> "methodname" for the object *at that point in time* or does it
> represent the method *at the time it is invoked*? That is, do we
> defer actual lookup until invocation, or do we resolve at method find
> time?
>
> This has some implications for when methods are overridden and
> namespaces swapped in and out, so it's (unfortunately) not an
> academic exercise.
> --

is it too much trouble to implement both, and give the HLLs a choice of
which they call?

would 'findmethod_sooner' and 'findmethod_later' be too difficult to
implement, or too large to add to the core ops?

what do you lose by offering both, as opposed to one or the other?

i wish i had more answers than questions...

--jerry *no longer just a lurker*

**************************************************************************
This e-mail and any files transmitted with it may contain privileged or
confidential information. It is solely for use by the individual for whom
it is intended, even if addressed incorrectly. If you received this e-mail
in error, please notify the sender; do not disclose, copy, distribute, or
take any action in reliance on the contents of this information; and delete
it from your system. Any other use of this e-mail is prohibited. Thank you
for your compliance.

Dan Sugalski

unread,
Feb 13, 2004, 12:40:38 PM2/13/04
to Gay, Jerry, perl6-i...@perl.org
At 12:32 PM -0500 2/13/04, Gay, Jerry wrote:
> > We also have to have a way to fetch the method PMC for a named method
>> for later use, which is where the interesting bits come in.
>>
>> This is required for a number of reasons, including Python, so we
>> have to have it. The question is... *When* is the name resolved? That
>> is, if we do:
>>
>> findmethod P4, Pobject, "methodname"
>>
>> does the method PMC that gets stuck in P4 represent the method
>> "methodname" for the object *at that point in time* or does it
>> represent the method *at the time it is invoked*? That is, do we
>> defer actual lookup until invocation, or do we resolve at method find
>> time?
>>
>> This has some implications for when methods are overridden and
>> namespaces swapped in and out, so it's (unfortunately) not an
>> academic exercise.
>> --
>
>is it too much trouble to implement both, and give the HLLs a choice of
>which they call?

Well... the problem is that at the point of call you really don't
know which type you have, and arguably ought not know, and just do
whatever the PMC thinks is proper, presuming the find returned a PMC
that Does The Right Thing.

Which answers the question, in its own way -- I'll make it "it
depends" and leave it up to the class authors/language designers to
decide what the heck to do with pre-looked-up methods.

Michal Wallace

unread,
Feb 14, 2004, 11:50:43 PM2/14/04
to Dan Sugalski, perl6-i...@perl.org
On Fri, 13 Feb 2004, Dan Sugalski wrote:

> We also have to have a way to fetch the method PMC for a named method
> for later use, which is where the interesting bits come in.
>
> This is required for a number of reasons, including Python, so we
> have to have it. The question is... *When* is the name resolved? That
> is, if we do:
>
> findmethod P4, Pobject, "methodname"
>
> does the method PMC that gets stuck in P4 represent the method
> "methodname" for the object *at that point in time* or does it
> represent the method *at the time it is invoked*? That is, do we
> defer actual lookup until invocation, or do we resolve at method find
> time?


For python, you want P4 to contain the method as
it is when this op is run.

But the whole idea of a findmethod seems very
unpythonic to me. In python, a method is just another
attribute... One that happens to be callable and also
happens to know what instance it's bound to.

Consider the second line in this code:

x = input()
x.foo()

Is that a method call or a function call? The
compiler has no possible way of knowing, so the
second line should be compiled as if it were:

_temp_ = getattr(x, "foo")
_temp_()
del _temp_

Maybe for python, findmethod and getprop (or whatever
the new eqivalent is) are the same... But I'd suspect
that getprop is all any (working) python compiler will
use.

Here are a couple examples of python weirdness:


EXAMPLE 1 - whose method is this, anyway?


class Alice:
def whoami(self):
return "Alice"
class Bruce:
def whoami(self):
return "Bruce"

a = Alice()
b = Bruce()

a.whoami, b.whoami = b.whoami, a.whoami
assert a.whoami()=="Bruce"
assert b.whoami()=="Alice"

# and just for kicks:
freestanding = a.whoami
assert freestanding() == "Bruce"


EXAMPLE 2 - callable classes as methods

class Methodical:
def __call__(self):
return "muahahahaha"

class Owner:
pass

x = Owner()
x.method = Methodical()
assert x.method() == "muahahahaha"


Sincerely,

Michal J Wallace
Sabren Enterprises, Inc.
-------------------------------------
contact: mic...@sabren.com
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
-------------------------------------

Michal Wallace

unread,
Feb 15, 2004, 12:04:22 AM2/15/04
to perl6-i...@perl.org
On Sat, 14 Feb 2004, Michal Wallace wrote:

> class Alice:
> def whoami(self):
> return "Alice"
> class Bruce:
> def whoami(self):
> return "Bruce"
>
> a = Alice()
> b = Bruce()
>
> a.whoami, b.whoami = b.whoami, a.whoami
> assert a.whoami()=="Bruce"
> assert b.whoami()=="Alice"


I'm not sure it affects my argument, but
here's a better example:

class Person:
def __init__(self, name):
self.name = name
def whoami(self):
return self.name

a = Person("alice")
b = Person("bob")


a.whoami, b.whoami = b.whoami, a.whoami

assert (a.name == "alice") and (a.whoami() == "bob")
assert (b.name == "bob") and (b.whoami() == "alice")

Luke Palmer

unread,
Feb 15, 2004, 2:25:20 AM2/15/04
to Michal Wallace, Dan Sugalski, perl6-i...@perl.org
Michal Wallace writes:
> On Fri, 13 Feb 2004, Dan Sugalski wrote:
>
> > We also have to have a way to fetch the method PMC for a named method
> > for later use, which is where the interesting bits come in.
> >
> > This is required for a number of reasons, including Python, so we
> > have to have it. The question is... *When* is the name resolved? That
> > is, if we do:
> >
> > findmethod P4, Pobject, "methodname"
> >
> > does the method PMC that gets stuck in P4 represent the method
> > "methodname" for the object *at that point in time* or does it
> > represent the method *at the time it is invoked*? That is, do we
> > defer actual lookup until invocation, or do we resolve at method find
> > time?
>
>
> For python, you want P4 to contain the method as
> it is when this op is run.
>
> But the whole idea of a findmethod seems very
> unpythonic to me. In python, a method is just another
> attribute... One that happens to be callable and also
> happens to know what instance it's bound to.

As with Perl 6. A sub object has a C<do> trait which specifies what to
do when it's called.

But I think findmethod is a good idea, cross-language-wise. Each
language has a different idea of what a method is, and they can store it
that way. As long as findmethod is vtableable, you can hook it up to
whatever system your language uses.

Luke

Michal Wallace

unread,
Feb 15, 2004, 10:12:20 AM2/15/04
to Luke Palmer, Dan Sugalski, perl6-i...@perl.org
On Sun, 15 Feb 2004, Luke Palmer wrote:

> As with Perl 6. A sub object has a C<do> trait which specifies what
> to do when it's called.

Cool.

> But I think findmethod is a good idea, cross-language-wise. Each
> language has a different idea of what a method is, and they can
> store it that way. As long as findmethod is vtableable, you can
> hook it up to whatever system your language uses.

I was thinking the same thing as I wrote my post
last night... But I'm not convinced.
Suppose I do something like this:

x = parrot.find("perl::whatever")
x.method()

Is that second line a method call or a function call?
It depends whether x is an object or not. Now maybe
in SOME cases (no dynamic input) a compiler could be
smart enough to tell for python... But how could I
ever know cross language?

How will the compiler know to emit findmethod here
rather than getproperty?

I would suggest that since perl and python both
work this way, this is the way it should work
for parrot.

If a language happens to let you do something like:

class MultiAttribute {
x : int = 2;
method x() {
return 1;
}
}

Then getattr(x) should return some kind of smart
attribute that knows how to evaluate to 2 if it's
used as an int or 5 if it's called.

And what about this?

class MultiMethod {
method x(a:int) { return a+1; }
method x(a:str) { return 200; }
}


Which x does the get? or does my compiler have to be
smart enough to look at the arguments that get passed
in? I submit that's impossible to determine, too:


args = input("enter arguments")
foo.multimethod(*args)


I think all methods for all languages should act the
perl/python way for this reason. Or at least all
languages that want to talk to each other should
emit getprop (or something like it) and then if the
property is invoked, it should be called just like a
normal function. If it needs a magic "self" variable
or does some kind of dispatch based on the arguments,
then that should be handled internally by the method
PMC.

In fact, since I'm on the subject, properties and
attributes also have this problem. If we want our
languages to work together there should be one and
only one type of "slot" on an object. It should
be up to the PMC itself to determine how that
works internally. If a more static language has
objects that are all the same size and wants attributes
instead of properties then it should handle that
internally. The interface should be the same either way.

Dan Sugalski

unread,
Feb 16, 2004, 10:45:32 AM2/16/04
to Michal Wallace, perl6-i...@perl.org
At 11:50 PM -0500 2/14/04, Michal Wallace wrote:
>
>Maybe for python, findmethod and getprop (or whatever
>the new eqivalent is) are the same... But I'd suspect
>that getprop is all any (working) python compiler will
>use.

I've chopped out everything but this bit, since it's perfectly valid,
and I think it's the important bit -- getprop and findmethod may well
do exactly the same thing on python objects, and that's just fine.
From what I can tell, the rule when fetching a 'property' (that is, a
named thingie tacked onto a PMC) is "return a bound method doodad if
it exists, otherwise return the property result"

The big question is whether you treat the returned value as a plain
scalar thing, or as a subroutine. That is, if you do:

x = object.some_name

can you then do:

x(1, 2, 3)

or not?

I'm not sure that, in the general case, too many compilers will use
findmethod anyway, as I'm not sure it's too common an activity, and I
think (but may be wrong) that making the result bound won't be
universal at all.

This may well be a case where a python compiler actually emits a
chunk 'o code, perhaps something like:

fetchmethod METHOD, OBJECT, "Foo"
isnull METHOD, getproperty
bind SUB_PMC, OBJECT, METHOD
return SUB_PMC
getproperty:
getprop PROPERTY, OBJECT, "Foo"
isnull PROPERTY, whine
return PROPERTY
whine:
throw UNBINDABLE_NAME, "Can't bind Foo"

or something kinda sorta like that. (Assuming we provide a bind op to
turn an object/method pair into a sub PMC that, when called, acts
like you called the method on the object)

I *think* I'd prefer the PMC findmethod vtable entry to return an
unbound method, since I think I'd like to have the plain method
invocation use that vtable entry to find the method, and if so I'd
like to use the result in the cache system as well.

I've no problem providing a binding scheme as part of the core, nor
of providing some sort of mutant "method_or_prop" op that looks for a
method and, if no joy, looks for a property.

We may end up with some sort of compiler game here, though.

Dan Sugalski

unread,
Feb 16, 2004, 11:10:29 AM2/16/04
to Michal Wallace, Luke Palmer, perl6-i...@perl.org
At 10:12 AM -0500 2/15/04, Michal Wallace wrote:
>On Sun, 15 Feb 2004, Luke Palmer wrote:
> > But I think findmethod is a good idea, cross-language-wise. Each
>> language has a different idea of what a method is, and they can
>> store it that way. As long as findmethod is vtableable, you can
>> hook it up to whatever system your language uses.
>
>I was thinking the same thing as I wrote my post
>last night... But I'm not convinced.
>Suppose I do something like this:
>
> x = parrot.find("perl::whatever")
> x.method()
>
>Is that second line a method call or a function call?

Got me. I can't see any way it wouldn't be a method call, honestly.
It's also very language dependent, being syntax and all--if python
says its a method call, it's a method call. (If x is a bound method
which you have to call first and then call a method on its return
value, well... that makes things a bit more interesting in spots but
not for the compiler)

Snipping the multimethod example, multimethod lookup is done by the
core as part of the provided "find me the method that matches" code.
If you use that code to do the lookup you get MMD. If you don't, you
won't.

>In fact, since I'm on the subject, properties and
>attributes also have this problem.

Properties and attributes have a much bigger problem. Two, actually.
First, they're private and may *not* be exposed, so non-class code
can't ever see them. (Well, OK, shouldn't ever see them without
cheating) Second, as they're class-private, there can (and will) be
duplicate names in there.

While I'd love 'em to be interchangeable, they're not going to be.
Python code won't ever see what we're calling attributes unless it
makes an explicit call to go look. (or Guido alters the syntax, which
is both unlikely and arguably a bad thing, or at least parrot's a bad
reason to do it)

Random code, in most languages (including perl 6 and python) that does:

y = foo.bar

will either get the bar property or the result of bar method, but
never (any of) the bar attributes. (And yes, before someone else
jumps in, languages can mark attributes public, but that means the
language compiler generates an lvalue method, reducing the problem to
a previous one :)

Togos

unread,
Feb 16, 2004, 8:06:39 PM2/16/04
to perl6-i...@perl.org
Dunno why it is, but I tried to post a message about
30 hours ago and nothing ever showed up in the NNTP
archive. So I re-subscribed again figuring that'd
speed things up. You should see my perl box:

...
WELCOME to perl6-i...@perl.org
confirm subscribe to perl6-i...@perl.org
GOODBYE from perl6-i...@perl.org
confirm unsubscribe from perl6-i...@perl.org
WELCOME to perl6-i...@perl.org
confirm subscribe to perl6-i...@perl.org
...

*ANYWAY*

Sorry if I get some of the details wrong or talk about
something that's already been covered. I haven't quite
kept up with the mailing list recently.

As I see it, there are 2 basic ways you can handle the
methodcall/property issue:

Way 1:

HL code -> pseudo-parrot code

python:
v = x.y -> c = getprop(x, "y")
(v now contains a bound method)
v() -> call( v )
x.y() -> callmeth( x, "y" )

ruby:
x.y -> getprop(x, "y")
x.y() -> callmeth(x, "y")

It is then up to the object to decide whether
getprop should return a bound method or the result
of calling the named method.

Way 2:

same as way 1 except for

ruby:
x.y -> callmeth(x, "y")

As this would result the behavior a ruby programmer
would tend to expect if x was a python object and y
was an accessor method. Still, it should be up to the
object to decide what getprop should do, but if more
languages went this route, it would be more common for
getprop to return bound methods instead of the result
of calling the method, as languages that don't expect
to ever get a method by saying "x.y" would always call
a method and never deal with properties.

Way 1 seems cleaner on a low level. OTOH, it could
cause problems when calling accessor methods on a
python object from ruby. But I think in this case it
is the responsibility of the python programmer to name
accessor methods as 'get_color()' as opposed to just
'color()', which looks to the programmer like a
property rather than a method.

__________________________________
Do you Yahoo!?
Yahoo! Finance: Get your refund fast by filing online.
http://taxes.yahoo.com/filing.html

0 new messages