NAME ^

docs/pdds/pdd15_objects.pod - Object and Class semantics for Parrot

ABSTRACT ^

This PDD describes the semantics of Parrot's object and class systems.

VERSION ^

$Revision$

DEFINITIONS ^

Object ^

An object is a value that incorporates both data and behavior related to that data.

Class ^

A class defines a pattern of characteristics and behaviors from which objects are constructed.

Attribute ^

An attribute is a slot in an object that contains a value, generally a PMC. Attributes are referenced by class name/attribute name pairs.

Attributes are set on a class-wide basis, and all the objects of a class will have the same set of attributes. Most OO languages don't allow attribute changes to existing classes, but Parrot's base attribute system does allow it. In order to safely support advanced dynamic features in HLLs, attributes are not accessible via fixed attribute offsets, but only via named lookup.

Method ^

A method is a piece of code that you invoke by name through an object. Methods implement the behaviour of an object.

Parent class ^

Also called the super-class. The parent class is, in an inheritance situation, the class being derived from. If A derives from B, B is the parent class of A.

Child class ^

Also called the sub-class. The child class is, in an inheritance situation, the class doing the deriving. If A derives from B, A is the child class.

Role ^

A role adds attributes and methods into a class without inheritance. The composed class retains a list of roles applied to it (so they can be checked with does), but otherwise maintains no distinction between composed attributes and methods and those defined in the class.

Delegate ^

An object that is transparently (to the user) embedded in another object. Delegate objects are used in those cases where we can't inherit from a class because the class is from a different object universe.

Property ^

A property is a role that only adds attributes and accessors.

Properties are generally assigned at runtime, and a particular property may or may not exist on a PMC at any particular time. Properties are not restricted to objects as such--any PMC may have a property attached to it.

Interface ^

An interface is a role that only adds methods.

DESCRIPTION ^

- The object and class system provides the flexibility to implement a core set of dynamic languages (Perl 6, Ruby, Python, etc). Other class systems may be implemented later to support other languages.

- Classes may have an associated namespace. (Anonymous classes are not associated with a namespace.)

- Classes may have one or more immediate parent classes

- Classes may have a catalog of attribute names.

- Classes may have a list of roles they implement

- Classes can instantiate an object of their class

- Classes can add and remove parent classes

- Classes can add and remove attributes

- Classes can add (but not remove) roles

- Classes are instances of a meta-class and have their own sets of class methods and class attributes

- Objects may have an array of attributes. Attribute values may be PMCs or a low-level type.

- Objects have an associated class.

- Objects may have a custom vtable or use a class-wide vtable.

- Objects can call a method

- Objects can retrieve a method PMC for a method (for deferred method calls)

- Objects can fetch their class

- Objects can be subclassed (note that objects may not necessarily be able to have their classes changed arbitrarily, but making a subclass and moving the object to it is allowable)

- Objects can get an attribute by name

- Objects can set an attribute by name

IMPLEMENTATION ^

There are four pieces to the object implementation. There are the PMCs for the classes and objects, the opcodes the engine uses to do objecty things, the specific vtable methods used to perform those objecty things, and the supporting code provided by the interpreter engine to do the heavy lifting.

Please note that Parrot, in general, does not restrict operations on objects and classes. If a language has restrictions on what can be done with them, the language is responsible for making sure that disallowed things do not happen. For example, Parrot permits multiple inheritance, and will not stop code that adds a new parent to an existing class. If a language doesn't allow for multiple inheritance it must not emit code which would add multiple parents to a class. (Parrot may, at some point, allow imposition of runtime restrictions on a class, but currently it doesn't)

Class PMC API ^

There are two PMC classes, Class and Object. Class PMCs hold all the class-specific information. Instantiating a new OO class creates a new Class PMC, and enters the new OO class into Parrot's PMC class table, at which point it is indistinguishable from any other PMC class.

It's important to note that 'standard' classes are Class PMC instances, or instances of a subclass of the Class PMC, and 'standard' objects are Object PMCs. It isn't necessary to create a brand new low-level PMC class for each OO class, and they all share the Class or Object vtable, respectively.

An instance of the Class PMC has ten attributes, which are:

0

The class name

1

A link to the class's associated namespace

2

A "have I been instantiated since I was last modified" flag

2

An array PMC of the immediate parent classes

3

