Re: Method Resolution Order question

2005-07-14 Thread Stevan Little

Larry,

Thanks much, this all makes sense. :)

Thanks,

Stevan

On Jul 14, 2005, at 4:54 PM, Larry Wall wrote:


On Thu, Jul 14, 2005 at 04:31:07PM -0400, Stevan Little wrote:
: Now, the metamodel currently does not have MMD, and  I think "next
: METHOD" is not as relevant in SMD. So would it make sense to do:
:
:   next SUPER if $?SELF != $?CLASS;
:
: or something like that?

It comes out to that under single inheritance, but under MI it might
well be that the next method that ought to be called is actually a
sibling method.


This is just to clarify for me (and anyone else paying attention), 
because this made more sense when I "saw" it.


class Foo {
method baz { ... }
}

class Bar {
submethod baz { ... }
}

class FooBar is Foo is Bar {}

my $foo_bar = FooBar.new();
$foo_bar.baz() # calls Foo::baz()

No need to respond unless I got it wrong :)



: Here is some example code which might encounter this:
:
: class Foo {
:   method baz { ... }
: } 
:
: class Bar is Foo {
:   submethod baz { ... }
: }
:
: class FooBar is Bar {}
:
: my $foo_bar = FooBar.new();
: $foo_bar.baz() # calls Foo::baz()
:
: basically the dispatch goes from  Bar::baz, which says "next SUPER" 
and

: the dispatcher then goes to Foo::baz since it is a method.
:
: Is that correct?

It says "next METHOD", which has the same effect under SI.  But we 
don't

know whether we're under MI, and we don't know if the dispatcher we're
working under has some weird order of visitation, so it's clearer to
say "next METHOD" and leave it up to the dispatcher to decide if the
SUPER is the next method.  It *usually* is, but...

: You refer to CREATE and BUILDALL as methods here, but A12 calls them
: submethods. Which is correct?

The default versions are methods so that they can be inherited.  The
individual versions defined by classes are submethods unless they 
intend
to be inherited, and force all their subclasses into a new set of 
default
sematics.  And they're always called as methods (except when things 
like

.* cheat).

: >I believe there's pseudo-code for that in A12.  The trick is that 
you
: >can always force a call to a submethod of the "wrong" class by 
taking

: >it as a sub reference and calling it like an ordinary subroutine.
:
: Okay, this is just as dirty a trick as sneaking up into the 
metamodel,
: so I will leave it that way for now, knowing I need to change it 
later

: :)

Of course, the metamodel can do whatever dirty tricks it likes,
but in Perl 6 the metamodel might actually implement this particular
operation by forcing a sub call through a reference, if the metamodel
is implemented in Perl 6.  It's the only way we've defined to
defeat the .foo dispatcher so far, from a language point of view.
(Though simply calling .meta could also be construed as cheating,
I guess.  Or at least an authorization of cheating on your behalf.)

Larry





Re: Method Resolution Order question

2005-07-14 Thread Larry Wall
On Thu, Jul 14, 2005 at 04:31:07PM -0400, Stevan Little wrote:
: > A submethod is simply a method that says "These
: >aren't the droids you're looking for" if you call it via either SMD
: >or MMD dispatch and the first invocant isn't of the exact run-time
: >type of the lexical class.  In other words, it just has an implicit
: >
: >next METHOD if $?SELF != $?CLASS;
: >
: >at the front.  So the dispatch continues until it finds either a 
: >submethod
: >that does have an exact match or a method that isn't a submethod.
: 
: Now, the metamodel currently does not have MMD, and  I think "next 
: METHOD" is not as relevant in SMD. So would it make sense to do:
: 
:   next SUPER if $?SELF != $?CLASS;
: 
: or something like that?

It comes out to that under single inheritance, but under MI it might
well be that the next method that ought to be called is actually a
sibling method.

