=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