A cached array of all parent PMCs, in search order (this is an optional optimization, and can be calculated from the class's rules of inheritance, the list of immediate parent classes, and the parent classes' rules of inheritance)

4

An array PMC of the composed roles

5

A hash PMC of the methods defined in the class or composed into the class

6

A hash PMC of the overloaded PMC vtable entries for the class.

7

The class attribute metadata hash. Keys are the attribute names and the values are a hash of attribute characteristics, including name, type, the class they're associated with and any flags (for example, private). Note that this only stores metadata for the attributes defined in this class, and not for attributes inherited from its parents.

8

The full attribute lookup table. This associates attribute names with an index into the object's attribute storage (an array). It includes all attributes defined in the current class and every other class that it inherits from either directly or indirectly. The table is keyed on the name of the class where the attribute is defined, along with the attribute name. The value is an index into the per-object attribute store.

9

The attribute cache. While the attribute lookup table defines every attribute, whether it is visible or not with the current method resolution order (MRO), the cache maps the names of the visible attributes directly to an index in the per- object attribute store. That saves a more costly lookup in the full attribute lookup table.

The attribute catalog holds only the attributes defined in a particular class. When instantiating an object, the object data store is created as a ResizablePMCArray, so doesn't need any specific details of the class's attribute structure. As attributes are set in the object (based on the index in the lookup table), the Array expands to accommodate the attribute indexes that are actually used. In the common case, a relatively small set near the lower index range is all that will be used.

When setting the attribute cache it is necessary to scan all parent classes as well as the instantiated class for attributes defined there. The inheritance rules (MRO) for a particular HLL will determine which child class attributes override which parent class attributes. The cache is only set on individual accesses to a particular attribute.

(If a parent class changes its set of attributes, should that change appear in later instantiations of objects from child classes? If so, all of these classes would need to be re-constructed as a result of the change; note that any already instantiated objects would refer to the old class. NOTE: flag old classes with an "updated" status, to notify objects of the old class that they should rebless themselves into the new class next time they access the old class?)

Class PMCs also have the "I am a class" flag set on them.

Methods

name

The accessor for the name attribute. With no argument, it simply returns the current value for name. When passed an argument, it sets the name of the class, and also sets the association with a namespace.

new

    obj = class.'new'( 'myattrib' => "Foo" )
Create a new instance object from the class object. It takes an optional slurpy, named list of attributes and values to initialize the object.

attributes

An accessor for the attributes of the class. It returns the a Hash of all attributes, with a key of the attribute name, and a value of the Attribute object. The accessor is read-only.

add_attribute

Adds a single attribute to the class. It takes a simple string name, and a simple string value for type.

parents

An accessor for the parents of the class. It returns an Array of all parents. The accessor is read-only.

add_parent

Adds a single parent to the class. It takes a simple string name.

roles

An accessor for the roles of the class. It returns an Array of all roles. The accessor is read-only.

add_role

Adds a single role to the class. It takes a simple string name.

Classes, Namespaces, and the Class Registry

[Stream-of-consciousness to be cleaned up later] The class registry has a much diminished role in this implementation. Its only responsibility is maintaining a mapping of unique IDs to class objects throughout the system. (We may eventually be able to eliminate the registry altogether.) It can't be used for looking up classes by name, because it's possible to have multiple classes with the same name in the same namespace. (When you extend an existing class, it actually creates a new class, that replaces the old class in the Namespace, but the old class can't be thrown away if it has objects instantiated in it. The old objects still point to the old class and do their method resolution and attribute lookup through that class. If a class hasn't been instantiated, adding a method doesn't create a new class. If it has been instantiated, it creates a new class the first time it's extended, and then doesn't create a new class until it is instantiated again.) The class registry needs to have names removed entirely (it doesn't care about names anymore). Low-level PMC types also need entries in the namespace hierarchy.

The Namespace always points to the most current incarnation of the class. All the class objects that nominally exist in a namespace point to that namespace object.

A class can be garbage collected when it has no instantiatated objects and no Namespace object referencing it. When a class is garbage collected, it should remove itself from the registry.

Object PMC API ^

Object PMCs are the actual objects, and hold all the per-object instance data.

The Object PMC is an array of meta-information and attributes. The elements of this array are:

0

The class PMC

1

