=pod

=head1 Meta-Meta-Classes

... or How to twist your brain up in knots without even trying.

Note that the "Meta Meta Class" used in this document does I<not>
exist in the implemented language at all; more concretely, it is the
I<encoding> of the class model in the host language.

=head1 Introduction

This document is an ongoing attempt to clarify (and hopefully
simplify) the all too hairy topic of MetaClasses and as a result provide
a working basis for the Perl-6 Meta-Model.  This may not be the
I<correct> nor is it the I<one and only way> to view the concept of 
MetaClasses; many books have been written on the subject which all 
use subtly different concepts and terminology.

=head1 The Object Environment

Let us assume for a moment that all our object's live in an I<object>
environment (B<O>), which is a finite set of objects, each of which is
identified with a unique object reference.

Here is a diagram of the entire object environment:

  +-{Instance}-+ +--{Class}--+ +{MetaClass}+ +{MetaMetaClass}+
  |            | |           | |           | |               |
  |   ------   | |   -----   | |  -------  | |  -----------  |
  |  ( $foo )------>( Foo )----->( Class )---->( MetaClass ) |
  |   ------   | |   -----   | |  -------  | |  -----------  |
  |            | |           | |           | |               |
  +------------+ +-----------+ +-----------+ +---------------+

Our object environment has a set of rules which help to define the
elements that exist within it. 

However, before we do that, we must first make a point about the 
nomenclature found in the document. 

=head3 Meta-Nomenclature

MetaClass systems are highly reflective by nature. This results in
a very cyclical nomenclature, which at times can seem as if it is 
using itself to describe itself. Because of this we will try to be
as consistent as possible in our nomenclature, and describe the 
"rules" of it here.

First, it needs to be noted that objects themselves are primative 
creatures in this environment. When we use the term object, we are
refering to this primative element, and not the instance of a class.

When we write "type of XXX", we are moving upwards in the object
environment (to the right on the above diagram); the type of an
Instance is a Class, the type of a Class is a MetaClass, and the
type of a MetaClass is a MetaMetaClass.

When we write "instance of XXX", we are moving downwards (or to the 
left in the diagram).  An instance of a MetaMetaClass is a MetaClass, 
an instance of a MetaClass is a Class, and an instance of a Class is
an Instance.

To stay on the same level, we use the term "XXX object". 

There is also an important distinction between a noun "class", and
a proper noun "Class". The proper noun "Class" refers specifically 
to the Class MetaClass, while "class" will refer to the class of which
an object is an instance of (however in most cases we will use "type"
here instead of class).

=head2 Rules of the object environment
 
=over 4

=item B<Every C<Instance> is an instance of some C<Class>>

These are the occupants of our environment B<O>.  Every noted
C<Instance> has a uniquely associated entity called a C<Class>.

=item B<Every C<Class> is an instance of a C<MetaClass>>

These objects are what would normally be described as your program's
I<Model>; ie, objects that are I<Classes> will be called "Dog", 
"Tree", etc.

=item B<Every C<MetaClass> is an instance of some C<MetaMetaClass>>

These objects are what would normally be described as your B<language>
I<Model>, or program I<Meta-Model>.  These will be called "Class",
"Role", etc.

=item B<Every I<MetaMetaClass> is an instance of the underlying system>

In theory, we could extend this relationship to any level.  However,
it simply does not make much sense to deal with these objects
directly, they are the building block on which the above are created.

=back

=head1 So what is a Meta-Meta-Class anyway?

Lets first define the other objects in our environment.

=head2 What is an object?

An object is a primative element in our environment. For the purposes of 
illustration we will use simple data-dictionaries/perl-ish hashes.

Here is an example of how an object describing a book might look like:

 {
    Book => { 
        'title'  => "VALIS",
        'author' => "Phillip K. Dick",
    }
 }

=head2 So what is an Instance?

An I<Instance> is simply an object with a c<class> slot whose value is a
reference to the class from which the instance is derived, and a set of instance 
variables (which are defined by the class (and which we will see later)).

So a C<iBook> instance of the class I<Book> would look like this:

 {
    'class' => Book
    Book => { 
        'title'  => "VALIS",
        'author' => "Phillip K. Dick",
    }
 }

=head2 So what is a Class?

A I<Class> is itself just another data dictionary, however its structure is a bit 
more complex. 

First, our class must have a name.

A class also needs to have a set of default instance variables from which new 
instances can be created. 

Next, our class needs to have a method table, which is just another data dictionary 
whose keys are labels and whose values are code references. This table is seperate 
from the instance variables becuase methods remain in the class, and are not 
copied into the instance.

And lastly, we have inheritance. Our class needs to have parents, which we represent
as an ordered list of other I<Class> objects.

So given that, our I<Book> class might be structured something like this:

 {
    'class' => Class,
    Class => {
        'name' => 'Book',
        'parents' => [ ... ],
        'instance_vars' => {
            Book => { title => '', author => '' }
        },
        'method_table' => {
            'get_author' => sub { ... },
            'set_author' => sub { ... },                    
            'get_title'  => sub { ... },
            'set_title'  => sub { ... },                                        
        }
    }
 }

As you can see, our I<Book> class is itself an instance of the meta-class I<Class>. 

A list of supported instance variables and methods can be found by accumulating a properly 
sorted unique list of all a class's instance_vars and method_tables merged with those of 
its ancestors. These lists make it is possible to determine the instance variable and 
method resolution order. 

