You said in an earlier post that python won't be able to talk to objects with attributes without a syntax change. I don't think a syntax change will be required -- we just need a wrapper class. But it would be *SO* much nicer if properties and attributes were mutually exclusive, and the same interface worked for both. I thought that was the point of having vtables. I'm all for having both, but the implemenation should be encapsulated. I think it's a big mistake to create two separate interfaces.
I tried to unify attributes and properties--I really did. The problem is that they're horribly semantically different. Attributes are class private and guaranteed across all objects of a class, while properties are ad hoc and can be thrown on anything. Python attributes, since they're really done per-object, correspond to our properties. I don't want to force things to be one or the other, because then you'd be in the unpleasant position of not being able to add pythonic attributes to a non-python object.
Unfortunately the semantics of the two systems don't have any overlap, at least no overlap that I can tease out. I suppose python code could see all properties and all attributes as fully-qualified names, with anything new going into the property list, but that's kinda nasty too. Plus there's the issue of python code easily seeing attributes that, arguably, it ought not see since they're supposed to be mostly class-private.
I'm tempted to punt this one to Guido for his opinion.
For callmeth, callmethcc, and tailcallmeth... I can understand the versions with the string... It looks up the method off of the PMC in P2, right? But what good is the version without the string?
One of the string registers is the name of the sub or method being called. The no-string version is supposed to use that. I need to document that better. I also need to add in the redispatch ops, which I forgot.
Again, I'm wary of the separate interface for object stuff.
Well... on the one hand I agree, on the other, method and sub dispatch really are very different things. (That might just be the dislike of the OO Kool-ade speaking, though :)
For these two:
""" addattr Px, Sy, Sz
Add attribute Sy, with a fully-qualified name Sz, to class Px. This will add the attribute slot to all objects of class Px and children of class Px, with a default value of Null
removeattr Px, Sy, Sz
Remove the attribute Sy (fully qualified name Sz) from class Px, all objects of class Px, and all objects of a child of class Px. """
Shouldn't there be correspdonding vtable methods for these? And shouldn't those methods get to decide how/if the instances are affected?
Well... yeah, there should be. I think. Currently I'm planning on peeking inside the guts for parrotclass-based objects and calling a method on the class PMC for non-parrotclass objects. I'm assuming, perhaps incorrectly, that attribute messing about will be rare enough that it doesn't warrant vtable slots. *Does* warrant documentation, which I was punting on.
There were two parts of the spec where I just plain didn't understand the language.
First:
""" The catalog metadata for objects is considered to be attributes on the class, so to get the offset for a class for an object, you fetch the object's class then look up the offset attribute from it. (The class attributes are detailed later) This is safe in general, since the only code reasonably querying a class' attribute list is the class code itself, and if a class doesn't know whether it's a ParrotClass-style class or not you've got bigger problems. """
Does this "catalog" have something to do with mapping strings to the appropriate position in the attribute array? "catalog" isn't mentioned anywhere else in the file, and "metadata" only shows up for the instantiate op... So I really don't get this at all.
Yeah. It's unclear, so I'll go fix it.
The reason I thought a catalog might map strings to ints is because there doesn't seem to be a vtable method for looking attributes up by string. What's the mechanism for making this happen?
There isn't one.
I also don't understand this opcode:
classoffset Ix, Py, Sz Returns the offset of the first attribute for class Sz in object Py.
What do you do with it once you have it?
That's how a class gets access to its particular set of attributes in the big wad 'o attributes attached to the object.
The way it's supposed to work is that if you have three classes:
class Foo { attr $a; attr $b; } class Bar { attr $c; attr $d; } class Xyzzy isa(Foo, Bar) { attr $e; attr $f; }
Methods in class Xyzzy should *only* be able to see attributes $e and $f -- the rest are invisible and inaccessible. In the object there will be six slots, which look sort of like:
+----+ | |->$a +----+ | |->$b +----+ | |->$c +----+ | |->$d +----+ | |->$e +----+ | |->$f +----+
Additionally there'll be a hash/dict/catalog/whatever hanging off the Xyzzy class that looks like:
Foo->0 Bar->2 Xyzzy->4
Now, each class' code *knows* the order that the attributes are in the object. (That code was compiled when the class was defined, after all) Xyzzy, for example, knows that $e is the first attribute and $f is the second attribute. It can't know where in the attribute array they fall, since Xyzzy methods may be looking at an object of a derived class. (In a single-inheritance case you can even know at compile time if you don't allow attributes to be added later. We have to support MI, though)
We could just use a hash for this, of course, and require access be via fully-qualified name. That'd get us past the colliding attribute problem, but that's slow, and we don't like slow. There's also the issue of guaranteed attribute presence -- they're all supposed to be there for all objects of a particular class. That could also be done with an autovivifying hash, but once again it's faster to just up and preallocate an array for the whole wad in one go.
I don't mean to be so grouchy, but you said to speak now or forever hold my peace, so...
Nah, that's not grouchy. :)
This is it. I'll do my best to make pirate work with whatever you come up with, but I'll say this one more time: Encapsulation is our friend! Please don't complicate the system with duplicate interfaces.
Well, that's the thing, they're really not duplicate interfaces. Properties and attributes are separate solutions for separate problems. The bigger problem is that Python (and perl 5) object data stuff maps better to properties, while perl 6 and ruby map better to the slot-based attribute way. (As do java and C++ and most of the other OO languages that I've run across, but we care less about them)
I think we're actually going to be OK with the split way of doing things, if python goes with the property scheme and perl 6/ruby goes with the attribute scheme. Properties are *supposed* to be public and queryable, while attributes are supposed to be private. Python code that accesses per-object thingies will access properties and see all the properties stuck on the object by any other piece of python code, or any other code that slammed on a property, and that's cool. Python code *won't* see the attributes, but again that's OK as it *shouldn't*, since it's private.
I think it's OK, sorta. The solution's not great, but I think it'll work out. I think. Things should even be reasonably interoperable inside class code with cross-language inheritance. (I think we should be just fine for user code)
--
Dan
--------------------------------------"it's like this"------------------- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk