☺唐鳳☻
and 1 contributors

Perl 6 Meta Meta Class Hierarchy

This document attempts to explain the Meta-Meta-Class hierarchy and implementation.

       .............> MetaClass <...............
       :                 |                     :         ---> isSubclassOf
       :                 |                     :         ...> isInstanceOf             
       :                 V                     :         - -> does()
       :          Class::Behavior<----------+  :
       :                 |                  |  :
       :                 |                  |  :       
       :                 V                  |  :       
       :  +------> Role::Behavior           |  :                                  
       :  |              |                  |  :
 metaclass(Role)         |      ..... > metaclass(Class)
       ^                 V      : 
       :              Object    :
       :                 |      :
       :                 |      : 
       :                 V      :
      Role < - - - - - Class ...   
   
 
 role Role {}
 class Class does Role {}  
 
 class Object is Class {}
 class Role::Behavior is Object {}
 class Class::Behavior is Role::Behavior {} 
 class MetaClass is Class::Behavior {}  
 
 my $Role = MetaClass.new('Role');
 $Role.superclass(Role::Behavior); 
 
 my $Class = MetaClass.new('Class'); 
 $Class.superclass(Class::Behavior);
 $Class.roles($Role);
 

Or a sligthly different view of the same:

 +--{ Implementation Layer }--------------------+
 |                                              |  ---> isSubclassOf
 |   +----------->Role::Behavior                |  ...> isInstanceOf
 |   |                  ^                       |  - -> does()
 |   |                  |                       |
 |   |           Class::Behavior<-----------+   |
 |   |                  ^                   |   |
 +---|------------------|-------------------|---+
 |   |                  |                   |   |
 |   |                  |                   |   |
 |  Role .........> MetaClass <.......... Class |
 |   ^                                      |   |                
 |   + - - - - - - - - - - - - - - - - - - -+   |
 |                                              |
 +---------------{ Meta Space }-----------------+

A Note about Roles

Roles are not and do not inherit.

A Role is flattened into either a Class or another Role. This act of flattening negates any real "hierarchy" like that of a Class hierarchy.

This is an important distinction to remember.

Implementation Layer

The behavior of classes and roles must be described somehow, and we should be able to re-use that implementation as well.

I propose a Class::Behavior and Role::Behavior implementation.

A Role::Behavior has a hash of methods and a hash of properties, as well as an array of Roles. Role::Behavior encapsulates all of the behavior needed to compose a Role.

A Class::Behavior is a subclass of Role::Behavior because a class also has a hash of methods and properties and an array of roles. It then adds to that with a parent class as well as a set of subclasses. Class::Behavior encapsulates all of the behavior needed to compose a Class.

Meta Space

The Meta Space contains all of our meta-objects of which I see 3 distinct types.

MetaClass

This is the "root" of our MetaClass hierarchy, and the loopback point of our object model. It is a subclass of Class::Behavior.

Role

The Role is itself an instance of the MetaClass, but it is also a subclass of the Role::Behavior.

Class

The Class too is an instance of the MetaClass, and it is a subclass of Class::Behavior.

The Class also does() the role Role.

NOTE: this Class.does(Role) relationship may not be needed, but I am leaving it in for now.

Rough Code Sketches

Conventions

"metaclass(Foo)" means the instance of MetaClass with the name of Foo
"class(Foo)" means the instance of Clas with the name of Foo

metametaclass(MetaClass)

    metametaclass MetaClass is Class::Behavior {
        has $.name;   
        has @:roles;   
        has $:superclass;
        has @:subclasses;            
        has %.properties;
        has %.methods;   
        
        method addProperties {}
        method addMethods {} 
        method invokeMethod {}
        method super { ... } # a class must be able to inherit from another class
        method subclasses { ... } # a class must be able to be inherited from        
        method doesRole {} # doing a Role just folds properties and methods into the metaclass
    }
    
    my $Role = MetaClass.new('Role'); # metaclass(Role) is an instance of metametaclass(MetaClass)
    $Role.addProperties(
        $.name,
        @:roles,
        %:properties,
        %:methods
    );
    $Role.addMethods(
        roles
    );
    
    # Hmmm,... MetaClass and Role look suspiciously similar
    
    my $Class = MetaClass.new('Class'); # metaclass(Class) is an instance of metametaclass(MetaClass)    
    $Class.doesRole($Role);
    $Class.addProperties(
        $:superclass,
        @:subclasses
    );
    $Class.addMethods(
        super,
        subclasses,
        invokeMethod        
    );

metaclass(Role)

When "compiled" the metaclass(Role) will look like this:

    metaclass Role is Role::Behavior {
        has $.name;
        has @.roles;
        has %.properties;
        has %.methods;

        method roles { ... } # a role must be able to attach other roles to it
        # property access is made possible through methods
    }

    my $bar_role = Role.new('Bar'); # role(Bar) is an instance of metaclass(Role)
    $bar_role.addProperties(
        $.baz
    );
    $bar_role.addMethods(
        baz
    );
    
    # creates this ...
    
    role Bar {
        has $.baz;
        method baz { ... }
    }

metaclass(Class)

When "compiled" the metaclass(Class) will look like this:

    metaclass Class is Class::Behavior does metaclass(Role) {
    
        # the following properties are from metaclass(Role)
        #   $.name, @.roles, %.properties, %.methods;
        # the following methods too
        #   roles(), invokeMethod()
    
        has @.superclasses;
        has @.subclasses;

        method super { ... } # a class must be able to inherit from another class
        method subclasses { ... } # a class must be able to be inherited from
        method invokeMethod { ... }
    }

    my $foo_class = Class.new('Foo'); # class(Foo) is an instance of metaclass(Class) 
    $foo_class.doesRole('Bar');
    $foo_class.addProperties(
        $.foo
    );
    $foo_class.addMethods(
        foo
    );
    
    # creates this ...
    
    class Foo {
        has $.foo;
        has $.baz;
        method foo { ... }
        method baz { ... }
    }
      

AUTHORS

Stevan Little <stevan@iinteractive.com>