Alek Storm wrote:
I was expecting new() to be a vtable method, since that is the only
way we can guarantee that whatever PMC comes out of find_class
implements new(). We don't want code to crash because somebody stuck
a non-class PMC into Parrot as a class.
Huh? A vtable method doesn't promise *anything* more about whether a
particular PMC implements it than a non-vtable method. Not all PMCs
implement all vtable methods. A non-class PMC would not implement the
new() vtable method and you'd get an exception thrown, same as if you
tried to call a non-vtable method.
So, I think we should keep the "new" opcode and make new() a vtable
method, which is called from inside the "new" opcode. This allows
PMCs to create class instances their own way, which is more than
necessary given that ParrotClass, the default implementation, doesn't
work for the semantics of all languages. According to PDD15,
"[Isolation from implementation details] also allows for multiple
concurrent interoperable object systems. The major thrust is for
transparent use of objects, though most class activity (including
creation of subclasses and modifications of existing classes) should
be transparent as well."
I expect the new opcode will locate the appropriate Class PMC and call
the new method on it, which is pretty much what you suggest. I don't see
why it there's any need for it to be a vtable method for that to happen,
or how it not being a vtable method stops other people from implementing
their own class PMCs (they too just have to write a new method).
All that said, there is an argument for having it as a vtable method
that I think stands, which is the same argument that suggests not having
any methods on the class PMC at all and making everything a vtable
method. The argument is that if a language wants to inherit from the
Class PMC, it may well want its own names for "add_attribute" and so on.
That'd mean a few new vtable slots for add_role, methods (get list of
methods), attributes (get list of attributes), roles (get list of roles)
and parents (get list of parents).
Unfortunately, going down that route leaves us with only being able to
use the C calling conventions rather than being able to provide a nice
interface to the OO system as we can by making those things PCCMETHODs.
There is a compromise - make them all vtable methods, write a BaseClass
PMC and inherit Class from it. BaseClass implements all of the vtable
variants of the method, and Class can then provide a sane interface. HLL
implementers who need their own class PMC but can implement it in terms
of the BaseClass semantics can then derive from BaseClass. (Oh, and I
think BaseClass is totally the wrong name, but I know Allison will find
a good name too... ;-))
I actually quite like this solution at the moment. What's anyone else think?
Jonathan