The object attribute store. This is simply an array of PMCs that provide the values for the attributes. It may be a resizable PMC array to provide lazy growth rather than allocating all needed memory for all attributes. We find the indexes into this array from the attribute cache or lookup table in the class.

A list of the object's attributes is accessible from the class. The attribute cache is the most straightforward way to retrieve a complete list of attributes visible to the object, but the first time you introspect for a complete list the class may have to calculate the list by traversing the inheritance hierarchy.

Object PMCs have the "I am an object" flag set on them.

Object PMCs have no methods aside from those defined in their associated class. They do have vtable methods providing access to certain low-level information about the object, method call functionality, etc. See the sections below on Objects and Vtables.

[stream-of-consciousness again] In addition to a value type, objects can have a container type. The container type can't be stored in the object itself, because a single object may live within multiple containers. So, the container type (when it exists) is stored in the LexPad or Namespace entry for a particular variable.

In a static language like C#.Net: B isa A A o1 = new B(); B o2 = new B();

o1.x; # retrieves A's attribute o2.x; # retrieves B's attribute

o1.foo(); # call's B's method o2.foo(); # call's B's method

Role PMC API ^

An instance of the Role PMC has five attributes, which are:

0

The role name

1

A link to the role's associated namespace

2

An array PMC of composed roles

3

An array PMC of the methods defined in the role or composed into the role

4

The role attribute hash. Keys are the attribute names and the values are a hash of attribute characteristics, including name, type, and the role they're associated with.

Methods

name

The accessor for the name attribute. With no argument, it simply returns the current value for name. When passed an argument, it sets the name of the role, and also sets the association with a namespace.

attributes

An accessor for the attributes of the role. It returns the a Hash of all attributes, with a key of the attribute name, and a value of the Attribute object. The accessor is read-only.

add_attribute

Adds a single attribute to the role. It takes a simple string name, and a simple string value for type.

roles

An accessor for the roles composed into the role. It returns an Array of all roles. The accessor is read-only.

add_role

Adds a single role to the role. It takes a simple string name.

Opcodes ^

The following ops are provided to deal with objects. Please note that method calls are governed by Parrot's calling conventions, and as such objects, method PMCs, return continuations, and parameters must be in the right places, though some ops will put parameters where they need to go.

classoffset Ix, Py, Sz [deprecated]

Returns the offset of the first attribute for class Sz in object Py.

getattribute Px, Py, Iz

Returns attribute Iz of object Py and puts it in Px. Note that the attribute number is an absolute offset.

getattribute Px, Py, Sz

Get the attribute with the fully qualified name Sz from object Py and put it in Px.

setattribute Px, Iy, Pz

Set the attribute Iy of object Px to Pz. Note that this op stores the actual PMC rather than a copy, and so if the PMC's value is subsequently changed, the value of the attribute will also change.

setattribute Px, Sy, Pz

Set the attribute of object Px with the fully qualified name Sy to Pz

callmethod

callmethod Sz

Call a method. If the method name is provided, we find the PMC for the named method and put it in the sub/method slot. If no name is provided we assume that all the calling conventions have already been set up and the method PMC is already in the proper place.

callmethodcc

callmethodcc Sx

Make a method call, automatically generating a return continuation. If a method name is passed in we look up the method PMC for the object and put it in the method slot. If a method name isn't provided then we assume that things are already properly set up.

tailcallmethod (Unimplemented) [deprecated]

tailcallmethod Sx (Unimplemented) [deprecated]

Make a tailcall to method Sx. If no method name is given, we assume everything is already set up properly.

newclass Px, Sy

Create a new base class named Sy, and put the PMC for it in Px

subclass Px, Py, Sz

Create a new class, named Sz, which has Py as its immediate parent.

addparent Px, Py

Add class Py to the end of the list of immediate parents of class Px. Adds any attributes of Py (and its parent classes) that aren't already in Px.

removeparent Px, Py (Unimplemented)

Remove class Py from the parent list of Px. All parent classes of Py which aren't parent classes of what remains of Px's parent list are removed, as are their attributes.

addattribute Px, Sy

Add attribute Sy 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.

removeattribute Px, Sy (Unimplemented)

Remove the attribute Sy from class Px, all objects of class Px, and all objects of a child of class Px.

addrole Px, Py

Add role Py to the end of the list of roles of class Px. Adds any attributes of Py that aren't already in Px.

