First, my apologies to Chip for this message -- I know he's
probably already answered this question for me a couple of
times but I've either forgotten, I'm too dense, or I just
can't find the answers now that I need them.  So, with
appropriate contrition for asking yet again...

After the changes introduced by pdd21, I'm lost as to how 
to deal with classname conflicts when multiple HLL namespaces 
are involved.  I have a very real example from PGE, but bear 
with me as I present some background.  Also, note that I've
simplified a few details here for illustration, so if
you compare this to the actual PGE code you'll notice some
(insignificant) differences.

Background - before pdd21
-------------------------

When PGE was first implemented, everything in Parrot tended to
go in a global shared namespace (or at least that's all I knew about).
Therefore, to avoid namespace conflicts, I wrote PGE with "PGE::"
prefixes in all of its classnames.  Therefore we have classes like:

    PGE::Match    - base class for Match objects
    PGE::Grammar  - base class for Grammar objects
    PGE::Exp      - base class for nodes in the regex AST

The PGE::Exp class is itself subclassed into different node
types representing literals, groups, anchors, quantifiers, closures,
etc.  The current PGE code has these expression node subclasses named
with a prefix of "PGE::Exp::", but they probably should have been
named without the Exp:: portion, thus we have AST classes like:

    PGE::Literal  - literal expressions
    PGE::Group    - non-capturing group
    PGE::CGroup   - capturing group
    PGE::Subrule  - subrule call
    PGE::Closure  - embedded closure

Here's code to create PGE::Exp and its subclasses:

    .sub __onload :load
        $P0 = newclass 'PGE::Exp'
        $P0 = subclass 'PGE::Exp', 'PGE::Literal'
        $P0 = subclass 'PGE::Exp', 'PGE::Group'
        $P0 = subclass 'PGE::Exp', 'PGE::CGroup'
        $P0 = subclass 'PGE::Exp', 'PGE::Subrule'
        $P0 = subclass 'PGE::Exp', 'PGE::Closure'
        # ...
    .end

Okay, so far so good.  Now let's move into the world
postulated by pdd21_namespaces...


After pdd21
-----------

According to pdd21, each HLL gets its own hll_namespace.
PGE is really a form of HLL compiler, so it should have
its own hll_namespace, instead of using parrot's hll namespace:

    .HLL 'pge', ''

Now then, the 'PGE::' prefixes on the classnames were
just implementation artifacts of working in a globally
flat namespace -- as a high-level language PGE really
ought to be referring to its classes as 'Match',
'Exp', 'Literal', etc.  So, if we're in the PGE HLL,
we ought to be able to drop the 'PGE::' prefix from
our classnames and namespaces.

So, here's the revised version of the code to create
the classes:

    .HLL 'pge', ''

    .sub __onload :load
        $P0 = newclass 'Exp'
        $P0 = subclass 'Exp', 'Literal'
        $P0 = subclass 'Exp', 'Group'
        $P0 = subclass 'Exp', 'CGroup'
        $P0 = subclass 'Exp', 'Subrule'
        $P0 = subclass 'Exp', 'Closure'
        # ...
    .end

This code fails when run from parrot, because Parrot seemingly
already has a class named 'Closure':

    $ ./parrot ns.pir
    Class Closure already registered!
    current instr.: '__onload' pc 19 (ns.pir:9)
    $

So, this brings me to my question:  What is the official 
"best practice" pattern for HLLs to create their own classes
such that we avoid naming conflicts with existing classes
in Parrot and other HLLs?

----

Anticipating the answer that the classname arguments to C<subclass>
should be namespace keys instead of strings, as in:

    $P0 = subclass [ 'pge'; 'Exp' ], [ 'pge'; 'Closure' ]

what namespace directive do we use to define the methods 
for the Closure class?

Thanks in advance, and apologies if I've overlooked the obvious.

Pm

Reply via email to