Mutating primordials and versioning

William Edney bedney at technicalpursuit.com
Tue Jan 19 11:15:45 PST 2010


Mike -

Responses below:

On Jan 19, 2010, at 12:16 PM, Mike Samuel wrote:

> 2010/1/19 William Edney <bedney at technicalpursuit.com>:
>> Mike -
>> 
>> Here's some specific answers to these questions. I've also been advised to read the old E4 versioning proposal and maybe try to get this issue on the Jan 28-29 agenda. Any tips on that process would be helpful.
>> 
>> 1. We've done both modification and replacement of prototypes in the past, although we've backed off of replacement of prototypes in the past few years, as the implementations (well, JScript) supported it very poorly. Obviously the modification of prototypes (and 'static' properties of the core 8 constructors) is really what I'm arguing for below. The scenario of replacement of prototypes is mostly around 'exporting' our 'enhanced' versions of these constructors to other 'global' contexts (i.e. windows in a browser). Unfortunately, due to the E3 spec not being prescriptive enough around object literals, the JScript engine does strange things with the prototype chain for objects created using object literals such that they follow a different chain than objects created with 'new'.
>> 
>> 2. The fact that an API-incompatible method named 'create' was placed on Object was what broke our 'create' call.
> 
> Ok, so normal namespace collisions broke your create call.
> If your framework were used along with a JS library that
> monkey-patched primordials, you would expect such collisions.
> 

Yes.

> How do two libraries that both monkey-patch coexist?
> Or do big frameworks not need to coexist with other code that uses
> similar tactics?
> 

They don't in the current world. About the best we get these days is folks putting everything inside of a closure, which hides non-globals, but that obviously doesn't solve the monkey patch problem of existing global objects, it just prevents further pollution of the global namespace.

I'm not opposed to fixing this problem via a construct like 'modules' or 'packages' or whatever. I get concerned when I see folks inching closer towards not allowing things that were previously allowed ('arguments.callee' springs to mind). And when I see folks talk about freezing primordials, potentially globally throughout the engine, that gives me cause for great concern.

>> 3. By versioning, I mean a mechanism whereby any new features of the language beyond ES5 (originally the intent was ES3, but now since that language is indistinguishable from ES5, there's no use) are explicitly opted-in. Therefore, the 'baseline' is ES5 and new features are only enabled if a statement such as "use ESHarmony" or "use ES6" or whatever the committee comes up with (much like 'strict mode' must be strictly opt-ed into). Originally, 1.5 years ago, I had proposed on this list to use the older syntax of specifying the JS version in the <script language="JavaScript1.5"/>, etc. but there were concerns about using that approach in ECMAScript engines that were not hosted in a browser. So that's fine - a 'language level' switch would be ok. As I stated above, I'll reread the old E4 versioning proposal to see if there are potential answers there.
> 
> So this language level versioning would differ, like strictness, from
> script block to script block, and from function body to function body?
> 
> So if ES5 had included a versioning scheme as you describe, then
> Object.create would be visible in the first script block but not the
> second?
>   <script>"use es5"; alert(typeof Object.create) // -> function</script>
>   <script>alert(typeof Object.create) // -> undefined </script>
> 

Yes, that would have been the preferred behavior. It's too late for ES5, but that's ok as we've successfully dodged the problem this time. ES5 was a relatively minor set of changes to ES. ES-Harmony has the potential to be a much greater set of changes.


I'm quite sure that by this point Brendan is convinced that a number of us out here suffer from "Stockholm Syndrome" with ES3. That's not really the case, although it may seem so :-).

For the record, here was our wish list for ES3 back in 2000:

- Getter / setter support

- Choosing whether or not to make a property enumerable

- Remove support for automatic semicolon insertion (or you suffer from what one of my team has affectionately referred to as 'autosemicolonoscopy' ;-) - yes, that can be as painful as it sounds)

- A 'doesNotUnderstand' (i.e. 'noSuchMethod') hook (i.e. catchall setters/getters)

- null / undefined as Real Objects, preferably singleton instances of the Null and Undefined type (this'll never happen for reasons previously discussed on this list, but it was a real wish at the time. Being able to use a catchall getter when a variable is null or undefined would serve the use case that this item was meant to solve).

- Weak references


With ECMA e5, we got the first 2 of those 6, so (to paraphrase Mr. Loaf), "2 outta 6 ain't bad" :-).

Cheers,

- Bill

