On May 16, 2006, at 19:32, Chip Salzenberg wrote:

There's is a problem with the naming of classes and their associated namespaces
that must be addressed.

The first question is: why is the namespace associated, or - in other words - why does a class C<has> a namespace instead of C<isa> namespace. The latter is AFAIK true for Perl6.
See below[1] for more.

Creating Parrot classes currently requires _typed_ namespaces, that is,
namespaces where more than one object can have the same fully-qualified
name. Parrot's default namespace allows that there be both a namespace and
another object (often a class) with the same name.

Namespace typing is a fine feature for any given HLL to use, but a basic
function of Parrot like class creation must not depend on it.

Why? It's implemented and is working.

There's also a more subtle flaw: a violation of the principle of least
repetition. Given a class (let's say it's a Perl 6 class) named foo::bar,
two distinct Parrot entities, both named foo;bar, must be created to
implement it: the class object, and its method namespace.  This is weak
design.  For example, it makes removing (or renaming) a class into a
multi-step operation.

This would simple be solved with the class C<isa> namespace.

So here are the changes I'm planning to PDD today:

(1) By default, the implementation objects of a class foo;bar will consist of:

   a namespace named      foo;bar
   a class object named   foo;bar;__parrot_class

This isn't quite correct. The first line is actually:

    a namespace named   $HLL;foo;bar

which leads to another can of worms[2], IMHO. I don't like the "__parrot_class" magic. A flag bit (PObj_is_class_FLAG) set in the namespace PMC could achieve the same. But it's still requiring the construction of 2 objects.

[2]
The implicit $HLL in all namespace operations seems to complicate all tasks that cross namespace boundaries, e.g. the whole compiler tool chain or parrot libs. I'd really prefer an explicit toplevel namespace, which is under the control of the code generation.

==[ Entering alternative universe ]===========================

An alternativeq design has the _classes_ being the visible objects, with
namespaces being externally anonymous and only visible by indirecting
through the classes that use them. This alternative is, of course, entirely
feasible, but it has downsides.

This looks like the C<isa> approach.

First, some namespaces would become more equal than others: class
namespaces, vs. namespaces unrelated to classes, would require a new
technique for lookup, or else some convention that classes would provide a namespace interface; neither of these options appeals, especially since the base namespace interface is 'hash', and I doubt that classes responding to
the hash interface meets anybody's idea of "elegant".

[1] The interface problem.

A namespace needs a distinct interface - one that isn't used by any class like 'Hash'. Or IOW - given the strong relationship between namespaces and classes - the namespace interface is a part of the class interface, which we actually already have (in some parts):

VTABLE methods:
  find_method, add_method, remove_method
  set_attr_str, get_attr_str
opcodes:
  addattribute, removeattribute

The latter 2 should probably be virtualized via the interface too. The 'remove'-thingies are all unimplemented.

Now given that an attribute is just the general case[3], it would correspond to the untyped namespace interface. The '*_method' interface deals with subs in a namespace, which is one part of the typed interface.

[3] e.g. for Python:

   m = o.f   # get_attribute, returning a 'bound' method
             # a limited currying operation

There is of course sill the chicken and egg problem of namespaces, when we want to sublass a namespace, which might need some vtable invocation directly via the namespace vtable as opposed to find_method.

This all is also strongly related to interfaces, which we actually don't have yet. A vtable is implementing all internally used interfaces for all PMCs and classes. A vtable, split into distinct interface slots, could be much more flexible, as each PMC could define it's own (and only the needed) interface functions. E.g.

   obj->vtable->scalar_if->abs()       # scalar interface slots
                         ->neg() ...
   ns ->vtable->ns_if    ->find_sub()  # namespace interface slots
                         ...

This would allow to customize methods per interface or per PMC/class (when that's the only one with that specific interface).

leo

Reply via email to