instantiate Px, Py, Sz (Unimplemented) [deprecated]

Instantiate a brand new class, based on the metadata in Py, named Sz.

Vtables ^

To make this work all PMCs must have the following vtable entries. They may, for non-objects, throw an exception.

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 Class-style class or not you've got bigger problems.

find_method(string *)

Returns the PMC for the named method. If no method of this name exists, nor can be constructed, returns a Null PMC.

Note that for languages which support default fallback methods, such as Perl 5's AUTOLOAD, this would be the place to return it if a normal lookup fails.

isa(class *)

Returns true or false if the class passed in as a parameter is in the inheritance hierarchy of the object.

can(string *)

Returns true or false if the object can perform the requested method. (Including with an AUTOLOAD)

does(class *)

Returns true or false to note whether the object in question implements the interface passed in.

get_attr(INTVAL) [deprecated]

Returns the attribute at the passed-in offset for the object.

get_attr(STRING*)

Returns the attribute with the fully qualified name for the object.

set_attr(INTVAL, PMC *) [deprecated]

Sets the attribute for the passed-in offset to the passed-in PMC value

set_attr(STRING*, PMC *)

Set the attribute with the fully qualified name for the object.

get_class

Returns the class PMC for the object.

Currently Parrot only supports mutating a class' metainformation for Class classes. This is a restriction which will be lifted at some point soon.

What The Bytecode Sees ^

The bytecode is isolated from most of the internal details of the implementation. This allows both for flexibility in the implementation and forward compatibility, generally good things. It 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.

EXAMPLES ^

The following examples all assume we're working with basic Object objects and Class classes.

Creating a new class ^

To create a new class Foo which has no parent classes:

   newclass $P0, "Foo"

Creating a new class with multiple parents ^

To create a class Foo with the parents A and B, the code would be:

   getclass $P0, "A"
   getclass $P1, "B"
   subclass $P2, $P0, "Foo"
   addparent $P2, $P1

Creating a new class with attributes ^

Adding the attributes a and b to the new class Foo:

  newclass $P0, "Foo"
  addattribute $P0, "a"   # This is offset 0 + classoffset
  addattribute $P0, "b"   # This is offset 1 + classoffset

Instantiating an object ^

Assuming we want an object of class Foo:

  .local pmc FooClass
  .local pmc MyObject
  find_class FooClass, "Foo"
  new MyObject, FooClass

Calling a method on an object ^

Calling the method Xyzzy on an object, assuming the PDD03 calling conventions are respected:

  callmethod "Xyzzy"

  set S0, "Xyzzy"
  callmethod

Or, if a return continuation needs constructing:

  callmethodcc "Xyzzy"

  set S0, "Xyzzy"
  callmethodcc

Accessing attributes from within a class ^

With named access:

  getattribute $P1, $P0, "Foo\x0b"

Explanations ^

To get a new class, you can do a newclass, which creates a new class with no parents besides Parrot's default super-ish parent class.

To get a new child class, you have two potential options:

Subclass the parent

Create a new standalone class and add a parent

Both ways work. It is, however, more efficient to use the first method, and just subclass the immediate parent class of your new class.

When adding in extra parents in a multiple-inheritance scenario, subclass the first class in the immediate parent list then use the addparent op to add in the rest of the immediate parents.

VTABLE OVERLOADING ^

Classes may override the vtable methods, allowing objects of a class to behave like a primitive PMC. Each vtable slot has a corresponding named method that Parrot looks for in your class hierarchy when an object is used in a primitive context.

To use these properly at a low-level requires a good working knowledge of the way Parrot works--generally for higher-level languages the language compiler or runtime will provide easier-to-use wrappers. These methods are all prototyped, and take a single fixed argument list, and return at most a single value.

While vtable methods may take a continuation, those continuations may not escape the vtable method's execution. This is due to the way that vtable methods are called by the interpreter--once a vtable method is exited any continuation taken within it is no longer valid and may not be used.

Note that any class method that wishes to use Parrot's multi-method dispatch system may do so. This is, in fact, encouraged, though it is not required. In the absence of explicit multimethod dispatch, a left-side wins scheme is used.

The following list details the raw method names:

init

Called when the object is first created.

init_pmc

Alternative entry point called when object is first created. Accepts a PMC parameter used to initialize the given object. Interpretation of the PMC is PMC-specific.

