The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

Perl 6 Meta-Model

This document will attempt to codify the perl 6 meta-model. It is very much still a work in progress and it's contents may change by the minute at times.

The Perl 6 Object environment

The perl6 object environment will be a multi-layered environment which might look something like this:

 +-{Instance}-+ +---{Type}--+ +--{Class}--+ +--{MetaClass}--+
 |            | |           | |           | |               |
 |   ------   | |   -----   | |  -------  | |  -----------  |
 |  ( $foo )------>( Foo )----->( Class )---->( MetaClass ) |
 |   ------   | |   -----   | |  -------  | |  -----------  |
 |            | |::Foo      | |::Foo.meta | |::Foo.meta.meta|
 |            | |$foo.ref   | |           | |               |
 +------------+ +-----------+ +-----------+ +---------------+

The following describes some of the details of this leveled environment.

This document does not touch on the intricacies of the Class model (roles, types, sub-types, classes, etc) - these are all contained in the Class level and, for the sake of this document, are treated as an opaque "Class".

each "level" is independant of the levels above and below it

Relationships such as "is a", "does a", etc only make sense within a particular level of the object system. So, for example, it does not make sense to describe all of these objects as descending from some über-Object class. Rules and principles that apply on one level do not necessarily transfer to the levels below.

each "level" looks like Objects from Perl

Despite this inherant heterogeneity of each level, they all look like Objects from Perl. They are described and accessed in exactly the same way, and can even share type definitions and refer to each other, to some extent. So, they all .does(Object), this is a definition.

The below table attempts to summarise the implications of these two points as code.

In the below table,

   $foo = MyClass.new
   $type = ::MyClass;
   $meta = MyClass.meta;
   $meta_meta = MyClass.meta.meta;

 Topic:          $foo       $type      $meta     $meta_meta
 .ref          ::MyClass   ::Type     ::Class  ::Meta::Class
 .isa(Object)      true     false      false      false
 .does(Object)     true     true       true       true
 .isa(MyClass)     true     true       false      false
 .does(MyClass)    true     true       false      false
 .isa(Class)       false    false      true       false
 .does(Class)      false    true       true       true
 .isa(Type)        false    true       true?      true?
 .does(Type)       false    true       true       true
 .isa(Meta::Class) false    false      false      true
 .does(Meta::Class)false    false      false      true
 .meta             dies     $meta    $meta_meta   dies(*)

(*) - this might return magic proxy objects that go on forever, but this is not required for core operation.

Even the above is in an ideal situation; it might be that with some weird MetaModels, you simply don't get those guarantees. However, such situations are probably a bit 'obstruese' so won't be mentioned further.

Occupants of the Perl6 object environment

Every Object is an instance of a Type

These are the occupants of our environment O. Every noted Object has exactly one uniquely associated entity called a Type.

99% of code will be using Objects for absolutely everything.

Every Type is defined by a Class

Type objects are normally identified by a leading ::, however if a type is global or is in scope, the :: prefix may be safely dropped.

Type objects always have a Class object, which may or may not be named. This object is available via .meta().

Type objects respond to .isa(), .does(), .can(), etc methods by querying their associated .meta() object with .classCan(), etc method calls, quite possibly caching the results for faster method dispatch.

Every ::SomeType.meta is a Class

The objects are what would normally be described as your program's Model; ie, objects that are Classes (or Roles, etc) will be called "Dog", "Tree", etc.

When you write:

  class Dog {
  }

You are actually doing something like this;

  Class.new(name => Dog).apply;

This is because the term Class actually refers to a Meta::Class, not a Class. There is nothing special about the term Class that makes it so, other than it was defined so. If we had chosen the term Qualifarniciferate to refer to instances of Meta::Classes, then the above would simply create an object of class (sorry, Qualifarniciferate) Class.

Class objects are instances of the "Class" Meta::Class

Class objects are presented to Perl in much the same manner as instances of some Class called Meta::Class might be. This might fool you into thinking that they are also instances of some Class, however in truth they are only ever instances of Meta::Class objects.

Instances of Meta::Class objects are what would normally be described as your language Model, or program Meta-Model. These will be called "Class", "Role", etc.

It is these objects that implement methods like .isa, .does, etc. They will provide proxy methods in the Type objects that they produce, that when compiled will produce the desired behaviour.

If you are performing run-time class creation without eval(), it is these objects that you need to call methods like .addMethod() to. They may or may not be `compiled' to run-time ::Type objects immediately after any change, however such behaviour may be considered undefined.

Meta::Class are instances of Meta::Meta::Classes

The Meta::Meta::Class objects define the structure of the Meta::Class objects.

If you are performing run-time trait specification without eval(), such as by adding Class Traits, Role Traits, and other language object traits, you are modifying objects on this level. New Meta::Property objects will be attached to the relevant Meta::Class objects. Hence, when you define a new trait, you are not modifying the program model, you are modifying the language model.

On the other hand, when you assign a trait to a new variable, you are creating a new type that has a new anonymous class which is the old class with the extra trait property set, so that requires no modifications on this level.

Meta::Meta::Class are instances of the interpreter

In theory, we could extend this Meta::Meta relationship to any level. However, it simply does not make much sense to deal with these objects directly; altering them is even more confusing. They might be Haskell definitions in the case of pugs, or perhaps in a Pure Perl Interpreter they will actually be real Objects; but you will not see the definition of Meta::Meta::Meta::Class in this module; in a sense, Perl 6 classes are being used as an underlying Meta::Meta::Model.

AUTHORS

Sam Vilain <samv@cpan.org>

Stevan Little <stevan@iinteractive.com>

1 POD Error

The following errors were encountered while parsing the POD:

Around line 38:

Non-ASCII character seen before =encoding in 'I<über>-Object'. Assuming UTF-8