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

Objects and classes, try 3

7 views
Skip to first unread message

Dan Sugalski

unread,
Mar 9, 2003, 1:07:46 PM3/9/03
to perl6-i...@perl.org
Okay, here's try three. I think I'm about ready to POD this up as a
formal spec to be assaulted, but this version is more a sketch than
anything:

Objects
=======

* Objects have properties you can fetch and store by name
* Objects have methods you can call
* Objects have attributes you can fetch
* You can fetch a hash of all the properties
* When fetching or storing a generic property, you may call a method
instead, as methods win
* You can fetch a method PMC from the object
* You can fetch the object's Class PMC

All of these have vtable entries in the PMC: get_prop, set_prop,
get_attrib, set_attrib, get_prop_hash, get_method, call_method,
get_class. (Some already have names, I'm doing this from memory)

No, you can't set a method or the property hash from an object PMC.
Arguments with good reasons to do so will be cheerfully read and not
implemented. :)

PMCs are responsible for making sure the get/set property stuff calls
methods if that should happen per the PMC's owning language spec.

If the property hash should call methods when things are fetched from
it (because there are override fetch methods or something) then the
PMC is responsible for returning a hash PMC with appropriate active
get/set methods attached to it.

Objects may actually be composite objects, if we're doing inheritance
via delegation, for when we inherit from a class of a different type.
In that case the delegated object has a property on it that refers to
the 'master' object that represents the ultimate child class' object.
This is done with a "PARENT" property on the

Note that objects do *not* have to have classes. Variables don't even
have to *be* objects, as such--plain integers can implement all this
stuff if they want. We're OO-fuzzy here.

Classes
=======

Classes are indirectly responsible for how objects behave, as the
class constructs the initial vtable that gets assigned to each
object. (Well, the PMC class, and language level classes will all
have a custom generated PMC class for them) The only thing actually
semi-required of classes is a set of metadata. It's semi-required in
that any class that uses the metadata *must* use it in the way we
prescribe. Anyone's free to do things differently, in which case it's
just a matter of implementing the right vtable code and suchlike
things. Doable, if not actually simple.

Parrot's base class mechanism support multiple inheritance, delegated
inheritance, and inherited interfaces. They correspond, more or less,
to "is", "has" and "does", and that's what we're going to refer to
them as. We are class-based, since that's what perl 6, python, and
ruby all do. Some of the other object systems are interesting, but
we're not going to bother with them here. Not our focus.

Each class is represented by a PMC with an "is", and "does" property,
which are arrays of parent classes and parent interfaces,
respectively. The default method dispatch vtable function should
respect both the is and does list--personally I'm thinking we should
pre-populate the method table for a class since we're going to do
notifications, but we can defer that until later.

