That does, though, argue that we need to revisit the global access
opcodes. If we're going hierarchic, and we want to separate out the
name from the namespace, that would seem to argue that we'd want it
to look like:
find_global P1, ['global', 'namespace', 'hierarchy'], "thingname"
That is, split the namespace path from the name of the thing, and
make the namespace path a multidimensional key.
Or I suppose we could just punt and toss the special global access
entirely and make the global namespace a hash 'o hashes hanging off
the interpreter and access it like any other variable, but that makes
local obscuration of the namespace somewhat difficult and I'd rather
not for right now.
This'd be the time to weigh in on it, folks...
--
Dan
--------------------------------------"it's like this"-------------------
Dan Sugalski even samurai
d...@sidhe.org have teddy bears and even
teddy bears get drunk
I expect we need multiple options and let compiler writers figure out which
ones
they need. (see **)
1) Lookup a fully qualified name in the top level namespace (true globals,
Foo::Baz::i)
2) Lookup a fully qualified name in a specific namespace (namespace handle
in PMC or string)
3) Upward lookup of a fully qualified name starting at a specific namespace
(I'm in Baz, resolve j = lookup in Baz, lookup in Baz->parent, lookup
in Baz->parent->parent)
Difference between 2 and 3 is that 2 does not recurse upwards to resolve
the name.
**We may also want variations of non-qualified name lookups (optimized not
to worry about tokenizing
the identifier).
That's off the top of my head from having written a couple of toy
compilers. Keyword = toy
Of course we'll need forms tailored to object instances that will also have
to deal with the
semantics of inheritance.
-Melvin
> find_global P1, ['global', 'namespace', 'hierarchy'], "thingname"
> That is, split the namespace path from the name of the thing, and
> make the namespace path a multidimensional key.
> Or I suppose we could just punt and toss the special global access
> entirely and make the global namespace a hash 'o hashes hanging off
> the interpreter and access it like any other variable,
What about:
getinterp P2
set P1, P2['global';'namespace';'hierarchy';'thingname']
That is get_pmc_keyed() on a ParrotInterpreter PMC with a multi-key,
straight-forward. The set_pmc_keyed() stores a global.
Constructing a multy-key by hand isn't that simple (or would need
hacking imcc) (and Key componenent separator is a semicolon).
leo
> Dan Sugalski <d...@sidhe.org> wrote:
>
> > Okay, okay, I give -- hierarchic namespaces are the way to go. Makes
> > local overrides somewhat interesting, but we'll burn that bridge
when
> > we get to it.
> >
> > find_global P1, ['global', 'namespace', 'hierarchy'], "thingname"
So (excuse the Perl 5), $::thingie would be this:
find_global P1, [], "thingie"
(Or [], "$thingie".)
Makes it odd to actually name a symbol, since it's broken in one + N.
What's the good of separating the symbol name from the namespace name?
> > That is, split the namespace path from the name of the thing, and
> > make the namespace path a multidimensional key.
> >
> > Or I suppose we could just punt and toss the special global access
> > entirely and make the global namespace a hash 'o hashes hanging off
> > the interpreter and access it like any other variable,
>
> What about:
>
> getinterp P2
> set P1, P2['global';'namespace';'hierarchy';'thingname']
>
> That is get_pmc_keyed() on a ParrotInterpreter PMC with a multi-key,
> straight-forward. The set_pmc_keyed() stores a global.
What if global.namespace happens to be autoloaded or otherwise magic?
Will the get_keyed break down and do something equivalent to this?
getinterp P2
set P1, P2['global';'namespace']
set P1, P1['hierarchy';'thingname']
Meaning the construction of an extra multikey? Yech, maybe.
> Constructing a multy-key by hand isn't that simple (or would need
> hacking imcc) (and Key componenent separator is a semicolon).
YECH.
I can see y'all are already leaning away from this direction, but I
thought
I'd still bring them up as ideas:
-> The nameless root namespace is an easy-to-get-to parrot or
interpreter global, so there's no need to have a separate interface
to access the global namespace vs. accessing a namespace in a PMC
register.
(Though interp-is-a-namespace is cute. Maybe too cute, if namespaces
are subclassable.)
-> Namespaces have methods/ops to look up a contained symbol (just
one level), where any string is a valid symbol. (And there's the
option of not recursing into parent namespaces; i.e., looking only
at "declared" members.)
-> Namespaces also have methods to traverse a path of symbols, where
all but the last symbol in the path must itself be a namespace.
Symbol paths are mangled using a DEAD SIMPLE, absolutely canonical
encoding, with debug-friendly printable ASCII escapes. e.g.:
# Example only:
# '.' is path delimiter and '%' is escape char
# Using '\' would induce LTS in IMCC & C.
foreach (@path) {
s/\%/\%\%/g;
s/\./\%\./g;
}
$path = join(".", @path);
So unless you use a '.' or '%' in your symbol, it won't be mangled
at all, and if it started out printable ASCII, it'll stay that way.
And if you do use one of those reserved characters, the mangled form
won't be too terribly surprising.
This does presume that symbols must be in a charset with '.' and
'%'. My heart bleeds for those that aren't.
Bad Thought: If the empty symbol were prohibited (or ignored) in paths,
the delimiter . could be its own escape character, e.g.:
["float";"1.0"] could be float.1..0.
While a strawman symbol path lookup could be implemented in terms of
single-level symbol lookup, smarter namespace implementations might
optimize away the array (multikey) and extra strings. And this doesn't
require any massive restructuring of IMCC or PIR. (Unless you want them
to just do the mangling internally, rather than storing that ["", "",
""]
as an array constant. But why bother? ".." is shorter than ["", "", ""],
and doesn't suggest to a compiler author's mind "keep a struct { char**;
char*; } around for each symbol reference.")
This would make Dan's example into:
find_global P1, "global.namespace.hierarchy.thingname"
shorthand for:
get_globals Py
find_sym P1, Py, "global.namespace.hierarchy.thingname"
and functionally equivalent to the wildly pedantic:
get_globals Py
find_onesym Py, Py, "global"
find_onesym Py, Py, "namespace"
find_onesym Py, Py, "hierarchy"
find_onesym P1, Py, "thingname"
Spelling aside, anyhow. (e.g., where find_onesym yada might be spelled
set yada[].)
--
Gordon Henriksen
IT Manager
ICLUBcentral Inc.
gor...@iclub.com
>> What about:
>>
>> getinterp P2
>> set P1, P2['global';'namespace';'hierarchy';'thingname']
> What if global.namespace happens to be autoloaded or otherwise magic?
> Will the get_keyed break down and do something equivalent to this?
> getinterp P2
> set P1, P2['global';'namespace']
> set P1, P1['hierarchy';'thingname']
> Meaning the construction of an extra multikey? Yech, maybe.
That's absolutely the same. Multikeys work on the nested aggregates, at
least if you are considering current PerlHash implementation. But -
AFAIK - nothing was said yet, how the namespace hierarchy is done
internally. It could be a HoHoH or a concatenated string key of an one
level flat hash - the value being the symbol name.
>> Constructing a multy-key by hand isn't that simple (or would need
>> hacking imcc) (and Key componenent separator is a semicolon).
> -> The nameless root namespace is an easy-to-get-to parrot or
> interpreter global, so there's no need to have a separate interface
> to access the global namespace vs. accessing a namespace in a PMC
> register.
set P1, P2["the_global"] # P2 is still the interpreter
So there is no special case.
> (Though interp-is-a-namespace is cute. Maybe too cute, if namespaces
> are subclassable.)
Different interpreters (threads), different global namespaces ...
> -> Namespaces have methods/ops to look up a contained symbol (just
> one level), where any string is a valid symbol. (And there's the
> option of not recursing into parent namespaces; i.e., looking only
> at "declared" members.)
Considering Melvins f'up and that, it might be better, to move that
functionality into a NameSpace PMC. That can be overridden and still
does the right thing for the standard case.
> -> Namespaces also have methods to traverse a path of symbols
That seconds above statement a lot.
> get_globals Py
Ah the get me a namespace PMC - yep.
leo
Well... I was hoping for a single option, so that everyone
interoperates properly. I *know* that folks writing perl programs are
going to want to stick methods into the ruby and python packages that
they import. (And the feeling, I expect, is mutual :)
It won't be optimal for everyone, but the needs of the dynamic
languages are pretty similar so if we can satisfy them without being
particularly onerous to the rest of the languages (most of whom won't
make much use of namespaces at runtime anyway) I'll be happy.