Namespaces as Sugar (was: complexity tax)
Graydon Hoare
graydon at mozilla.com
Tue May 27 14:02:56 PDT 2008
Brendan Eich wrote:
> I want to say thanks for making this proposal (open namespace search
> only for lexical references). It leaves most of the use-cases I cited
> intact. Well done, good compromise (not complete evisceration of
> property qualifiers, or dismissal of unqualified import).
Likewise. It's an important distinction to have made and I'm glad you
made it. Gives the discussion clearer texture. I'm mostly sitting out
the argument here, but there are good points being raised and it's good
to explore around them.
> The helper/informative usage in the RI does open those namespaces,
> and intrinsic works only as a cross-cutting namespace that can be
> opened via pragma. So we should focus on these, if only to agree to
> disagree on the importance of the former, argue for hardcoding the
> latter via a separate early-binding pragma, and so forth.
Deploying a 'use namespace intrinsic' pragma does more than give
early-binding opportunity to ES3 code (which, realistically, you'll need
to do some extra type-level work to fully resolve). More importantly,
it grants a one-switch migration point from mutable prototype slots
(compatible) to fixed class slots (predictable). IOW it's a semantic,
program-integrity feature.
This is IMO the more serious issue we're missing in the discussion. I
want to elaborate on it here for the sake of clarity. What we have now
is the ability to take ES3 code such as:
var x = "hello";
x.split("e");
and, by putting "use namespace intrinsic" at the front of it, make a
rather drastic upgrade in its "integrity" (by at least some measure, see
below). The call x.split() changes from a prototype-resolved lookup on a
dynamic property (likely to resolve at String.prototype.public::split())
to a lookup that stops with the fixture intrinsic::split() defined on
the class __ES4__::string, that x is an instance of. This fixture has
the following "improved" nature:
- It has fixed semantics! the user knows what they're getting and
no 3rd party code twiddling String.prototype will change it.
- It so happens that we "improved" the semantics by sticking dynamic
typechecks on the boundaries of intrinsic::split(), so you'll get
more type-error checking.
- It can be cached and reused w/o worrying about cache invalidation
due to mutation of String.prototype. The implementation can get
adequate performance without having to play as-subtle tricks.
Moreover, a single "use namespace intrinsic" will upgrade an *entire*
compilation unit at a time (or a limited scope within one) using this
technique, without having to go through and modify every x.split() to
x.improved_split().
I'd be curious to hear if there's another well-developed way to provide
this sort of thing. I guess it could be done by some sort of pragma that
is specific to the standard library, but the current technique will work
for helping other library authors (dojo / yui / etc.) provide an
integrity-upgrading facility for *their* users too. It'd be nice to make
this technique usable to all.
(The same technique can be used to e.g. provide debugging-heavy variants
of methods, or side-by-side usable "new" versions in the presence of
"old" versions, that you toggle by opening namespaces. I have less
experience with this, but IIRC it was part of Waldemar's the initial
motivation.)
-Graydon
More information about the Es4-discuss
mailing list