NOTE: It is strongly suggested that init_pmc(PMCNULL) be equivalent to init(), though there will of necessity be exceptions.

morph

mark

Called when the DOD is tracing live PMCs. If this method is called then the code must mark all strings and PMCs that it contains as live, otherwise they may be collected.

This method is only called if the PMC is flagged as having a special mark routine, and is not necessary for normal objects.

destroy

Called when the object is destroyed. This method is only called if the PMC is marked as having an active finalizer.

getprop

setprop

delprop

getprops

type

type_keyed

type_keyed_int

type_keyed_str

subtype

name

clone

find_method

get_integer

Return the integer value of the object

get_integer_keyed

get_integer_keyed_int

get_integer_keyed_str

get_number

Return the floating-point value of the object

get_number_keyed

get_number_keyed_int

get_number_keyed_str

get_bignum

Return the extended precision numeric value of the PMC

get_string

Return the string value of the PMC

get_string_keyed

get_string_keyed_int

get_string_keyed_str

get_bool

Return the true/false value of the PMC

get_bool_keyed

get_bool_keyed_int

get_bool_keyed_str

get_pmc

Return the PMC for this PMC.

get_pmc_keyed

get_pmc_keyed_int

get_pmc_keyed_str

get_pointer

get_pointer_keyed

get_pointer_keyed_int

get_pointer_keyed_str

set_integer_native

Set the integer value of this PMC

set_integer_same

set_integer_keyed

set_integer_keyed_int

set_integer_keyed_str

set_number_native

Set the floating-point value of this PMC

set_number_same

set_number_keyed

set_number_keyed_int

set_number_keyed_str

set_bignum_int

Set the extended-precision value of this PMC

set_string_native

Set the string value of this PMC

set_string_same

set_string_keyed

set_string_keyed_int

set_string_keyed_str

set_bool

Set the true/false value of this PMC

assign_pmc

Set the value to the value of the passed in

set_pmc

Make the PMC refer to the PMC passed in

set_pmc_keyed

set_pmc_keyed_int

set_pmc_keyed_str

set_pointer

set_pointer_keyed

set_pointer_keyed_int

set_pointer_keyed_str

elements

Return the number of elements in the PMC, if the PMC is treated as an aggregate.

pop_integer

pop_float

pop_string

pop_pmc

push_integer

push_float

push_string

push_pmc

shift_integer

shift_float

shift_string

shift_pmc

unshift_integer

unshift_float

unshift_string

unshift_pmc

splice

add

add_int

add_float

subtract

subtract_int

subtract_float

multiply

multiply_int

multiply_float

divide

divide_int

divide_float

modulus

modulus_int

modulus_float

cmodulus

cmodulus_int

cmodulus_float

neg

bitwise_or

bitwise_or_int

bitwise_and

bitwise_and_int

bitwise_xor

bitwise_xor_int

bitwise_ors

bitwise_ors_str

bitwise_ands

bitwise_ands_str

bitwise_xors

bitwise_xors_str

bitwise_not

bitwise_shl

bitwise_shl_int

bitwise_shr

bitwise_shr_int

concatenate

concatenate_native

is_equal

is_same

cmp

cmp_num

cmp_string

logical_or

logical_and

logical_xor

logical_not

repeat

repeat_int

increment

decrement

exists_keyed

exists_keyed_int

exists_keyed_str

defined

defined_keyed

defined_keyed_int

defined_keyed_str

delete_keyed

delete_keyed_int

delete_keyed_str

nextkey_keyed

nextkey_keyed_int

nextkey_keyed_str

substr

substr_str

invoke

can

does

isa

freeze

thaw

thawfinish

visit

share

LANGUAGE NOTES ^

This PDD is due an overhaul. This requirements section is for language implementers to list the OO-related needs of their language in so as to aid that.

PMCS ^

Ruby: Just like small talk, everything is an object. I'm hoping to be able to implement core Ruby classes(String, Array, Hash, Module, etc) something like this.

ParrotClass | RubyClass String | | \ / RubyString

Objectspace ^

Ruby: Objectspace in Ruby allows the programmer to iterate through every live object in the system. There is some debate about how to make this play nice with different garbage collection schemes.

Classes ^

