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

Syntax for Constructing new Objects (and classes?)

9 views
Skip to first unread message

Klaas-Jan Stol

unread,
Mar 26, 2007, 12:21:42 PM3/26/07
to Perl 6 Internals
Hello,

I have a short and simple question w.r.t. syntax for constructing new
objects for the architect :-)
Currently, it's done through:

new P0, .Integer
or in PIR:
$P0 = new Integer # or .Integer

I thought to have read somewhere this will be changed into something
like this:

$P0 = Integer.new()

(also solving the issue (ticket) of whether there should be dot-prefix
in PIR for built-in types)
However, I have not read this in the PDD on objects. Will this be the case?

kind regards,
klaas-jan

Allison Randal

unread,
Mar 31, 2007, 1:45:29 PM3/31/07
to Klaas-Jan Stol, Perl 6 Internals
Klaas-Jan Stol wrote:
> Hello,
>
> I have a short and simple question w.r.t. syntax for constructing new
> objects for the architect :-)
> Currently, it's done through:
>
> new P0, .Integer
> or in PIR:
> $P0 = new Integer # or .Integer
>
> I thought to have read somewhere this will be changed into something
> like this:
>
> $P0 = Integer.new()

The two candidates currently are:

$P0 = get_class "HLLClass"
$P1 = $P0.new()

Or:

$P0 = get_hll_namespace
$P1 = $P0.find_class("HLLClass")
$P2 = $P1.new()

> (also solving the issue (ticket) of whether there should be dot-prefix
> in PIR for built-in types)
> However, I have not read this in the PDD on objects. Will this be the case?

No dot-prefix, but also no bareword class names. Only quoted names. Same
is true for both high-level objects and low-level PMC objects.

Allison

Alek Storm

unread,
Mar 31, 2007, 3:42:30 PM3/31/07
to Allison Randal, Klaas-Jan Stol, Perl 6 Internals
>
> $P0 = get_hll_namespace
> $P1 = $P0.find_class("HLLClass")
> $P2 = $P1.new()


Will new() be a vtable method or PCCMETHOD in a Class PMC? That's the only
way I can see this syntax not conflicting with normal method-calling syntax.

Jonathan Worthington

unread,
Mar 31, 2007, 4:09:40 PM3/31/07
to Alek Storm, Allison Randal, Klaas-Jan Stol, Perl 6 Internals
Alek Storm wrote:
>>
>> $P0 = get_hll_namespace
>> $P1 = $P0.find_class("HLLClass")
>> $P2 = $P1.new()
> Will new() be a vtable method or PCCMETHOD in a Class PMC?
It's implemented as a PCCMETHOD in the Class PMC, yes.

Though at the moment you must write:

$P2 = $P1.'new'()

But that may well be a bug in IMCC.

Jonathan

Allison Randal

unread,
Mar 31, 2007, 4:14:58 PM3/31/07
to Alek Storm, Perl 6 Internals

new() is a class method, an ordinary method on the class object. So, in
this code:

$P1 = get_class "Dog"
$P2 = $P1.new()
$P2.foobar()

new() is a method called on the class object, and foobar() is a method
called on the instance of the class object. The two don't conflict
because they're called on different objects.


It sounds like you're getting confused about what a PCCMETHOD is. It's a
method defined in C code that can be called using the full Parrot
calling conventions. That is, it's an ordinary method.

Allison

Jonathan Worthington

unread,
Mar 31, 2007, 4:13:08 PM3/31/07
to Allison Randal, Klaas-Jan Stol, Perl 6 Internals
Allison Randal wrote:
> No dot-prefix, but also no bareword class names. Only quoted names.
> Same is true for both high-level objects and low-level PMC objects.
I guess the upshot of this is we need to deprecate the old syntax and
make sure the new one works. Deprecate in the next release, remove
support in the one afterwards?

Does this also imply that all number-based type instantiation is going
away, and thus we need to deprecate the find_type op too?

Thanks,

Jonathan

Allison Randal