Each class has the following semi-required properties (The names aren't fixed):

* does - Array of immediate parent interfaces
* is - Array of immediate parent classes
* needs - A count of the attributes for this class (class only, not
parent classes)
* attributes - an array of attribute names for this class (not parent
classes, just this class)
* object_style - What type of object this is. 0 = no object, 1 =
parrot base object, 2 = delegated object
* core_functions - An array of the core functions for the class.
We'll get to those in a moment.

Core Functions
==============

These are in the core_functions property array, and are considered
part of the base parrot class/object mechanism. They're here since we
may need to do something fancier than a plain
most-derived-class-method call.

* allocate - Called when we need to create a new object. Must return a PMC
* initialize - Called when we need to initialize the object that
allocate returned

Destruction is part of the vtable, so classes should just fill that
in in their initialization code.

Method Dispatch
===============

The engine will have a function to determine the "closest" method or
sub in a tree, given a signature. We walk the tree of classes based
on the metainformation and do our best to find the right method. (No,
we've not talked about method metadata. Assume we have some)

The base method dispatch looks for actual sub/methods, then AUTOLOAD,
then multimethod dispatch. We do *not* do AUTOLOAD for more 'special'
methods (no AUTOLOADed DESTROY methods, for example) so if a language
requires them it should instantiate an empty method (one with a
signature but no code) as when we call those we do invoke the class'
autoloading mechanism to find the body.
--
Dan

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

Uri Guttman

unread,
Mar 9, 2003, 1:52:12 PM3/9/03
to Dan Sugalski, perl6-i...@perl.org
>>>>> "DS" == Dan Sugalski <d...@sidhe.org> writes:


DS> * Objects have properties you can fetch and store by name
DS> * Objects have methods you can call
DS> * Objects have attributes you can fetch

and store

DS> * You can fetch a hash of all the properties
DS> * When fetching or storing a generic property, you may call a method
DS> instead, as methods win

what about methods overriding attributes? or are attribute accessors
just methods?


DS> Objects may actually be composite objects, if we're doing inheritance
DS> via delegation, for when we inherit from a class of a different type. In
DS> that case the delegated object has a property on it that refers to the
DS> 'master' object that represents the ultimate child class' object. This
DS> is done with a "PARENT" property on the

on the what?

it would be helpful to clarify which direction you mean with
parent/child with regard to delegation. i take it the parent object gets
the original method call and it delegates it to the child object that
the parent owns. i use 'own' (others say 'has') for the delegation
relationship and i mean the parent owns the child which will get the
delegated call. note that a parent could own multiple children of the
same name and delegate different parent methods to different
children. 'has' doesn't cover that case as well as own. minor semantic
difference but worth mentioning.

DS> Each class is represented by a PMC with an "is", and "does" property,
DS> which are arrays of parent classes and parent interfaces,
DS> respectively. The default method dispatch vtable function should respect
DS> both the is and does list--personally I'm thinking we should
DS> pre-populate the method table for a class since we're going to do
DS> notifications, but we can defer that until later.

what about 'has'?

uri

--
Uri Guttman ------ u...@stemsystems.com -------- http://www.stemsystems.com
----- Stem and Perl Development, Systems Architecture, Design and Coding ----
Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
Damian Conway Perl Classes - January 2003 -- http://www.stemsystems.com/class

Piers Cawley

unread,
Mar 9, 2003, 1:53:57 PM3/9/03
to Dan Sugalski, perl6-i...@perl.org
Dan Sugalski <d...@sidhe.org> writes:

> Okay, here's try three. I think I'm about ready to POD this up as a
> formal spec to be assaulted, but this version is more a sketch than
> anything:

[...]

Am I reading it right if I reckon that a Class isa Object? and an
Object hasa Class (assuming that the object is, um, Classy)?

--
Piers

Dan Sugalski

unread,
Mar 9, 2003, 2:02:17 PM3/9/03
to Piers Cawley, perl6-i...@perl.org

Pretty much, yeah. I'm not sure if Classes will be objects as such,
rather than just another Special PMC Thing (like scalars, hashes,
arrays) but they'll be pretty darned close to objects if they aren't.

Dan Sugalski

unread,
Mar 9, 2003, 2:08:02 PM3/9/03
to Uri Guttman, perl6-i...@perl.org
At 1:52 PM -0500 3/9/03, Uri Guttman wrote:
> >>>>> "DS" == Dan Sugalski <d...@sidhe.org> writes:
>
>
> DS> * Objects have properties you can fetch and store by name
> DS> * Objects have methods you can call
> DS> * Objects have attributes you can fetch
>
>and store

Well... I'm not sure about that. Classes can store data in object
attributes, but there isn't necessarily a public API through the PMC
to do this. Basically if you can get to it through a PMC's vtable, it
was on the "Objects have" list. I'm not sure that storing into an
attribute should be easily doable from the outside.

Methods have access to an object's internal bits, so the class
methods can poke into slots in the attribute array directly, which is
probably how they'll work.

> DS> * You can fetch a hash of all the properties
> DS> * When fetching or storing a generic property, you may call a method
> DS> instead, as methods win
>
>what about methods overriding attributes? or are attribute accessors
>just methods?

Attribute accessors are methods. If an object wants accessors, it
exports lvalue methods (potentially--they don't strictly have to be
lvalue if it's read-only) for them.

> DS> Objects may actually be composite objects, if we're doing inheritance
> DS> via delegation, for when we inherit from a class of a different type. In
> DS> that case the delegated object has a property on it that refers to the
> DS> 'master' object that represents the ultimate child class' object. This
> DS> is done with a "PARENT" property on the
>
>on the what?

The delegated object. D'oh!

So if class A isa B, and B is a perl 5 hash-object-thingie, the
object that B creates would have the "PARENT" property stuck on it,
pointing ot the A object. That way B can make method calls on its
object the right way. (If B couldn't get back to the containing
object transparently we'd trim off a lot of the inheritance tree and
we don't want that)

>it would be helpful to clarify which direction you mean with
>parent/child with regard to delegation. i take it the parent object gets
>the original method call and it delegates it to the child object that
>the parent owns. i use 'own' (others say 'has') for the delegation
>relationship and i mean the parent owns the child which will get the
>delegated call. note that a parent could own multiple children of the
>same name and delegate different parent methods to different
>children. 'has' doesn't cover that case as well as own. minor semantic
>difference but worth mentioning.

Sorry. Parent == derived class, child == parent class. Bad choice of
words on my part.

> DS> Each class is represented by a PMC with an "is", and "does" property,
> DS> which are arrays of parent classes and parent interfaces,
> DS> respectively. The default method dispatch vtable function should respect
> DS> both the is and does list--personally I'm thinking we should
> DS> pre-populate the method table for a class since we're going to do
> DS> notifications, but we can defer that until later.
>
>what about 'has'?

Don't need it. The object the class 'has' is stored in an attribute
slot, and the class is in the "is" array, since it really 'is' that
foreign class, albeit with some magic to make it work. (The parent
property and such)

Uri Guttman

unread,
Mar 9, 2003, 2:33:50 PM3/9/03
to Dan Sugalski, perl6-i...@perl.org
>>>>> "DS" == Dan Sugalski <d...@sidhe.org> writes:

DS> At 1:52 PM -0500 3/9/03, Uri Guttman wrote:

DS> is done with a "PARENT" property on the
>>
>> on the what?

DS> The delegated object. D'oh!

DS> So if class A isa B, and B is a perl 5 hash-object-thingie, the object
DS> that B creates would have the "PARENT" property stuck on it, pointing ot
DS> the A object. That way B can make method calls on its object the right
DS> way. (If B couldn't get back to the containing object transparently we'd
DS> trim off a lot of the inheritance tree and we don't want that)

so any class X that inherits from B must also modify the PARENT property
in B? that sounds like PARENT is a hash of the classes which inherit
from B.

<i hate all the variant OO names, parent/super/etc. so damned
confusing. maybe we should have a special parrot OO section in the
glossary>

>> it would be helpful to clarify which direction you mean with
>> parent/child with regard to delegation. i take it the parent object gets
>> the original method call and it delegates it to the child object that
>> the parent owns. i use 'own' (others say 'has') for the delegation
>> relationship and i mean the parent owns the child which will get the
>> delegated call. note that a parent could own multiple children of the
>> same name and delegate different parent methods to different
>> children. 'has' doesn't cover that case as well as own. minor semantic
>> difference but worth mentioning.

DS> Sorry. Parent == derived class, child == parent class. Bad choice of
DS> words on my part.

so please resend that out soon (try 4) with the edits.

<ditto on the glossary note :)>

DS> Each class is represented by a PMC with an "is", and "does" property,
DS> which are arrays of parent classes and parent interfaces,
DS> respectively. The default method dispatch vtable function should respect
DS> both the is and does list--personally I'm thinking we should
DS> pre-populate the method table for a class since we're going to do
DS> notifications, but we can defer that until later.
>>
>> what about 'has'?

DS> Don't need it. The object the class 'has' is stored in an attribute
DS> slot, and the class is in the "is" array, since it really 'is' that
DS> foreign class, albeit with some magic to make it work. (The parent
DS> property and such)

how does that handle which methods in the 'owner' object get
mapped/delegated to which methods in the 'owned' object? damian's
delegate module has a map for that with owner method names mapping to
attribute (owned object)/method pairs. not all methods of an owned
object need to be accessible via the owner's interface. also how do you
handle multiple owned objects and method mapping?

i happen to like owned/has more than most and use it quite a bit more
than ISA these days. i would like to see a clean mapping spec like the
delegate module has.

Dan Sugalski

unread,
Mar 9, 2003, 2:54:16 PM3/9/03
to Uri Guttman, perl6-i...@perl.org
At 2:33 PM -0500 3/9/03, Uri Guttman wrote:
> >>>>> "DS" == Dan Sugalski <d...@sidhe.org> writes:
>
> DS> At 1:52 PM -0500 3/9/03, Uri Guttman wrote:
>
> DS> is done with a "PARENT" property on the
> >>
> >> on the what?
>
> DS> The delegated object. D'oh!
>
> DS> So if class A isa B, and B is a perl 5 hash-object-thingie, the object
> DS> that B creates would have the "PARENT" property stuck on it, pointing ot
> DS> the A object. That way B can make method calls on its object the right
> DS> way. (If B couldn't get back to the containing object transparently we'd
> DS> trim off a lot of the inheritance tree and we don't want that)
>
>so any class X that inherits from B must also modify the PARENT property
>in B? that sounds like PARENT is a hash of the classes which inherit
>from B.

Yep. Basically if the inheriting class is of a different type, such
that the parent class must be inherited with delegation, then when
the parent object is instantiated it gets the PARENT property on it.
Messy in some ways, but I don't see any way around it.

><i hate all the variant OO names, parent/super/etc. so damned
>confusing. maybe we should have a special parrot OO section in the
>glossary>

Works for me.

Ah, this isn't for the Damian "We do Interesting Things with
delegation" stuff. This mechanism is in specifically to handle
inheriting from an incompatible parent class. Stuff like Damian wants
can be handled completely in user-code, so it should be.

At some point someone will come up with a clever general way to
handle this, in which case we'll look into rolling it into the base
object system, but for now, in the interests of what simplicity we
can muster, we're going to duck the issue.

Piers Cawley

unread,
Mar 9, 2003, 3:01:16 PM3/9/03
to Dan Sugalski, perl6-i...@perl.org
Dan Sugalski <d...@sidhe.org> writes:

> At 6:53 PM +0000 3/9/03, Piers Cawley wrote:
>>Dan Sugalski <d...@sidhe.org> writes:
>>
>>> Okay, here's try three. I think I'm about ready to POD this up as a
>>> formal spec to be assaulted, but this version is more a sketch than
>>> anything:
>>
>>[...]
>>
>>Am I reading it right if I reckon that a Class isa Object? and an
>>Object hasa Class (assuming that the object is, um, Classy)?
>
> Pretty much, yeah. I'm not sure if Classes will be objects as such,
> rather than just another Special PMC Thing (like scalars, hashes,
> arrays) but they'll be pretty darned close to objects if they aren't.

For various, nefarious reasons I'd like to be able to manipulate
classes as objects at a language level, even if they aren't objects
down at the Parrot level, but I'll wait for Apo 12 for that one.

--
Piers

Uri Guttman

unread,
Mar 9, 2003, 3:05:12 PM3/9/03
to Dan Sugalski, perl6-i...@perl.org
>>>>> "DS" == Dan Sugalski <d...@sidhe.org> writes:

>> so any class X that inherits from B must also modify the PARENT property
>> in B? that sounds like PARENT is a hash of the classes which inherit
>> from B.

DS> Yep. Basically if the inheriting class is of a different type, such that
DS> the parent class must be inherited with delegation, then when the parent
DS> object is instantiated it gets the PARENT property on it. Messy in some
DS> ways, but I don't see any way around it.

the use of 'inherit' with delegation bothers me. that assumes (some of)
the method names in the owned object are the same in the owner (parent)
object.

>> how does that handle which methods in the 'owner' object get
>> mapped/delegated to which methods in the 'owned' object? damian's
>> delegate module has a map for that with owner method names mapping to
>> attribute (owned object)/method pairs. not all methods of an owned
>> object need to be accessible via the owner's interface. also how do you
>> handle multiple owned objects and method mapping?

DS> Ah, this isn't for the Damian "We do Interesting Things with delegation"
DS> stuff. This mechanism is in specifically to handle inheriting from an
DS> incompatible parent class. Stuff like Damian wants can be handled
DS> completely in user-code, so it should be.

i assume by user code you mean perl6 itself? that can be done just
before method lookup is called but the mapping hash still has to be in
the object/class and private to that. can that be handled at the perl6
level without parrot support?

DS> At some point someone will come up with a clever general way to handle
DS> this, in which case we'll look into rolling it into the base object
DS> system, but for now, in the interests of what simplicity we can muster,
DS> we're going to duck the issue.

it doesn't seem to be too hard. all that is needed is a OWNED/DELEGATED
hash with the method/delegated mappings provided by perl6. then that map
(if it exists) is checked before any other method lookups are done. this
is all i see that is needed to support proper delegation and it is
pretty much what damian's module does now. it can be added later if it
simplifies things now but it doesn't seem that complex or tricky.

Dan Sugalski

unread,
Mar 9, 2003, 3:11:00 PM3/9/03
to Piers Cawley, perl6-i...@perl.org

I think Larry's planning on that, which is fine, and I'd as soon
allow it in at least some form, because it seems really useful, if a
bit evil.

Dan Sugalski

unread,
Mar 9, 2003, 3:22:55 PM3/9/03
to Uri Guttman, perl6-i...@perl.org
At 3:05 PM -0500 3/9/03, Uri Guttman wrote:
> >>>>> "DS" == Dan Sugalski <d...@sidhe.org> writes:
>
> >> so any class X that inherits from B must also modify the PARENT property
> >> in B? that sounds like PARENT is a hash of the classes which inherit
> >> from B.
>
> DS> Yep. Basically if the inheriting class is of a different type, such that
> DS> the parent class must be inherited with delegation, then when the parent
> DS> object is instantiated it gets the PARENT property on it. Messy in some
> DS> ways, but I don't see any way around it.
>
>the use of 'inherit' with delegation bothers me. that assumes (some of)
>the method names in the owned object are the same in the owner (parent)
>object.

Yup. What I'm talking about here is delegation to implement
inheritance, in those cases where the parent and child classes are
structurally incompatible.

> >> how does that handle which methods in the 'owner' object get
> >> mapped/delegated to which methods in the 'owned' object? damian's
> >> delegate module has a map for that with owner method names mapping to
> >> attribute (owned object)/method pairs. not all methods of an owned
> >> object need to be accessible via the owner's interface. also how do you
> >> handle multiple owned objects and method mapping?
>
> DS> Ah, this isn't for the Damian "We do Interesting Things with delegation"
> DS> stuff. This mechanism is in specifically to handle inheriting from an
> DS> incompatible parent class. Stuff like Damian wants can be handled
> DS> completely in user-code, so it should be.
>
>i assume by user code you mean perl6 itself?

Yep.

>that can be done just
>before method lookup is called but the mapping hash still has to be in
>the object/class and private to that. can that be handled at the perl6
>level without parrot support?

I don't plan on adding any special support for the fancy delegation
tricks Damian plays. I don't think there's any real need--the
standard AUTILOAD and shim creation tricks he plays to get it working
will work just fine, so there's not much need for anything else.

> DS> At some point someone will come up with a clever general way to handle
> DS> this, in which case we'll look into rolling it into the base object
> DS> system, but for now, in the interests of what simplicity we can muster,
> DS> we're going to duck the issue.
>
>it doesn't seem to be too hard. all that is needed is a OWNED/DELEGATED
>hash with the method/delegated mappings provided by perl6. then that map
>(if it exists) is checked before any other method lookups are done. this
>is all i see that is needed to support proper delegation and it is
>pretty much what damian's module does now. it can be added later if it
>simplifies things now but it doesn't seem that complex or tricky.

I don't think the extra support will be difficult, I just think it's
stuff we don't need to implement to get our required functionality. I
also think it can be done entirely without extra engine support, so
as such I'd as soon not do anything about it for now. We've more than
enough to do as it is. :)

Graham Barr

unread,
Mar 10, 2003, 3:25:12 AM3/10/03
to Dan Sugalski, Uri Guttman, perl6-i...@perl.org
On Sun, Mar 09, 2003 at 02:08:02PM -0500, Dan Sugalski wrote:
> At 1:52 PM -0500 3/9/03, Uri Guttman wrote:
> > >>>>> "DS" == Dan Sugalski <d...@sidhe.org> writes:
> >
> >
> > DS> * Objects have properties you can fetch and store by name
> > DS> * Objects have methods you can call
> > DS> * Objects have attributes you can fetch
> >
> >and store
>
> Well... I'm not sure about that. Classes can store data in object
> attributes, but there isn't necessarily a public API through the PMC
> to do this. Basically if you can get to it through a PMC's vtable, it
> was on the "Objects have" list. I'm not sure that storing into an
> attribute should be easily doable from the outside.
>
> Methods have access to an object's internal bits, so the class
> methods can poke into slots in the attribute array directly, which is
> probably how they'll work.

Surely thats a high-level restriction that Perl will impose. Why should Parrot
impose that restriction ? Other languages may want to access attributes from
outside the class.

Graham.

Dan Sugalski

unread,
Mar 10, 2003, 9:59:37 AM3/10/03
to Graham Barr, Uri Guttman, perl6-i...@perl.org

The big reason to impose it is because if I do, then parrot doesn't
need to expose the details of attributes to user code. That seemed to
make sense at the time, but since we're letting user code fetch
attributes by name or slot number as it is, I'm not sure that one
more vtable entry is a problem.

I'll add in update capabilities to the spec.

Christopher Armstrong

unread,
Mar 10, 2003, 10:22:58 AM3/10/03
to perl6-i...@perl.org
On Sun, Mar 09, 2003 at 01:07:46PM -0500, Dan Sugalski wrote:

> * Objects have properties you can fetch and store by name
> * Objects have methods you can call
> * Objects have attributes you can fetch
> * You can fetch a hash of all the properties
> * When fetching or storing a generic property, you may call a method
> instead, as methods win
> * You can fetch a method PMC from the object
> * You can fetch the object's Class PMC
>
> All of these have vtable entries in the PMC: get_prop, set_prop,
> get_attrib, set_attrib, get_prop_hash, get_method, call_method,
> get_class. (Some already have names, I'm doing this from memory)
>
> No, you can't set a method or the property hash from an object PMC.
> Arguments with good reasons to do so will be cheerfully read and not
> implemented. :)

How about "target languages allow you to do this"? :) (Python!)

But otherwise, I like this spec much more than your previous ones. It
seems more interface-oriented than implementation-oriented. That's
crucial for language compatibility, I think. If you stick to an
interface-oriented approach, then it should be no problem for Python,
Perl, Ruby, etc, to implement all of their wacky object semantics
while preventing incompatibility (or even special inter-language glue
code).

--
Twisted | Christopher Armstrong: International Man of Twistery
Radix | Release Manager, Twisted Project
---------+ http://twistedmatrix.com/users/radix.twistd/

Dan Sugalski

unread,
Mar 10, 2003, 1:31:18 PM3/10/03
to Christopher Armstrong, perl6-i...@perl.org
At 10:22 AM -0500 3/10/03, Christopher Armstrong wrote:
>On Sun, Mar 09, 2003 at 01:07:46PM -0500, Dan Sugalski wrote:
>
>> * Objects have properties you can fetch and store by name
>> * Objects have methods you can call
>> * Objects have attributes you can fetch
>> * You can fetch a hash of all the properties
>> * When fetching or storing a generic property, you may call a method
>> instead, as methods win
>> * You can fetch a method PMC from the object
>> * You can fetch the object's Class PMC
>>
>> All of these have vtable entries in the PMC: get_prop, set_prop,
>> get_attrib, set_attrib, get_prop_hash, get_method, call_method,
>> get_class. (Some already have names, I'm doing this from memory)
>>
>> No, you can't set a method or the property hash from an object PMC.
>> Arguments with good reasons to do so will be cheerfully read and not
>> implemented. :)
>
>How about "target languages allow you to do this"? :) (Python!)

Nope! Python's attributes map to Parrot's properties. I'm going to
add in a translation matrix/glossary to the PDD when I write it, as I
keep getting confused as to who calls which thing what. :)

Still, I've given up on enforcing no-outsite-writing to attributes.
I'm going to add in a set_attrib vtable method, and let
alternate-object systems have at it.

(And you're right, I was getting interface and implementation sloppy
before, which is a mistake I'm trying not to make in the actual spec)

0 new messages