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