A class is a collection of methods and attributes. It would be desirable, for those classes whose definition is fully known at compile time, to have a convenient way to have the class along with its attributes and methods stored into a PBC file rather than created at runtime. However, creation of new classes at runtime will be needed too.

Meta-classes ^

Ruby: Ruby has meta classes. It would be nice if classes were objects in Parrots OO model.

Attributes ^

Attributes are instance data associated with a class (or role, however those are supported). They may not always be of a type specified by a PMC, though boxing/unboxing is of course an option.

Perl 6: All attributes are opaque (not externally visible, even to any subclasses).

.Net: Attributes may be private (not externally visible), public (always externally visible), protected (only visible to subclasses) and internal (only visible inside the current assembly - the closest correspondence in Parrot is perhaps only visible inside the same PBC file). Additionally, it is allowable for a subclass to introduce an attribute of the same name as the a parent class has, and they both exist depending on what type an instance of the class is currently viewed as being (read: there is a difference between the type of the reference and the type of the value).

Ruby: Attributes can be dynamically added and removed at runtime.

Methods ^

Perl 6: Methods may be public (anyone can invoke them) or private (only invokable by the class they are defined in). Additionally, submethods are methods that do not get inherited.

.Net: Like attributes, methods may be public, private, protected or internal.

Ruby: has a method_missing that gets called when method resolution fails to find a method. Methods can be dynamically added and removed at runtime.

Constructors ^

A constructor is run when an object is instantiated.

.Net: There may be many constructors for an object (provided they all have different signatures), and the correct one is called based upon the passed parameters.

Inheritance ^

Perl 6: Multiple inheritance.

.Net: Single inheritance.

Ruby: Single inheritance but support for mixins of Ruby modules.

Interfaces ^

An interface specifies a set of methods that must be implemented by a class that inherits (or implements) the interface, but does not provide any form of implementation for them.

.Net: Interfaces are pretty much what was just describe above. XXX Need to check behavior of you implement two interfaces with methods of the same name.

Roles ^

A role consists of a set of methods and attributes. It cannot be instantiated on its own, but must be composed into a class. When this happens its methods and attributes become of that classes methods and attributes. This may happen at compile time or runtime, however when a role is composed into a class at runtime then what really happens is that a new anonymous class is created with the role composed into it and then the namespace entry for the existing class is updated to refer to the new one. Note that this means classes must be garbage collectable, with all those referred to by a namespace or with objects of that class existing being marked live.

Perl 6: Roles pretty much are a Perl 6 thing, so the definition above contains all that is needed. An open question is whether Parrot worry about collision detection? For compile time composition that's easy to punt to the compiler; for runtime composition, that's not so easy though.

Introspection (aka Reflection) ^

Perl 6: Reflection provides access to a list of methods that a class has, its parent classes and the roles it does, as well as the name of the class and its memory address. For methods, their name, signature, return type and whether the method is declared multi are available.

.Net: Reflection provides access to a list of attributes and methods as well as the name of the class and its parent. The types of attributes and signatures of methods are also available.

Inner Classes ^

An inner class is essentially a class defined within a class. Therefore it has access to things private to its outer class.

Perl 6: Inner classes are allowed, and may also be private.

.Net: Inner classes are allowed and may be private, public, protected or internal.

Delegation ^

Delegation is where a method call is "forwarded" to another class. Parrot may provide support for simple cases of it directly, or could just provide a "no method matched" fallback method that the compiler fills out to implement the delegation.

Perl 6: Delegation support is highly flexible, even allowing a regex to match method names that should be delegated to a particular object.

Prototype-based OO ^

Prototype-based OO has no classes. All objects are cloned from existing objects and modified. Requires lightweight singleton creation, without a needing separate class for every instance object. (Self, JavaScript, and Io are examples of prototype-based 00.)

QUESTIONS ^

Should we have a super or next opcode?

NOTES ^

Interaction with PMCs ^

The interaction between objects and PMCs is currently underspecified.

Translation ^

The following list a set of languages, then within each language what the Parrot term translates to.

Python

Attribute

A Python attribute maps to a Parrot property

.NET

Attribute

What .NET calls an attribute Parrot calls a property

Property

What .NET calls a property we call an attribute

Generic Terminology

Instance Variable

Instance Variables map to what we call attributes

ATTACHMENTS ^

None.

FOOTNOTES ^

None.

REFERENCES ^

None.


parrot