unread,
Mar 31, 2007, 4:24:36 PM3/31/07
to Jonathan Worthington, Perl 6 Internals
Jonathan Worthington wrote:
> Allison Randal wrote:
>> No dot-prefix, but also no bareword class names. Only quoted names.
>> Same is true for both high-level objects and low-level PMC objects.
> I guess the upshot of this is we need to deprecate the old syntax and
> make sure the new one works. Deprecate in the next release, remove
> support in the one afterwards?

We can note it as deprecated now. And the current 'new' accepts string
names, so people can start using it now. But let's get the new objects
working before we remove the old syntax.

> Does this also imply that all number-based type instantiation is going
> away, and thus we need to deprecate the find_type op too?

Eventually, yes (almost certainly), but not in the next month.

Allison

Alek Storm

unread,
Mar 31, 2007, 4:28:29 PM3/31/07
to Allison Randal, Perl 6 Internals
Thank you, but I know what a PCCMETHOD is.

Chromatic

unread,
Mar 31, 2007, 4:44:51 PM3/31/07
to perl6-i...@perl.org, Alek Storm

I believe it *is* normal method-calling syntax. Thus, it should be a
PCCMETHOD.

-- c

Klaas-Jan Stol

unread,
Apr 1, 2007, 10:28:56 AM4/1/07
to Allison Randal, Perl 6 Internals
Allison Randal wrote:
> Klaas-Jan Stol wrote:
>> Hello,
>>
>> I have a short and simple question w.r.t. syntax for constructing new
>> objects for the architect :-)
>> Currently, it's done through:
>>
>> new P0, .Integer
>> or in PIR:
>> $P0 = new Integer # or .Integer
>>
>> I thought to have read somewhere this will be changed into something
>> like this:
>>
>> $P0 = Integer.new()
>
> The two candidates currently are:
>
> $P0 = get_class "HLLClass"
> $P1 = $P0.new()
>
> Or:
>
> $P0 = get_hll_namespace
> $P1 = $P0.find_class("HLLClass")
> $P2 = $P1.new()
IIUC, instead of create a new object (either a built-in PMC or an OO
object) in 1 instruction, it should now be done in 2?
Or, can I also write:

$P0 = Integer.new() # create new Integer PMC object
$P1 = Hash.new() # create new Hash PMC object

kjs

Allison Randal

unread,
Apr 1, 2007, 9:03:43 PM4/1/07
to Klaas-Jan Stol, Perl 6 Internals
Klaas-Jan Stol wrote:
>>
>> $P0 = get_class "HLLClass"
>> $P1 = $P0.new()
>>
> IIUC, instead of create a new object (either a built-in PMC or an OO
> object) in 1 instruction, it should now be done in 2?

Yes. It adds a small amount of tedious typing, but gains us a great deal
of power in our OO system. We will still have a 'new' opcode, but it
will likely only handle the simplest cases.

$P0 = new "HLLClass"

> Or, can I also write:
>
> $P0 = Integer.new() # create new Integer PMC object
> $P1 = Hash.new() # create new Hash PMC object

No, we're eliminating bareword class names from PIR/PASM entirely. It's
easy to do that in an HLL, though.

Allison

Allison Randal

unread,
Apr 1, 2007, 10:21:02 PM4/1/07
to Klaas-Jan Stol, Perl 6 Internals
Allison Randal wrote:
>
>> Or, can I also write:
>>
>> $P0 = Integer.new() # create new Integer PMC object
>> $P1 = Hash.new() # create new Hash PMC object
>
> No, we're eliminating bareword class names from PIR/PASM entirely. It's
> easy to do that in an HLL, though.

Unless, of course, you declare Integer and Hash as local variables, e.g.:

.local pmc HLLClass
HLLClass = get_class "HLLClass"
$P1 = HLLClass.new()

Allison

Joshua Isom

unread,
Apr 2, 2007, 1:37:23 AM4/2/07
to Allison Randal, Perl 6 Internals

On Mar 31, 2007, at 3:24 PM, Allison Randal wrote:

> Jonathan Worthington wrote:
>> Does this also imply that all number-based type instantiation is
>> going away, and thus we need to deprecate the find_type op too?
>
> Eventually, yes (almost certainly), but not in the next month.
>
> Allison

I'm not sure how the imcc compiler handles the .Foo syntax internally,
but there's a file, runtime/parrot/include/pmctypes.pasm that at least
appears as though it's magically included into the beginning of every
pir/pasm file. If it were changed to output a string instead of an
integer, the dot syntax would still work with the strings(although the
under the hood part I don't know about). It's merely a macro
substitution if you think about it.

Plus it'd mean we wouldn't have to rewrite all of the tests, and keep
the old dot syntax that I personally like(easier for editors to detect
a typo).

Allison Randal

unread,
Apr 2, 2007, 3:00:01 AM4/2/07
to Joshua Isom, Perl 6 Internals
Joshua Isom wrote:
>
> I'm not sure how the imcc compiler handles the .Foo syntax internally,
> but there's a file, runtime/parrot/include/pmctypes.pasm that at least
> appears as though it's magically included into the beginning of every
> pir/pasm file. If it were changed to output a string instead of an
> integer, the dot syntax would still work with the strings(although the
> under the hood part I don't know about). It's merely a macro
> substitution if you think about it.
>
> Plus it'd mean we wouldn't have to rewrite all of the tests, and keep
> the old dot syntax that I personally like(easier for editors to detect a
> typo).

There are several reasons to do away with constants for types and the
class registry (the type constants just supply an ID from the class
registry).

- They don't respect namespaces, so you currently can't have an
"Integer" class, for example, in multiple different HLLs. We could
mangle namespaces into the type registry, but we already have a
perfectly good way of storing classes in a namespace hierarchy, so it
doesn't make sense to implement it twice.

- They can't handle having more than one implementation of a class in
the system. This we need to safely allow dynamic changes to a class
after it has been instantiated.

And, less critical, but still annoying:

- The type constants collide with user-defined constants in
less-than-desirable ways. If you define a constant with the same name as
a type constant, the system simply ignores the redefinition and supplies
the type constant's value.

Allison

Leopold Toetsch

unread,
Apr 2, 2007, 5:12:09 PM4/2/07
to perl6-i...@perl.org, Joshua Isom, Allison Randal
Am Montag, 2. April 2007 07:37 schrieb Joshua Isom:
> I'm not sure how the imcc compiler handles the .Foo syntax internally,
> but there's a file, runtime/parrot/include/pmctypes.pasm that at least
> appears as though it's magically included into the beginning of every
> pir/pasm file.

Nope the pmctypes.pasm isn't included. It's more a docu thingy than anythig
else. The magic happens inside the lexer:

# imcc.l 442

<emit,INITIAL>{DOT}{LETTER}{LETTERDIGIT}* {
char *macro_name = str_dup(yytext+1);
int type = pmc_type(interp, string_from_cstring(interp, macro_name,
0));

leo

Alek Storm

unread,
Apr 2, 2007, 7:33:44 PM4/2/07
to Allison Randal, Perl 6 Internals
On 3/31/07, Allison Randal <all...@perl.org> wrote:

Apparently I came off as not fully knowing what I was talking about.
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. In addition, since vtable
methods are not PCCMETHODs, new() would not be directly callable from
PIR. Hence my confusion.

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."

So, whaddya think?

--
Alek Storm

Jonathan Worthington

unread,
Apr 2, 2007, 8:00:48 PM4/2/07
to Alek Storm, Allison Randal, Perl 6 Internals
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

Alek Storm

unread,
Apr 2, 2007, 10:46:59 PM4/2/07
to Jonathan Worthington, Allison Randal, Perl 6 Internals
On 4/3/07, Jonathan Worthington <jona...@jnthn.net> wrote:
> 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've asked for something pretty darn close to what you've suggested (see #41619), but you've explained it a lot better than I ever could.

What I think you were saying:
Default
|
BaseClass (default Parrot implementation)
/ \
Class UserClass
(PCCMETHOD interface to BaseClass) (modified version of BaseClass)

Please correct me where I'm wrong :)

Instead of having a BaseClass, which I think would be an unnecessary layer of indirection, PMCs implementing class behavior should be able to inherit from either:
1. Default: Throw an exception if an unimplemented vtable method is called on the PMC.
2. ParrotClass: All semantics are already taken care of, and you need only change the behavior where necessary.
The choice of which to inherit from is left up to the PMC implementor.

What I'm saying:
Default
/ \
UserClass ParrotClass (default Parrot implementation)
|
UserClass

We could also add "class" to the list of do-able interfaces available to PMCs in tools/build/pmc2c.pl.

--
Alek Storm

Allison Randal

unread,
Apr 3, 2007, 2:47:15 AM4/3/07
to Jonathan Worthington, Alek Storm, Perl 6 Internals
Jonathan Worthington wrote:
> 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).

We've got add_method, add_attribute, add_parent, add_role (note, these
are confusingly named next to add, add_int, and add_float), get_class,
get_attr, set_attr, find_method, clone, isa, can, does specified as
vtable entries.

What would be remaining is removes for parents/attributes/roles,
introspection for methods/parents/attributes/roles, name, new, newclass,
subclass.

- newclass is just syntactic sugar for 'new', so doesn't get its own
vtable entry

- There's too much confusion around 'new' so I'll suggest 'instantiate'
(which was an opcode in an earlier draft, and has been implemented and
deleted at various times over the history of Parrot).

- Does 'subclass' make sense as a vtable entry? "Make a subclass of
yourself." No, let's leave it at 'add_parent' on the child class.

- For removes, let's go with 'remove_*' for parent/attribute/role.

- For now let's say you can't set the 'name' on an instantiated class,
but only through the initialization parameters of a class. (And
re-evaluate if it turns out we need the feature later. We may also need
to consider how to modify clones.)

- I'm inclined not to provide individual named vtable entries for
introspecting the methods/parents/attributes/roles/name information of
the class, because once we start down that road we'll be providing
hundreds of named vtable entries for introspecting various different
classes and PMCs, which is just insane. Instead, I'd like to provide one
general introspection vtable entry, which each class/PMC can implement
how it chooses. Suggestions welcome. I'll start with: 'inspect', which
when called with no arguments returns a data structure of all
information it considers relevant to report, and when called with a
string name ('attributes', for example, or 'name'), returns a PMC Hash,
Array, String, Integer, or Number value corresponding to the requested
name. This may be overridden to report information about the internals
of an object that aren't actually true (useful for mocking). It can also
be used for straight introspection capabilities even when a particular
object is using keyed access to act like a hash or array.

> 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... ;-))