: Here is some example code which might encounter this:
: 
: class Foo {
:   method baz { ... }
: } 
: 
: class Bar is Foo {
:   submethod baz { ... }
: }
: 
: class FooBar is Bar {}
: 
: my $foo_bar = FooBar.new();
: $foo_bar.baz() # calls Foo::baz()
: 
: basically the dispatch goes from  Bar::baz, which says "next SUPER" and 
: the dispatcher then goes to Foo::baz since it is a method.
: 
: Is that correct?

It says "next METHOD", which has the same effect under SI.  But we don't
know whether we're under MI, and we don't know if the dispatcher we're
working under has some weird order of visitation, so it's clearer to
say "next METHOD" and leave it up to the dispatcher to decide if the
SUPER is the next method.  It *usually* is, but...

: You refer to CREATE and BUILDALL as methods here, but A12 calls them 
: submethods. Which is correct?

The default versions are methods so that they can be inherited.  The
individual versions defined by classes are submethods unless they intend
to be inherited, and force all their subclasses into a new set of default
sematics.  And they're always called as methods (except when things like
.* cheat).

: >I believe there's pseudo-code for that in A12.  The trick is that you
: >can always force a call to a submethod of the "wrong" class by taking
: >it as a sub reference and calling it like an ordinary subroutine.
: 
: Okay, this is just as dirty a trick as sneaking up into the metamodel, 
: so I will leave it that way for now, knowing I need to change it later 
: :)

Of course, the metamodel can do whatever dirty tricks it likes,
but in Perl 6 the metamodel might actually implement this particular
operation by forcing a sub call through a reference, if the metamodel
is implemented in Perl 6.  It's the only way we've defined to
defeat the .foo dispatcher so far, from a language point of view.
(Though simply calling .meta could also be construed as cheating,
I guess.  Or at least an authorization of cheating on your behalf.)

Larry


Re: Method Resolution Order question

2005-07-14 Thread Stevan Little

Larry,

Thanks for the detailed reply. Just a few more questions and I think I 
can get this into the metamodel :)


On Jul 14, 2005, at 3:40 PM, Larry Wall wrote:

On Wed, Jul 13, 2005 at 07:27:52PM -0400, Stevan Little wrote:
: The way I am viewing the notion of "current class" for submethods
: currently is:
:
: From inside another method or submethod:
:
: - a submethod should only be called from the class which defines it.

This doesn't sound right to me.  There is no distinction between
inside or outside.


Yes, I am not sure what I was thinking there. Shortly after I wrote 
this mail I did some work on submethods in the metamodel and realized 
how silly that idea is :)


I also realized that a sepereate submethod dispatch table made no sense 
either, so scratch that thought out as well.



 A submethod is simply a method that says "These
aren't the droids you're looking for" if you call it via either SMD
or MMD dispatch and the first invocant isn't of the exact run-time
type of the lexical class.  In other words, it just has an implicit

next METHOD if $?SELF != $?CLASS;

at the front.  So the dispatch continues until it finds either a 
submethod

that does have an exact match or a method that isn't a submethod.


Now, the metamodel currently does not have MMD, and  I think "next 
METHOD" is not as relevant in SMD. So would it make sense to do:


next SUPER if $?SELF != $?CLASS;

or something like that? Here is some example code which might encounter 
this:


class Foo {
method baz { ... }
}   

class Bar is Foo {
submethod baz { ... }
}

class FooBar is Bar {}

my $foo_bar = FooBar.new();
$foo_bar.baz() # calls Foo::baz()

basically the dispatch goes from  Bar::baz, which says "next SUPER" and 
the dispatcher then goes to Foo::baz since it is a method.


Is that correct?


: This means that since Object::bless() calls Object::BUILDALL() it is
: all well and good, assuming you have not overridden bless() in your
: class, and are calling it $class.bless().

No, Object::bless() (which perhaps delegates to Class.meta.bless so
that different meta classes can have different .bless primitives)


