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

=pod

=head1 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 }-----------------+


=head2 A Note about Roles

=head3 Roles B<are not> and B<do not> inherit.

A Role is I<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.

=head2 A Note about Duck-Typing

Duck typing is usually described like this:

  If it quacks like a duck, it must be a duck.

Which basically means that a Type is defined by the methods it responds to, 
instead of some label it has been given. However, this is a very simple defintion
of duck-typing from the I<users> point of view, and fails to explain it from 
the implementation point of view.

From the implementation point-of-view, duck-typing means that instead of an object's
behavior being defined by a class, it is defined by a B<Type> entity which exists in
the somewhat muddy area between Class and Instances. 

  [ Class + [ Role, ... ]] --> ::Type <--- Instances

A class and it's attached roles are "compiled" into a Type, which is then used by 
instances in the system. 

=head1 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.

=head1 Meta Space

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

=over 4

=item MetaClass

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

=item Role

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

=item 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.

=back

=head1 Rough Code Sketches

=head2 Conventions

=over 4

=item "metaclass(Foo)" means the instance of MetaClass with the name of Foo

=item "class(Foo)" means the instance of Class with the name of Foo

=back

=head2 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.superclass(Role::Behavior); 
    $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.superclass(Class::Behavior); 
    $Class.doesRole($Role);
    $Class.addProperties(
        $:superclass,
        @:subclasses
    );
    $Class.addMethods(
        super,
        subclasses,
        invokeMethod 
    );

=head2 metaclass(Role)

When "compiled" the metaclass(Role) will look something 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
    }

NOTE: In order for the metaclass(Role) to be able to compose more roles, it must
have all the methods of a Role::Behavior. Since we don't want these methods to 
actually be inherited down to the next level (the "user" space), we make the 
metaclass inherit from Role::Behavior in the implementation itself, and not as a
C<superclass()>. The same is done for metaclass(Class) and Class::Behavior.

    my $bar_role = Role.new('Bar'); # role(Bar) is an instance of metaclass(Role)
    $bar_role.addProperties(
        $.baz
    );
    $bar_role.addMethods(
        baz
    );
    
Can then be "compiled" into this role(Bar):
    
    role Bar {
        has $.baz;
        method baz { ... }
    }

=head2 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
    );
    
This can then be compiled into this class(Foo):
    
    class Foo {
        has $.foo;
        has $.baz;
        method foo { ... }
        method baz { ... }
    }
      
=head1 AUTHORS

Stevan Little E<lt>stevan@iinteractive.comE<gt>

=cut