Class is the base for all classes. I can see the value of stripping away
any methods that may interfere with a particular HLL's concept of how a
class should behave, so we'll do that. And what should we call the
subclass of Class that adds lots of methody syntactic sugar over the
top? My best suggestion at the moment is ParrotClass, as a contrast to
PerlClass, PythonClass, RubyClass, etc.

Allison

Jonathan Worthington

unread,
Apr 3, 2007, 8:20:56 AM4/3/07
to Alek Storm, Allison Randal, Perl 6 Internals
Alek Storm wrote:
> I've asked for something pretty darn close to what you've suggested
> (see #41619), but you've explained it a lot better than I ever could.
Glad we're thinking similar things.

> What I think you were saying:
> Default
> |
> BaseClass (default Parrot implementation)
> / \
> Class UserClass
> (PCCMETHOD interface to BaseClass) (modified version of BaseClass)
>
> Please correct me where I'm wrong :)

Yes, though maybe I'd not say "modified version of BaseClass", but
"inherits from and extends BaseClass" or something.

> Instead of having a BaseClass, which I think would be an unnecessary
> layer of indirection, PMCs implementing class behavior should be able
> to inherit from either:
> 1. Default: Throw an exception if an unimplemented vtable method is
> called on the PMC.
> 2. ParrotClass: All semantics are already taken care of, and you need
> only change the behavior where necessary.
> The choice of which to inherit from is left up to the PMC implementor.

I think, naming of it all aside, we agree here. I said in my email:

~~


HLL implementers who need their own class PMC but can implement it in
terms of the BaseClass semantics can then derive from BaseClass.

~~

Or put another way:

* If you want, inherit from Default and build from scratch.

* If [insert name of the thing that just has the vtable methods here]
gives the right semantics to build upon, inherit from that.

* If [insert name of the thing that also provides the nice sane
interface here] is what you want and you just want to add to it a bit,
inherit from that.

Or more generally, inherit from whatever leads to the least code
duplication and gives the interface you want. :-)