Okay, this makes sense.


calls MyClass.CREATE to create the type, while will be an opaque type
if that normal method dispatch runs up the tree to Object::CREATE.
(But user classes are allowed to define their own CREATE method to
create non-opaque objects.)

After the storage is allocated, .meta.bless then calls $newobj.BUILDALL
as an ordinary method call on the instance.  Again this is overridable
by each class, but typically goes back to Object::BUILDALL (which, as
usual, probably delegates at least some of the work to the meta class).


You refer to CREATE and BUILDALL as methods here, but A12 calls them 
submethods. Which is correct?



: (Object::BUILDALL of course then digs into the metaclass to call
: BUILD() for all the superclasses in post-order. I am not sure how to 
do

: that otherwise, submethod or not.)

I believe there's pseudo-code for that in A12.  The trick is that you
can always force a call to a submethod of the "wrong" class by taking
it as a sub reference and calling it like an ordinary subroutine.


Okay, this is just as dirty a trick as sneaking up into the metamodel, 
so I will leave it that way for now, knowing I need to change it later 
:)




: However, if you define MyClass::bless, then you will need to define
: MyClass::BUILDALL as well.

We did not intend that people redefined .bless.  It's really intended 
to be
a primitive like .meta.  The occasional redefinables are CREATE and 
BUILDALL,

but it's really only intended that BUILD be defined typically.


Agreed, .bless should probably never be redefined, I will pull that up 
into the MetaClass.





: > There's some kind of "yes I mean
: >you" notion in the dispatcher.  It comes out in user-visible terms
: >in .*foo calls but not ordinary .foo calls,
:
: I am not familiar with .*foo calls? Can you elaborate?

This is all pretty much straight from A12.


I see now, I forgot about those :)


: > which call a submethod
: >only when the object is actually that type, and otherwise look for 
an

: >ancestral method of that name.
:
: Yes, to expand upon my above statements. The method resolution would
: begin looking in the local submethod table, then move onto the local
: method table, and then on up the superclass hierarchy. Is that 
correct?


There is no separate submethod table.  From the standpoint of ordinary
.foo method resolution they're ordinary methods that happen to say
"next METHOD" as a form of failure.


Yup, realized that as soon as I tried to implement it :)

Thanks,

Stevan



Re: Method Resolution Order question

2005-07-14 Thread Larry Wall
On Wed, Jul 13, 2005 at 07:27:52PM -0400, Stevan Little wrote:
: The way I am viewing the notion of "current class" for submethods 
: currently is:
: 
: From inside another method or submethod:
: 
: - a submethod should only be called from the class which defines it.

This doesn't sound right to me.  There is no distinction between
inside or outside.  A submethod is simply a method that says "These
aren't the droids you're looking for" if you call it via either SMD
or MMD dispatch and the first invocant isn't of the exact run-time
type of the lexical class.  In other words, it just has an implicit

next METHOD if $?SELF != $?CLASS;

at the front.  So the dispatch continues until it finds either a submethod
that does have an exact match or a method that isn't a submethod.

: This means that since Object::bless() calls Object::BUILDALL() it is 
: all well and good, assuming you have not overridden bless() in your 
: class, and are calling it $class.bless().

No, Object::bless() (which perhaps delegates to Class.meta.bless so
that different meta classes can have different .bless primitives)
calls MyClass.CREATE to create the type, while will be an opaque type
if that normal method dispatch runs up the tree to Object::CREATE.
(But user classes are allowed to define their own CREATE method to
create non-opaque objects.)

After the storage is allocated, .meta.bless then calls $newobj.BUILDALL
as an ordinary method call on the instance.  Again this is overridable
by each class, but typically goes back to Object::BUILDALL (which, as
usual, probably delegates at least some of the work to the meta class).

: (Object::BUILDALL of course then digs into the metaclass to call 
: BUILD() for all the superclasses in post-order. I am not sure how to do 
: that otherwise, submethod or not.)