=head2 So what is a MetaClass?

Once again, we can represent our meta-class as a data dictionary. Here is an example of 
how the meta-class I<Class> would look:

 {
    'class' => MetaClass,
    MetaClass => {
        'name' => 'Class',
        'parents' => [ ... ],
        'instance_vars' => {
            Class => { 
                'name'          => "",
                'parents'       => [],
                'instance_vars' => {},
                'method_table'  => {}
            }
        },
        'method_table' => {
            'create_instance' => sub { 
                return { 'class' => Class, Class.<instance_vars> }
            }
        }
    }
 }

The C<instance_vars> for a I<Class> are basically those of an empty parent-less class, 
nothing more, nothing less. The simplicity of this notion can be somewhat difficult to
swallow. The tempation is to make it seem much more complex, but in reality it is not.

We also take this opportunity to define a C<create_instance> method for our I<MetaClass> 
which basically just creates a new data dictionary, adding the required 'class' key and 
value pair, along with a copy of the C<instance_vars>. Again, it need not be any more 
complex than that.

=head2 So what is a MetaMetaClass?

Now we are back to our original question, and hopefully by now the answer is quite obvious.

A MetaMetaClass is simply a concrete implementation of the data structures we have been 
constructing above. Our MetaMetaClass is the root of our object hierarchy, and the object from
which all others can be defined.

"That's all?" you say. "But it can't possibly be all!". 

It is of course important to keep a few things in mind, the first of which is that this 
MetaMetaClass is actually independent of a given programming language. That it is not 
something which the "user" should ever really have access too. It is a part of the compiler 
and/or runtime environment upon which a programming language resides.

The second thing is ... hmmm, what was it?

=head1 Why do we need all this abstraction?

What follows is a (slightly edited) snippet of a converstation which took place on IRC.

    <gaal>	    why do we need one more level after classes?
    <gaal>	    and how come just one more level is enough?
    <gaal>	    what do you do with that? that kind of stuff
    <stevan>	well, there is not a really a quick answer
    <stevan>	but I will try :)
    <stevan>	basically it is this
    <stevan>	a class needs to be something
    <stevan>	an instance of something that is
    <stevan>	because there are more than one class in any system
    <gaal>	    why not an object, like in java?
    <stevan>	well the Object type in Java is sort of like a metaclass
    <gaal>	    okay
    <stevan>	it is the base from which all things are derived
    <stevan>	just automagically
    <gaal>	    yes, i see that.
    <stevan>	the heirarchy must come to a point/root
    <stevan>	in Java it is the Object
    <stevan>	in Smalltalk it is MetaClass (i think)
    <stevan>	take a theoretical object model 
    <gaal>	    uh huh
    <stevan>	where we have basic Classes
    <stevan>	which have methods and properties
    <stevan>	say you want to add Final classes
    <stevan>	like Java
    <stevan>	how would you do that?
    <stevan>	subclass Class of course
    <stevan>	but this means that Class itself must be an instance of something 
    <gaal>	    okay, yes
    <stevan>	remember too that this is not something the "user" of the language ever sees
    <gaal>	    yup
    <gaal>	    that was clear enough from your explanation
    <stevan>	so you can subclass Class and get FinalClass
    <stevan>	so this brings up the question, what is Class an instance of
    <stevan>	MetaClass
    <stevan>	so you can stop your model at MetaClass
    <stevan>	and say that is the root
    <stevan>	OR
    <stevan>	you can go one level higher
    <stevan>	which then makes it easier to have Roles, Classes, Traits, etc.
    <stevan>	the MetaMetaClass is the root now, and each MetaClass is an instance of it
    <stevan>	some of the MetaClasses in Perl6 will be Role, Class
    <stevan>	mugwump also included Module and Package too
    <gaal>	    the perl code in ext/, is it part of the actual implementation of oop in pugs?
    <stevan>	no
    <gaal>	    has autrijus assimilated that into the haskell code?    
    <stevan>	right now it is just a prototype to play around with an object model
    <gaal>	    ah, okay
    <stevan>	he might eventually do that
    <stevan>	if it works out
    <gaal>	    i see. this is cool stuff.    
    <stevan>	but it is easier to prototype in perl (5|6) then it is in Haskell (at least for me)
    <gaal>	    yeah, me too.
    <stevan>	meta-meta-hacking :)
    <stevan>	basically you are modeling the class/object system
    <gaal>	    yes, i get that. i think java is a big help here because it's so consistent
    <stevan>	I will try to update the meta-meta doc later today
    <gaal>	    okay thanks for the brief.
    <stevan>	np

I always find that the best way to explain things is to use examples. So for an 
example of how one might use meta-classes (not meta-meta-classes), please see the 
F<create_your_own_object_model.pod> document in the folder as this document.

=head1 ACKNOWLEDGEMENTS

Much of what is found in this document is a direct rip-off of the contents of the first
few chapter of this book (defined here as an instance of a Book class):

 {
    'class' => Book,
    Book => {
        'title'     => "Putting Metaclasses to Work",
        'authors'   => [ 'Ira R. Forman', 'Scott H. Danforth' ],
        'publisher' => 'Addison-Wesley'
        'isbn'      => 0-201-43305-2,
    }
 }

However, despite my plagarism/summariazation, I still take responsibility for all errors, 
inconsistencies or outright lies this document might contain.

=head1 AUTHORS

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

Sam Vilain E<lt>samv@cpan.orgE<gt>

=cut