> 
>> 4. Obviously, things like 'defineProperty' help the situation somewhat, although its of limited value if the system can still find and invoke/access the property. I'm not concerned with making the property visible/enumerable. I'm concerned with the engine finding it and invoking it. The module proposal has more usefulness here.
>> 
>> 5. Opt-in security extensions don't bother me all that much, since I never plan to opt-in, just like 'strict mode' in ES5.
>> 
>> 6. Obviously, this is what has been discussed on the list for the past week or so. I'm still thinking through the implications here. I can imagine a scenario where our framework is 'one big module', so as long as there are no code size limitations here, I'm somewhat noncommittal. Need to review and think more here.
>> 
>> Thanks for your response.
>> 
>> Cheers,
>> 
>> - Bill
>> 
>> On Jan 18, 2010, at 9:49 PM, Mike Samuel wrote:
>> 
>>> Do you both modify prototypes, e.g.
>>>  Array.prototype.indexOf = ...;
>>> and replace prototypes,
>>>  Date = ...;
>>> ?
>>> 
>>> Which ES5 changes in particular broke your create calls?
>>> 
>>> What do you mean by versioning?
>>> 
>>> Let me also list a few trends, and get your thoughts on them individually:
>>> (1) Features that allow better patching, such as Object.defineProperty
>>> which allows patchers to define non-enumerable extensions.
>>> 
>>> (2) Opt-in security extensions that assume frozen primordials.
>>> 
>>> (3) Module schemes that might allow a module to be unaffected by other
>>> modules' extension.
>>> 
>>> 
>>> 2010/1/18 William Edney <bedney at technicalpursuit.com>:
>>>> All -
>>>> 
>>>> I've been lurking here, just to make sure you all were talking about what I thought you were talking about (didn't know the context under which the term 'primordials' was being used, but I understand it now to be built-in objects, such as Array, Boolean, Function etc. - if this isn't the case, please correct me and ignore the rest of this post).
>>>> 
>>>> As co-authors and maintainers of a rather large framework, we've been 'mutating primordials' for over 10 years and have every intention to continue doing so. We do this for 2 main reasons, both of which drive right to the core of our framework:
>>>> 
>>>> Polymorphism: Being able to retrofit an API onto the built-ins is crucial. JavaScript is a very dynamic language (maybe that rubs some of the people here the wrong way, but there it is - sorry), and being able to treat all objects in a true polymorphic fashion is one of the most powerful aspects of dynamism. Objective-C recognized this need long ago and allowed for "Categories", which allowed existing types to be extended (even compiled code).
>>>> 
>>>> Bugs: I know that no one here has ever run into a browser bug (tongue firmly in cheek), but the ability to monkey-patch a buggy implementation of a browser native method to fix a bug has allowed us to maintain a consistent API with methods that have already been standardized, but are broken in a particular implementation. For instance, older versions of IE have a problem with negative indexes on methods like slice(). We were able to 'repair' those by monkey-patching. Simple and elegant and, most importantly, no deviation from the well established standard. Bug-free JS implementations exist in the same world as the Tooth Fairy and Sandy Claws.
>>>> 
>>>> There seems to be an obsession on this group to try to turn the clock back 10 years and change some of the choices made when ECMAScript ed. 3 was standardized in late 1999. Well, as Austin Powers would say, "That train has sailed". We're gonna be living with E3 from now until the end of time (or until the Web becomes something else entirely). Too much code has been written and, as I've stated on this list before, much of it is behind corporate firewalls, etc. that will never be known, never be 'surveyed', never be 'measured' - and to which the author of said code wandered off 5 years ago.
>>>> 
>>>> We will continue to express our grave concern, as we did 1.5 years ago on this very list, that without a versioning mechanism in place and a requirement for engines to continue to support older language semantics (and requiring explicit opt-in for the 'new' language - think "use Harmony" or whatever) we're on the fast train to hell here. The assumption that new method names can be added to existing objects and that's "ok, because its additive and so no one would've used that" is just wrong. Even HTML has standards mode vs. compatibility mode. Anything else would have broken the web. The same requirement exists for JavaScript.
>>>> 
>>>> What we know for sure, regardless of agreement on best practices or coding or lack thereof, is that the work done on ES5 broke our framework.  We used 'create' as a wrapper around our own alloc/init sequence and now, thanks to ES5, we've had to rebuild every single type and all calls to our constructors. If there is no plan for a versioning model moving forward, we're anticipating the worst from Harmony.
>>>> 
>>>> Cheers,
>>>> 
>>>> - Bill
>>>> 
>>>> "The beauty of creating a language, or any tool for that matter, is that people take it and use it in ways you could never imagine...unless of course you go to the trouble to ensure they can't possibly do anything outside of the box you currently imagine."
>>>> _______________________________________________
>>>> es-discuss mailing list
>>>> es-discuss at mozilla.org
>>>> https://mail.mozilla.org/listinfo/es-discuss
>>>> 
>> 
>> 



More information about the es-discuss mailing list