I believe there's pseudo-code for that in A12.  The trick is that you
can always force a call to a submethod of the "wrong" class by taking
it as a sub reference and calling it like an ordinary subroutine.

: However, if you define MyClass::bless, then you will need to define 
: MyClass::BUILDALL as well.

We did not intend that people redefined .bless.  It's really intended to be
a primitive like .meta.  The occasional redefinables are CREATE and BUILDALL,
but it's really only intended that BUILD be defined typically.

: Or is it possible just do $self.Object::BUILDALL()? So can I call a 
: submethod from a different class if I fully qualify it?

No, that would just fail.  You have to do the reference casting trick
to call it as an ordinary subroutine.  We made that hard on purpose.

: From outside a method (in "user" space):
: 
: - the invocant of the submethod must be a direct instance of the class 
: in which the submethod is defined. No inheritance involved.
: 
: Maybe this is too strict, though? What do you think?

There is no "user" space distinction.  You still just call a method
with the ordinary dispatcher, and it still just runs down the list of
dispatcher class candidates till it either finds one that's a method
or finds one that is a submethod and whose class matches the object's.
Of course, that's highly unlikely to match a submethod on anything
but the first probe, given the usual visitation order of the standard
dispatcher and the fact that virtual method calls always start with
the actual run-tiem type of the object, but MMD might have a different
idea about order, and the same principle still applies.  Plus other
dispatchers are possible.

The point of a submethod is that it doesn't make sense to call it on
anything other than an actual object of this type (where initialization
and finalization are examples of where we basically lie about the
actual type because we want the various bit of the current object
treated as if they were really an ancestral class even though they
aren't really).  Since that's the point of a submethod, the proper
place to put the constraint is on the front of the submethod itself,
and let it just fail to be dispatched to if it doesn't want to be
dispatched to.  In general, unless you are a funny dispatcher like
.*foo, you shouldn't be thinking about "how you call them".

: > There's some kind of "yes I mean
: >you" notion in the dispatcher.  It comes out in user-visible terms
: >in .*foo calls but not ordinary .foo calls,
: 
: I am not familiar with .*foo calls? Can you elaborate?

This is all pretty much straight from A12.

: > which call a submethod
: >only when the object is actually that type, and otherwise look for an
: >ancestral method of that name.
: 
: Yes, to expand upon my above statements. The method resolution would 
: begin looking in the local submethod table, then move onto the local 
: method table, and then on up the superclass hierarchy. Is that correct?

There is no separate submethod table.  From the standpoint of ordinary
.foo method resolution they're ordinary methods that happen to say
"next METHOD" as a form of failure.  The dispatcher doesn't even have
to know the

Re: Method Resolution Order question

2005-07-13 Thread Stevan Little

Larry,

On Jul 13, 2005, at 2:30 PM, Larry Wall wrote:

: The Syn/Apoc seem to indicate that methods and submethods of the same
: name can coexist. So the class definition itself is legal. However, 
it

: brings up an issue when it comes time to call bar().

If the Syn/Apoc is giving that impression, it's giving the wrong 
impression.

Subs, methods, and anything in between all live in the same namespace.
The class above is illegal because you're trying to give two things
the name &bar in the absence of a "multi".


Horray


: Can submethods only be called from within the class (like private
: methods)?

No, they can be called from anywhere.  They're just constrained to
work only when a dispatcher's idea of "current class" matches the
actual class, where "current class" usually means the actual class
of the object in question, but can also mean an ancestral class when
we're doing BUILDALL, for instance.


The way I am viewing the notion of "current class" for submethods 
currently is:


From inside another method or submethod:

- a submethod should only be called from the class which defines it.

This means that since Object::bless() calls Object::BUILDALL() it is 
all well and good, assuming you have not overridden bless() in your 
class, and are calling it $class.bless().


(Object::BUILDALL of course then digs into the metaclass to call 
BUILD() for all the superclasses in post-order. I am not sure how to do 
that otherwise, submethod or not.)


However, if you define MyClass::bless, then you will need to define 
MyClass::BUILDALL as well.


Or is it possible just do $self.Object::BUILDALL()? So can I call a 
submethod from a different class if I fully qualify it?


From outside a method (in "user" space):

- the invocant of the submethod must be a direct instance of the class 
in which the submethod is defined. No inheritance involved.


Maybe this is too strict, though? What do you think?


 There's some kind of "yes I mean
you" notion in the dispatcher.  It comes out in user-visible terms
in .*foo calls but not ordinary .foo calls,


I am not familiar with .*foo calls? Can you elaborate?


 which call a submethod
only when the object is actually that type, and otherwise look for an
ancestral method of that name.


Yes, to expand upon my above statements. The method resolution would 
begin looking in the local submethod table, then move onto the local 
method table, and then on up the superclass hierarchy. Is that correct?


Thanks,

Stevan




Re: Method Resolution Order question

2005-07-13 Thread Larry Wall
On Wed, Jul 13, 2005 at 12:51:49PM -0400, Stevan Little wrote:
: Hello,
: 
: More questions for the metamodel. I am trying to add proper submethod 
: and private method handling and I have a question about method 
: resolution order as a whole. I asked a similar question last week, but 
: this time I have more details :)
: 
: Given this class:
: 
: class Foo {
:   submethod bar { ... }
:   method bar { ... }
: }
: 
: and given this code:
: 
: Foo.new().bar()
: 
: What should happen?
: 
: The Syn/Apoc seem to indicate that methods and submethods of the same 
: name can coexist. So the class definition itself is legal. However, it 
: brings up an issue when it comes time to call bar().