> We could also add "class" to the list of do-able interfaces available
> to PMCs in tools/build/pmc2c.pl.

Aye, we could, though we already have the "I am a class" flag. I don't
think having two different ways to specify or check if something is a
class is a good thing.

Jonathan

Allison Randal

unread,
Apr 3, 2007, 2:26:58 PM4/3/07
to Perl 6 Internals
Allison Randal wrote:
>
> Class is the base for all classes. I can see the value of stripping away
> any methods that may interfere with a particular HLL's concept of how a
> class should behave, so we'll do that. And what should we call the
> subclass of Class that adds lots of methody syntactic sugar over the
> top? My best suggestion at the moment is ParrotClass, as a contrast to
> PerlClass, PythonClass, RubyClass, etc.

Then again, the syntactic sugar methods could just be a role applied to
Class, once we get roles working for low-level PMCs.

Allison

Alek Storm

unread,
Apr 3, 2007, 7:55:28 PM4/3/07
to Allison Randal, Perl 6 Internals
Since classes are now a great deal more polymorphic, it seems we don't
really need a newclass opcode anymore, since HLLs will instantiate the
class objects themselves anyway. Instead of having

$P0 = get_class "HLLClass"
$P1 = $P0.new()

Or:

$P0 = get_hll_namespace


$P1 = $P0.find_class("HLLClass")
$P2 = $P1.new()

we can just use set_hll_global and get_hll_global, storing the class
PMCs like normal objects. Which makes sense, given that class PMCs
can also *be* normal objects (metaclasses, etc), and we don't need a
separate container for classes. My Smalltalk-to-PIR compiler used
this, and it worked quite well.

> Then again, the syntactic sugar methods could just be a role applied to
> Class, once we get roles working for low-level PMCs.

Now *that* would be cool.

--
Alek Storm

Alek Storm

unread,
Apr 4, 2007, 5:03:40 PM4/4/07
to Allison Randal, Perl 6 Internals
On 4/3/07, Alek Storm <alek....@gmail.com> wrote:
>
> we can just use set_hll_global and get_hll_global, storing the class
> PMCs like normal objects. Which makes sense, given that class PMCs
> can also *be* normal objects (metaclasses, etc), and we don't need a
> separate container for classes. My Smalltalk-to-PIR compiler used
> this, and it worked quite well.
>

Whoops, that metaclasses reference didn't quite make sense (it was pretty
late in my timezone). I meant that, in Smalltalk for example, classes are
also first-class objects. Also, in prototype-based languages like Self and
ECMAScript, objects might also want to act like classes, as they can be
cloned and extended, etc.

--
Alek Storm

Allison Randal

unread,
Apr 4, 2007, 9:17:54 PM4/4/07
to Alek Storm, Perl 6 Internals
Alek Storm wrote:
>
> Whoops, that metaclasses reference didn't quite make sense (it was pretty
> late in my timezone). I meant that, in Smalltalk for example, classes are
> also first-class objects. Also, in prototype-based languages like Self and
> ECMAScript, objects might also want to act like classes, as they can be
> cloned and extended, etc.

Yup, it makes for a much more consistent and flexible system.

Allison

Alek Storm

unread,
Apr 5, 2007, 10:43:59 AM4/5/07
to Perl 6 Internals


Awesome. I was a little worried, because I heard talk of a separate "class
registry" or something of the sort.

--
Alek Storm

0 new messages