
=pod

=head1 NAME

PIL^N object repr types

=head1 DESCRIPTION

I propose that *all* the objects in the PIL^N runtime be able to
support the creation of the different kinds of $repr types. Each 
different $repr type will have an accompanying vtable which will 
contain the methods available to manipulate that $repr type. 
There will be a few common methods available, they will be:

    `id()       # returns the id of the instance
    `meta()     # returns the class of the instance
    `repr()     # returns the name of the $repr type used
    `as_bit()   # returns whether a representation is empty
    `as_str()   # returns a stringified representation

The layout of these types will all be pretty similar, and look 
something like this:
               
    +-------------+
    | id          |
    +-------------+
    | meta-ptr    |
    +-------------+
    | <repr_type> |
    +-------------+

Here is a description of each of the different $repr types:

=head2 $meta`create("p6opaque")

The opaque type takes nothing in its constructor, all items must be added to it
using the methods in its vtable.  Those methods are as follows:

    `has_attr($key)             # returns a bit type
    `get_attr($key)             # returns the value stored at $key
    `set_attr($key, $value)     # returns nil

The C<$key> is constrained to be a PIL^N string.

=head2 $meta`create("p6array")

The array type should be passed a PIL^N list type, any values 
found in that list will be added into the resulting object. It is
also possible to add more elements as well, or even to replace the
list entirely using the following vtable of methods:

    `exists($idx)               # returns a bit type
    `fetch($idx)                # fetches the value at $idx
    `store($idx, $val)          # sets the $val at $idx
    `splice($idx, $len, @vals)  # removes and stores a list of values
    `push($val)                 # adds a value from the end
    `unshift($val)              # adds a value from the front
    `pop()                      # removes and returns a value from the end
    `shift()                    # removes and returns a value from the front
    `replace(@vals)             # replaces the array
    `as_map()                   # returning a PIL^N hash
    `as_seq()                   # returning a PIL^N list
    `as_int()                   # returns the number of elements as int
    `as_num()                   # returns the number of elements as num

=head2 $meta`create("p6hash")

The hash type should be passed a PIL^N hash or list type, and
any values found with it will be transferred into the resulting object.
As with the array and opaque types, it is possible to manipulate the
elements further with the vtable of methods:

    `exists($key)               # returns a bit type
    `fetch($key)                # fetches the value at $key
    `delete($key)               # removes the $key
    `store($key, $val)          # sets the $val at $key
    `replace(%vals)             # replaces the hash
    `union(%vals)               # adds into the hash
    `keys()                     # fetchs keys (returning a PIL^N list)
    `vals()                     # fetchs vals (returning a PIL^N list)
    `as_map()                   # returning a PIL^N hash
    `as_seq()                   # returning a PIL^N list
    `as_int()                   # returns the number of elements as int
    `as_num()                   # returns the number of elements as num
        
=head2 $meta`create("p6scalar")

As with the array and hash $repr types, this should be passed a PIL^N type. 
(This could include list and hash types too, but it probably wouldn't make 
sense really). The value passed can be stored and fetched with the following
vtable of methods:

    `fetch()                    # returns the value stored
    `store($value)              # stored the $value passed in

This repr type has some interesting qualities to it. It could be used to 
not only implement the ^Scalar container type, but it can also be used for 
the autoboxing of ^Int, ^Num, ^Str, etc. with no real specialization. 

=head2 $meta`create("p6nil")

This is a very specialized repr type, which is used to implement the 
"class but undef" part of the Perl 6 object model as spec-ed by @Larry. 
This has no additional methods in its vtable other than the core ones 
(`meta, `id and `repr).

The way this will be used is to create undefined instances of a class which 
will act like any other instance of a the class, but evaluate to undef. It 
will provide a means of dispatching to the meta-class as well through the
`meta method. This nil instance serves as a "prototypical" instance through
which you can inspect the behaviors of "real" instances.
  
  [13:53] stevan  so ::Int will have repr of nil, and ::Int.meta will be 
                  ^Int,.. which means we will have a nil instance of ^Int
  [13:53] stevan  I like that
  [13:53] stevan  it works
  [13:53] stevan  so ::Int's cls is ^Int
  [13:53] audreyt yes.

=head1 CLARIFICATION OF CONCERNS/MEANING

The issue has been raised on #perl6 that if the repr type 'p6array' uses
a Perl 6 Array as it's repr, then what does a Perl 6 Array use? It was also
brought up that to use a Perl 6 Array as a repr would be quite silly.

So I will clarify what repr is in the I<context of the PIL^N metamodel only>.

The 'p6array' repr type does not mean "use a Perl 6 Array as my repr type", 
instead it should be understood to mean "use the same repr type that a 
Perl 6 Array would use". The same is also true for 'p6hash', 'p6scalar' and
all other repr types which seem like the don't make sense as repr types.

=head1 SEE ALSO

docs/notes/object_space.txt

docs/notes/PILN_core_classes.pod

docs/notes/range_implementation_notes.pod

=head1 AUTHOR

Stevan Little <stevan@iinteractive.com>

Audrey Tang <autrijus@autrijus.org>

=cut