If the Syn/Apoc is giving that impression, it's giving the wrong impression.
Subs, methods, and anything in between all live in the same namespace.
The class above is illegal because you're trying to give two things
the name &bar in the absence of a "multi".

: Should submethod bar() be called first, then method bar() after it?
: Should method bar() be called first, then submethod bar() after it?

Question doesn't arise.

: Can submethods only be called from within the class (like private 
: methods)?

No, they can be called from anywhere.  They're just constrained to
work only when a dispatcher's idea of "current class" matches the
actual class, where "current class" usually means the actual class
of the object in question, but can also mean an ancestral class when
we're doing BUILDALL, for instance.  There's some kind of "yes I mean
you" notion in the dispatcher.  It comes out in user-visible terms
in .*foo calls but not ordinary .foo calls, which call a submethod
only when the object is actually that type, and otherwise look for an
ancestral method of that name.

: And if submethods can only be called from within the class, then how do 
: I handle this:
: 
: class Foo {
:   submethod bar { ... }
:   method bar { ... }
:   method baz {
:   $?SELF.bar()
:   }
: }
: 
: Foo.new().baz()

Again, illegal class.

: Thanks,
: 
: Stevan
: 


Method Resolution Order question

2005-07-13 Thread Stevan Little

Hello,

More questions for the metamodel. I am trying to add proper submethod 
and private method handling and I have a question about method 
resolution order as a whole. I asked a similar question last week, but 
this time I have more details :)


Given this class:

class Foo {
submethod bar { ... }
method bar { ... }
}

and given this code:

Foo.new().bar()

What should happen?

The Syn/Apoc seem to indicate that methods and submethods of the same 
name can coexist. So the class definition itself is legal. However, it 
brings up an issue when it comes time to call bar().


Should submethod bar() be called first, then method bar() after it?
Should method bar() be called first, then submethod bar() after it?

Can submethods only be called from within the class (like private 
methods)?


And if submethods can only be called from within the class, then how do 
I handle this:


class Foo {
submethod bar { ... }
method bar { ... }
method baz {
$?SELF.bar()
}
}

Foo.new().baz()

Thanks,

Stevan