Re: Array.prototype change (Was: @@toStringTag spoofing for null and undefined)
On 19 Feb 2015, at 21:09, Andrea Giammarchi andrea.giammar...@gmail.com wrote: if we'd like to have Array.empty, Function.empty, String.empty and friends, what's wrong with having these as we always had already: as prototypes? I find it more self-explanatory. Here, prototypes are taking on a role that they don’t usually have: they are empty instances of “their” constructors. A much more important reason, though, is that you want to freeze everything `*.empty`, because these instances will get shared and then mutability is a problem. However, you can’t freeze `Array.prototype`. Greetings, Axel -- Dr. Axel Rauschmayer a...@rauschma.de rauschma.de ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Array.prototype change (Was: @@toStringTag spoofing for null and undefined)
On Thu, Feb 19, 2015 at 12:14 PM, Axel Rauschmayer a...@rauschma.de wrote: However, you can’t freeze `Array.prototype` We do. -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Array.prototype change (Was: @@toStringTag spoofing for null and undefined)
yep, not only you can, but also consider if that was frozen, half of ES5 wouldn't have existed. You want to exted it? Thanks to ES5 just go for it! You want to be obtrusive or that secure? Freeze it. Does this affect the ability to use Array.prototype as empty array? Not at all, it does not change a single bit of empty purpose. On Thu, Feb 19, 2015 at 8:18 PM, Mark Miller erig...@gmail.com wrote: On Thu, Feb 19, 2015 at 12:14 PM, Axel Rauschmayer a...@rauschma.de wrote: However, you can’t freeze `Array.prototype` We do. -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Array.prototype change (Was: @@toStringTag spoofing for null and undefined)
P.S. yes, the semantic already frozen purpose of an empty property though, I agree that'd be cool On Thu, Feb 19, 2015 at 8:21 PM, Andrea Giammarchi andrea.giammar...@gmail.com wrote: yep, not only you can, but also consider if that was frozen, half of ES5 wouldn't have existed. You want to exted it? Thanks to ES5 just go for it! You want to be obtrusive or that secure? Freeze it. Does this affect the ability to use Array.prototype as empty array? Not at all, it does not change a single bit of empty purpose. On Thu, Feb 19, 2015 at 8:18 PM, Mark Miller erig...@gmail.com wrote: On Thu, Feb 19, 2015 at 12:14 PM, Axel Rauschmayer a...@rauschma.de wrote: However, you can’t freeze `Array.prototype` We do. -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Array.prototype change (Was: @@toStringTag spoofing for null and undefined)
Personally I'd love to see `Array.empty`, `Function.empty`, `Map.empty`, `String.empty`, etc as nonconfigurable nonwritable frozen/sealed/extensionsPrevented available by default - that might provide the (polyfillable) use case Kyle is currently describing, and might provide a path to making builtins’ prototypes not be instances of the builtin, without breaking code. That said, I also agree with Kyle that this is something that will certainly break some code. It’s already been decided that `Function.prototype` remains a function - if `Array.prototype` remains an array, are there any other builtins that anybody (Kyle, or otherwise) sees as problematic to continue with the breaking change (ie, continue with making them normal objects)? Kyle, if there was `Array.empty` and `Function.empty`, which would both be polyfillable, would you find those sufficient replacements for your current usages of `Function.prototype` and `Array.prototype`? (my thought process here is, can we provide for this use case without also needing to keep the magic behavior of builtin's prototypes) On Thu, Feb 19, 2015 at 11:05 AM, Kyle Simpson get...@gmail.com wrote: I'm not writing to start or join a debate on the merits of using `Function.prototype` and `Array.prototype` in the aforementioned ways. I'm writing to confirm that they are in fact used, not just theoretically made up. I have been writing about and teaching for several years usage of `Function.prototype` as a (convenience) no-op empty function and `Array.prototype` as a (convenience) default empty array (not to be mutated, obviously). The most recent case of me publicly talking about these techniques is in my recently published book YDKJS: Types Grammar: https://github.com/getify/You-Dont-Know-JS/blob/master/types%20%20grammar/ch3.md#prototypes-as-defaults While I can't go back now and get at all those old code bases that I either consulted on or taught on in workshops, and though that code may unfortunately not show up in GitHub searches, I assure you that such code exists. Moreover, I have right now a local (non-GH, for certain reasons) fork of Esprima that I've been hacking on for about a year, and atm I have 34 occurrences in it of using `Array.prototype` as a shared empty default array for starting iterations, etc. There is no debate of if it will break code, but rather if it's ok to break code since the numbers are sufficiently low. Please don't pretend this is just academic contrarianism at play. Furthermore, I would posit that whatever evidence was used to roll back the `Function.prototype` change -- that is, people who use it as an empty no-op function -- would be the symmetric evidence, and the nearly identical mindset, to using `Array.prototype` as a default empty array. That is, I think there's at least a decent amount of correlation/overlap there. However, I'm not seeing or finding the contra-argument of why it's so much better to justify making this breaking change, nor why it makes more sense to break `Array.prototype` usage but not `Function.prototype` usage. --Kyle ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Array.prototype change (Was: @@toStringTag spoofing for null and undefined)
are there any other builtins that anybody (Kyle, or otherwise) sees as problematic to continue with the breaking change As that book chapter mentions, the only other one I've ever used is RegExp.prototype (being the default empty match /(?:)/ regular expression). I have used that only once in my recollection, though I've certainly taught it so I don't know if others ever did. I would *like* it to keep working, but it's not a sword I'd die on. AWB has suggested on twitter a patch to test() and exec() that could hack around that case while letting the ES6 change go through. Kyle, if there was Array.empty and Function.empty, which would both be polyfillable, would you find those sufficient replacements for your current usages of Function.prototype and Array.prototype? Yes, a long time back I proposed (not on here, but informally) that there should be just such a thing Function.empty, but basically just settled back into using `Function.prototype` since it was already there (and I didn't conceive of it ever changing). The points in favor of either the prototype exotic or an empty stand-in are: 1) convenience 2) possible performance aide to engines. can we provide for this use case I certainly wasn't coming to this list to propose new features for ES6, as late as it is. I only just late last nite found out about this change, and was just hoping it wasn't too late to abort the change. But if the fix/compromise is empty stand-ins that give a polyfill path to migration, I'd be OK with that. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Array.prototype change (Was: @@toStringTag spoofing for null and undefined)
if we'd like to have Array.empty, Function.empty, String.empty and friends, what's wrong with having these as we always had already: as prototypes? I see just moving and duplicating gotchas, instead of keeping in a well known behavior. This exotic problem ... I never really understood it, I blindly trusted it was needed to avoid that kind of invisible Empty constructor Function.prototype inherits from ... which is the Empty we all look for too. Oh well, chicken/eggs inheritance is hard I guess :D Just kidding, if not for good reasons, throw away 60% of Annex E ( also the Array thingy is duplicated in there, it's at the bottom and before too in the HTML version ... just saying ) On Thu, Feb 19, 2015 at 7:33 PM, Kyle Simpson get...@gmail.com wrote: are there any other builtins that anybody (Kyle, or otherwise) sees as problematic to continue with the breaking change As that book chapter mentions, the only other one I've ever used is RegExp.prototype (being the default empty match /(?:)/ regular expression). I have used that only once in my recollection, though I've certainly taught it so I don't know if others ever did. I would *like* it to keep working, but it's not a sword I'd die on. AWB has suggested on twitter a patch to test() and exec() that could hack around that case while letting the ES6 change go through. Kyle, if there was Array.empty and Function.empty, which would both be polyfillable, would you find those sufficient replacements for your current usages of Function.prototype and Array.prototype? Yes, a long time back I proposed (not on here, but informally) that there should be just such a thing Function.empty, but basically just settled back into using `Function.prototype` since it was already there (and I didn't conceive of it ever changing). The points in favor of either the prototype exotic or an empty stand-in are: 1) convenience 2) possible performance aide to engines. can we provide for this use case I certainly wasn't coming to this list to propose new features for ES6, as late as it is. I only just late last nite found out about this change, and was just hoping it wasn't too late to abort the change. But if the fix/compromise is empty stand-ins that give a polyfill path to migration, I'd be OK with that. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Array.prototype change (Was: @@toStringTag spoofing for null and undefined)
you want to freeze everything *.empty I don't think most of those *need* to be frozen, per se, since they're already immutable: `Function`, `String`, `Number`, `Boolean`, `RegExp`, … all immutable themselves. `Array.prototype` is however mutable (`Array.prototype.push(1,2,3)`), so freezing it from mutation is an extra step of caution you might want to take. FWIW, I've used `Array.prototype` as an empty array in quite a few cases, and never actually run across one where it got mutated. *That* part is currently just theory, I think. you can’t freeze Array.prototype. I think what he meant was, freezing Array.prototype would both prevent it from being mutated, but also prevent it from being extended (Array.prototype.superCool = ..). That seems, to me anyway, as a negative. So in support of Axel's argument, an `Array.empty` *could* definitely be frozen, if it were separate, without affecting `Array.prototype` extensibility. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Array.prototype change (Was: @@toStringTag spoofing for null and undefined)
I just remembered that I also do a sort of `Object.empty` in my own code somewhat frequently, as can be seen here for example: https://github.com/getify/asynquence/blob/master/asq.src.js#L826 Declaring an empty object: `var ø = Object.create(null)`, and then using that `ø` as a sort of global DMZ object that I use for any place where I need a throw-away `this` binding, like `apply(..)`, `bind(..)`, etc. I also wrote about that technique in YDKJS: this Object Prototypes, here: https://github.com/getify/You-Dont-Know-JS/blob/master/this%20%20object%20prototypes/ch2.md#safer-this So, having an `Object.empty` might be nice in place of `ø`. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Array.prototype change (Was: @@toStringTag spoofing for null and undefined)
On Feb 19, 2015, at 12:09 PM, Andrea Giammarchi wrote: if we'd like to have Array.empty, Function.empty, String.empty and friends, what's wrong with having these as we always had already: as prototypes? Just to keep things focused. *.empty is not something that is on the table for ES6. It would have to go into the ES7 track. Today's issue, is 1) do we need to revert Array.prototype to being an Array exotic object (I think we do) 2) do we need to revert RegExp.prototype to being a RegExp instance.(with initialize RegExp internal slots) (maybe not, and alternatively I have very minor tweaks to the exec and test methods that will maintain the most likely such legacy RegExp.prototype uses without needing those internal slots) allen ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Array.prototype change (Was: @@toStringTag spoofing for null and undefined)
Is there a good reason behind making prototypes ordinary objects? On the margin - I would assume Array.empty to be static method to clean array. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Array.prototype change (Was: @@toStringTag spoofing for null and undefined)
On Thu, Feb 19, 2015 at 12:56 PM, Allen Wirfs-Brock al...@wirfs-brock.com wrote: On Feb 19, 2015, at 12:09 PM, Andrea Giammarchi wrote: if we'd like to have Array.empty, Function.empty, String.empty and friends, what's wrong with having these as we always had already: as prototypes? Just to keep things focused. *.empty is not something that is on the table for ES6. It would have to go into the ES7 track. Today's issue, is 1) do we need to revert Array.prototype to being an Array exotic object (I think we do) 2) do we need to revert RegExp.prototype to being a RegExp instance.(with initialize RegExp internal slots) (maybe not, and alternatively I have very minor tweaks to the exec and test methods that will maintain the most likely such legacy RegExp.prototype uses without needing those internal slots) RegExp.prototype.compile https://people.mozilla.org/~jorendorff/es6-draft.html#sec-regexp.prototype.compile is a visible side effect that survives Object.freeze. It is only not a global communications channel because there is no longer a primordial RegExp instance. So we cannot consider making RegExp.prototype a RegExp unless Object.freeze must disable RegExp.prototype.compile on RegExp instances. -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Array.prototype change (Was: @@toStringTag spoofing for null and undefined)
Does it not make sense anyways for Object.freeze on a RegExp instance to prohibit https://people.mozilla.org/~jorendorff/es6-draft.html#sec-regexpinitialize from being called? `var regex = Object.freeze(/a/g); regex.compile('b', 'i');` should throw imo. On Thu, Feb 19, 2015 at 1:13 PM, Mark S. Miller erig...@google.com wrote: On Thu, Feb 19, 2015 at 12:56 PM, Allen Wirfs-Brock al...@wirfs-brock.com wrote: On Feb 19, 2015, at 12:09 PM, Andrea Giammarchi wrote: if we'd like to have Array.empty, Function.empty, String.empty and friends, what's wrong with having these as we always had already: as prototypes? Just to keep things focused. *.empty is not something that is on the table for ES6. It would have to go into the ES7 track. Today's issue, is 1) do we need to revert Array.prototype to being an Array exotic object (I think we do) 2) do we need to revert RegExp.prototype to being a RegExp instance.(with initialize RegExp internal slots) (maybe not, and alternatively I have very minor tweaks to the exec and test methods that will maintain the most likely such legacy RegExp.prototype uses without needing those internal slots) RegExp.prototype.compile https://people.mozilla.org/~jorendorff/es6-draft.html#sec-regexp.prototype.compile is a visible side effect that survives Object.freeze. It is only not a global communications channel because there is no longer a primordial RegExp instance. So we cannot consider making RegExp.prototype a RegExp unless Object.freeze must disable RegExp.prototype.compile on RegExp instances. -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Re-export default?
I hear the verdict but not any substantial rationale; why is it “confusing”?’ @caridy regarding your examples for JS2016 wouldn’t this export default from “foo”; just re-export one module’s default as another module’s default, right? In my use-case, in order to map n-number of default-export functions to named-export functions I would have to do this ad-infinitum: export {default as a} from “./a” export {default as b} from “./b” export {default as c} from “./c” export {default as d} from “./d” export {default as e} from “./e” ... I’m not saying my syntax for my use-case is amazing, I’m just working within the confines of JS. Other languages such as Go have their own interesting approaches to modules that we cannot really consider in JS due to needing a high level of semantic mapping to legacy CJS Modules. On Feb 19, 2015, at 1:31 AM, caridy car...@gmail.com wrote: Yes, that syntax is incorrect and confusing. There was an overside from our end to provide a way to re-export only the default export from another module, and this is something we plan to revisit for ES7/2016. Probably something like this: `export default from “foo”;` this is just sugar for: `export {default} from “foo”;` which is perfectly supported in ES6, including the ability to rename it: `export {default as something} from “foo”;` /caridy On Feb 18, 2015, at 9:08 PM, Jason Kuhrt jasonku...@me.com mailto:jasonku...@me.com wrote: I was prompted to bring this issue to es-discuss. https://github.com/babel/babel/issues/826 https://github.com/babel/babel/issues/826 It is my confusion about why this syntax does not work: export foo from ‘./foo' More details are in the issue but the gist is that sometimes it is actually quite handy to export just defaults internally and then re-export thing as a “bag” of named exports. This is not currently “easy”. I assume this was discussed/considered. I’d be curious what the rationale was. Thanks! Jason ___ es-discuss mailing list es-discuss@mozilla.org mailto:es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Object.freeze(Object.prototype) VS reality
On Feb 19, 2015, at 9:23 AM, David Bruant bruan...@gmail.com wrote: Hi, Half a million times the following meta-exchange happened on es-discuss: - if an attacker modifies Object.prototype, then you're doomed in all sorts of ways - Don't let anyone modify it. Just do Object.freeze(Object.prototype)! Depending on your goals you could use Object.seal. It prevents new properties from being added, but allows you to modify existing properties. From there you could selectively re-define the existing properties with Object.defineProperty and set writable:false. Although I wouldn’t trust the browser anyway and verify everything server side. Luke ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Object.freeze(Object.prototype) VS reality
this, and the fact descriptors suffer inheritance which for 3 boolean properties or a method are absolutely not helpful and make the env doomed by `Object.prototype.writable = true` shenanigans. Umm, those solutions are in opposition. If you seal-freeze-scotch-tape Object.prototype up, no-one's going to add `get`s, `set`s and `writable`s to it. Taking inheritance into account in defineProperty won’t then be a problem. A. On Feb 19, 2015, at 19:58, Andrea Giammarchi andrea.giammar...@gmail.com wrote: this, and the fact descriptors suffer inheritance which for 3 boolean properties or a method are absolutely not helpful and make the env doomed by `Object.prototype.writable = true` shenanigans. Yes, I'd personally +1 all these fixes that made these ES5 features not the easiest one to play with On Thu, Feb 19, 2015 at 5:41 PM, Mark S. Miller erig...@google.com wrote: On Thu, Feb 19, 2015 at 9:23 AM, David Bruant bruan...@gmail.com wrote: Hi, Half a million times the following meta-exchange happened on es-discuss: - if an attacker modifies Object.prototype, then you're doomed in all sorts of ways - Don't let anyone modify it. Just do Object.freeze(Object.prototype)! I've done it on client-side projects with reasonable success. I've just tried on a Node project and lots of dependencies started throwing errors. (I imagine the difference is that in Node, it's easy to create projects with a big tree of dependencies which I haven't done too much on the client side). I tracked down a few of these errors and they all seem to relate to the override mistake [1]. * In jsdom [2], trying to add a constructor property to an object fails because Object.prototype.constructor is configurable: false, writable: false * in tough-cookie [3] (which is a dependency of the popular 'request' module), trying to set Cookie.prototype.toString fails because Object.prototype.toString is configurable: false, writable: false Arguably, they could use Object.defineProperty, but they won't because it's less natural and it'd be absurd to try to fix npm. The Cookie.prototype.toString case is interesting. Of all the methods being added, only toString causes a problem. Using Object.defineProperty for this one would be an awkward inconsistency. So, we're in a state where no module needs to modify Object.prototype, but I cannot freeze it because the override mistake makes throw any script that tries to set a toString property to an object. Because of the override mistake, either I have to let Object.prototype mutable (depite no module needing it to be mutable) or freeze it first hand and not use popular modules like jsdom or request. It's obviously possible to replace all built-in props by accessors [4], of course, but this is a bit ridiculous. It is indeed ridiculous. Not fixing this in the ES5 timeframe was my single biggest failure and disappointment as a member of TC39. For reference, Caja's implementation of the technique described in [4] is at https://code.google.com/p/google-caja/source/browse/trunk/src/com/google/caja/ses/repairES5.js#278 As it states, our term for freezing an object so that it does not provoke this problem is tamper proofing. Can the override mistake be fixed? I imagine no web compat issues would occur since this change is about throwing less errors. There was a time when some of the browsers did not suffer from the override mistake, and in so doing, were technically out of conformance with the ES5 spec. During this window, it was clearly still web compatible to fix the override mistake. It was during this window that I raised the issue and argued that it be fixed. I brought this up in meetings several times and never made any progress. Once all browsers suffered equally from the override mistake, it was no longer *clearly* web compatible to fix it, so I gave up and focussed on other things instead. However, I agree with your suspicion that it actually would still be web compatible to fix this. Unfortunately, the only way to find out at this point is for a browser to try deploying without the override mistake. I don't have much hope. Instead, I suggest you promote tamper proofing to those audiences to which you currently promote freezing. Though the need for it is indeed ridiculous, it actually works rather well. We've been using it successfully for many years now. David [1] http://wiki.ecmascript.org/doku.php?id=strawman:fixing_override_mistake [2] https://github.com/tmpvar/jsdom/blob/6c5fe5be8cd01e0b4e91fa96d025341aff1db291/lib/jsdom/utils.js#L65-L95 [3] https://github.com/goinstant/tough-cookie/blob/c66bebadd634f4ff5d8a06519f9e0e4744986ab8/lib/cookie.js#L694 [4] https://github.com/rwaldron/tc39-notes/blob/c61f48cea5f2339a1ec65ca89827c8cff170779b/es6/2012-07/july-25.md#fix-override-mistake-aka-the-can-put-check ___
Re: Object.freeze(Object.prototype) VS reality
On Thu, Feb 19, 2015 at 10:14 AM, Andrea Giammarchi andrea.giammar...@gmail.com wrote: uhm ... have I forgotten a `delete` or should I have set `{value: Object.prototype[name], writable: false, configurable: false}` instead ? (enumerable should be preserved as false too) Either would work, but I would do the second. The first technique is not idempotent but the second is. Deleting will fail a second time, but setting a property to its current settings works fine. Yep, actually you got me there, this is a light side effect since usually nobody redefines the `Object.prototype`, but good to know, I could have fallen hard there. Cheers On Thu, Feb 19, 2015 at 6:06 PM, Mark S. Miller erig...@google.com wrote: On Thu, Feb 19, 2015 at 9:54 AM, Andrea Giammarchi andrea.giammar...@gmail.com wrote: Just as workaround, if you really need that much to freeze the `Object.prototype`, you could: ```js Object .getOwnPropertyNames(Object.prototype) .filter((name) = !/^constructor|toString|valueIOf$/.test(name)) .forEach((name) = Object.defineProperty( Object.prototype, name, {value: Object.prototype[name]} )) Your defineProperty call above has no effect. When doing a defineProperty on an existing property, recall that omitting attributes means that the setting of these attributes should not be changed. Omitted attributes only default to false when the property does not already exist. Interesting that I've seen this bug several times now, by several different authors. Apparently, it is an unanticipated footgun in the ES5 reflection API. ; Object.preventExtensions(Object.prototype); ``` You can eventually fix those 3 properties somehow via accessors. Not ideal, but it should hopefully make your project work (at least) Best Regards On Thu, Feb 19, 2015 at 5:23 PM, David Bruant bruan...@gmail.com wrote: Hi, Half a million times the following meta-exchange happened on es-discuss: - if an attacker modifies Object.prototype, then you're doomed in all sorts of ways - Don't let anyone modify it. Just do Object.freeze(Object.prototype)! I've done it on client-side projects with reasonable success. I've just tried on a Node project and lots of dependencies started throwing errors. (I imagine the difference is that in Node, it's easy to create projects with a big tree of dependencies which I haven't done too much on the client side). I tracked down a few of these errors and they all seem to relate to the override mistake [1]. * In jsdom [2], trying to add a constructor property to an object fails because Object.prototype.constructor is configurable: false, writable: false * in tough-cookie [3] (which is a dependency of the popular 'request' module), trying to set Cookie.prototype.toString fails because Object.prototype.toString is configurable: false, writable: false Arguably, they could use Object.defineProperty, but they won't because it's less natural and it'd be absurd to try to fix npm. The Cookie.prototype.toString case is interesting. Of all the methods being added, only toString causes a problem. Using Object.defineProperty for this one would be an awkward inconsistency. So, we're in a state where no module needs to modify Object.prototype, but I cannot freeze it because the override mistake makes throw any script that tries to set a toString property to an object. Because of the override mistake, either I have to let Object.prototype mutable (depite no module needing it to be mutable) or freeze it first hand and not use popular modules like jsdom or request. It's obviously possible to replace all built-in props by accessors [4], of course, but this is a bit ridiculous. Can the override mistake be fixed? I imagine no web compat issues would occur since this change is about throwing less errors. David [1] http://wiki.ecmascript.org/doku.php?id=strawman:fixing_ override_mistake [2] https://github.com/tmpvar/jsdom/blob/6c5fe5be8cd01e0b4e91fa96d02534 1aff1db291/lib/jsdom/utils.js#L65-L95 [3] https://github.com/goinstant/tough-cookie/blob/ c66bebadd634f4ff5d8a06519f9e0e4744986ab8/lib/cookie.js#L694 [4] https://github.com/rwaldron/tc39-notes/blob/ c61f48cea5f2339a1ec65ca89827c8cff170779b/es6/2012-07/july- 25.md#fix-override-mistake-aka-the-can-put-check ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss -- Cheers, --MarkM -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Object.freeze(Object.prototype) VS reality
uhm ... have I forgotten a `delete` or should I have set `{value: Object.prototype[name], writable: false, configurable: false}` instead ? (enumerable should be preserved as false too) Yep, actually you got me there, this is a light side effect since usually nobody redefines the `Object.prototype`, but good to know, I could have fallen hard there. Cheers On Thu, Feb 19, 2015 at 6:06 PM, Mark S. Miller erig...@google.com wrote: On Thu, Feb 19, 2015 at 9:54 AM, Andrea Giammarchi andrea.giammar...@gmail.com wrote: Just as workaround, if you really need that much to freeze the `Object.prototype`, you could: ```js Object .getOwnPropertyNames(Object.prototype) .filter((name) = !/^constructor|toString|valueIOf$/.test(name)) .forEach((name) = Object.defineProperty( Object.prototype, name, {value: Object.prototype[name]} )) Your defineProperty call above has no effect. When doing a defineProperty on an existing property, recall that omitting attributes means that the setting of these attributes should not be changed. Omitted attributes only default to false when the property does not already exist. Interesting that I've seen this bug several times now, by several different authors. Apparently, it is an unanticipated footgun in the ES5 reflection API. ; Object.preventExtensions(Object.prototype); ``` You can eventually fix those 3 properties somehow via accessors. Not ideal, but it should hopefully make your project work (at least) Best Regards On Thu, Feb 19, 2015 at 5:23 PM, David Bruant bruan...@gmail.com wrote: Hi, Half a million times the following meta-exchange happened on es-discuss: - if an attacker modifies Object.prototype, then you're doomed in all sorts of ways - Don't let anyone modify it. Just do Object.freeze(Object.prototype)! I've done it on client-side projects with reasonable success. I've just tried on a Node project and lots of dependencies started throwing errors. (I imagine the difference is that in Node, it's easy to create projects with a big tree of dependencies which I haven't done too much on the client side). I tracked down a few of these errors and they all seem to relate to the override mistake [1]. * In jsdom [2], trying to add a constructor property to an object fails because Object.prototype.constructor is configurable: false, writable: false * in tough-cookie [3] (which is a dependency of the popular 'request' module), trying to set Cookie.prototype.toString fails because Object.prototype.toString is configurable: false, writable: false Arguably, they could use Object.defineProperty, but they won't because it's less natural and it'd be absurd to try to fix npm. The Cookie.prototype.toString case is interesting. Of all the methods being added, only toString causes a problem. Using Object.defineProperty for this one would be an awkward inconsistency. So, we're in a state where no module needs to modify Object.prototype, but I cannot freeze it because the override mistake makes throw any script that tries to set a toString property to an object. Because of the override mistake, either I have to let Object.prototype mutable (depite no module needing it to be mutable) or freeze it first hand and not use popular modules like jsdom or request. It's obviously possible to replace all built-in props by accessors [4], of course, but this is a bit ridiculous. Can the override mistake be fixed? I imagine no web compat issues would occur since this change is about throwing less errors. David [1] http://wiki.ecmascript.org/doku.php?id=strawman:fixing_ override_mistake [2] https://github.com/tmpvar/jsdom/blob/6c5fe5be8cd01e0b4e91fa96d02534 1aff1db291/lib/jsdom/utils.js#L65-L95 [3] https://github.com/goinstant/tough-cookie/blob/ c66bebadd634f4ff5d8a06519f9e0e4744986ab8/lib/cookie.js#L694 [4] https://github.com/rwaldron/tc39-notes/blob/ c61f48cea5f2339a1ec65ca89827c8cff170779b/es6/2012-07/july- 25.md#fix-override-mistake-aka-the-can-put-check ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Object.freeze(Object.prototype) VS reality
Yeah, beside the fact whenever you freeze something, and you create a module, or a library, or whatever, you don't know what you are freezing up. Since priority is arbitrary, if script A sets stuff before script B then you are done. Also, I use Object.prototype without causing any sort of problems/error since years now, nobody complained, but an Object.freeze upfront would screw the library anyway. Trust what you load in and avoid XSS from users as much as you can you have your problem fixed for most of the cases (and the current state of JS) Best Regards On Thu, Feb 19, 2015 at 6:50 PM, Andri Möll an...@dot.ee wrote: this, and the fact descriptors suffer inheritance which for 3 boolean properties or a method are absolutely not helpful and make the env doomed by `Object.prototype.writable = true` shenanigans. Umm, those solutions are in opposition. If you seal-freeze-scotch-tape Object.prototype up, no-one's going to add `get`s, `set`s and `writable`s to it. Taking inheritance into account in defineProperty won’t then be a problem. A. On Feb 19, 2015, at 19:58, Andrea Giammarchi andrea.giammar...@gmail.com wrote: this, and the fact descriptors suffer inheritance which for 3 boolean properties or a method are absolutely not helpful and make the env doomed by `Object.prototype.writable = true` shenanigans. Yes, I'd personally +1 all these fixes that made these ES5 features not the easiest one to play with On Thu, Feb 19, 2015 at 5:41 PM, Mark S. Miller erig...@google.com wrote: On Thu, Feb 19, 2015 at 9:23 AM, David Bruant bruan...@gmail.com wrote: Hi, Half a million times the following meta-exchange happened on es-discuss: - if an attacker modifies Object.prototype, then you're doomed in all sorts of ways - Don't let anyone modify it. Just do Object.freeze(Object.prototype)! I've done it on client-side projects with reasonable success. I've just tried on a Node project and lots of dependencies started throwing errors. (I imagine the difference is that in Node, it's easy to create projects with a big tree of dependencies which I haven't done too much on the client side). I tracked down a few of these errors and they all seem to relate to the override mistake [1]. * In jsdom [2], trying to add a constructor property to an object fails because Object.prototype.constructor is configurable: false, writable: false * in tough-cookie [3] (which is a dependency of the popular 'request' module), trying to set Cookie.prototype.toString fails because Object.prototype.toString is configurable: false, writable: false Arguably, they could use Object.defineProperty, but they won't because it's less natural and it'd be absurd to try to fix npm. The Cookie.prototype.toString case is interesting. Of all the methods being added, only toString causes a problem. Using Object.defineProperty for this one would be an awkward inconsistency. So, we're in a state where no module needs to modify Object.prototype, but I cannot freeze it because the override mistake makes throw any script that tries to set a toString property to an object. Because of the override mistake, either I have to let Object.prototype mutable (depite no module needing it to be mutable) or freeze it first hand and not use popular modules like jsdom or request. It's obviously possible to replace all built-in props by accessors [4], of course, but this is a bit ridiculous. It is indeed ridiculous. Not fixing this in the ES5 timeframe was my single biggest failure and disappointment as a member of TC39. For reference, Caja's implementation of the technique described in [4] is at https://code.google.com/p/google-caja/source/browse/trunk/src/com/google/caja/ses/repairES5.js#278 As it states, our term for freezing an object so that it does not provoke this problem is tamper proofing. Can the override mistake be fixed? I imagine no web compat issues would occur since this change is about throwing less errors. There was a time when some of the browsers did not suffer from the override mistake, and in so doing, were technically out of conformance with the ES5 spec. During this window, it was clearly still web compatible to fix the override mistake. It was during this window that I raised the issue and argued that it be fixed. I brought this up in meetings several times and never made any progress. Once all browsers suffered equally from the override mistake, it was no longer *clearly* web compatible to fix it, so I gave up and focussed on other things instead. However, I agree with your suspicion that it actually would still be web compatible to fix this. Unfortunately, the only way to find out at this point is for a browser to try deploying without the override mistake. I don't have much hope. Instead, I suggest you promote tamper proofing to those audiences to which you currently promote freezing. Though the need for it is indeed ridiculous, it actually
Re: Array.prototype change (Was: @@toStringTag spoofing for null and undefined)
I'm not writing to start or join a debate on the merits of using `Function.prototype` and `Array.prototype` in the aforementioned ways. I'm writing to confirm that they are in fact used, not just theoretically made up. I have been writing about and teaching for several years usage of `Function.prototype` as a (convenience) no-op empty function and `Array.prototype` as a (convenience) default empty array (not to be mutated, obviously). The most recent case of me publicly talking about these techniques is in my recently published book YDKJS: Types Grammar: https://github.com/getify/You-Dont-Know-JS/blob/master/types%20%20grammar/ch3.md#prototypes-as-defaults While I can't go back now and get at all those old code bases that I either consulted on or taught on in workshops, and though that code may unfortunately not show up in GitHub searches, I assure you that such code exists. Moreover, I have right now a local (non-GH, for certain reasons) fork of Esprima that I've been hacking on for about a year, and atm I have 34 occurrences in it of using `Array.prototype` as a shared empty default array for starting iterations, etc. There is no debate of if it will break code, but rather if it's ok to break code since the numbers are sufficiently low. Please don't pretend this is just academic contrarianism at play. Furthermore, I would posit that whatever evidence was used to roll back the `Function.prototype` change -- that is, people who use it as an empty no-op function -- would be the symmetric evidence, and the nearly identical mindset, to using `Array.prototype` as a default empty array. That is, I think there's at least a decent amount of correlation/overlap there. However, I'm not seeing or finding the contra-argument of why it's so much better to justify making this breaking change, nor why it makes more sense to break `Array.prototype` usage but not `Function.prototype` usage. --Kyle ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Array.prototype change (Was: @@toStringTag spoofing for null and undefined)
On Feb 19, 2015, at 1:13 PM, Mark S. Miller wrote: On Thu, Feb 19, 2015 at 12:56 PM, Allen Wirfs-Brock al...@wirfs-brock.com wrote: On Feb 19, 2015, at 12:09 PM, Andrea Giammarchi wrote: if we'd like to have Array.empty, Function.empty, String.empty and friends, what's wrong with having these as we always had already: as prototypes? Just to keep things focused. *.empty is not something that is on the table for ES6. It would have to go into the ES7 track. Today's issue, is 1) do we need to revert Array.prototype to being an Array exotic object (I think we do) 2) do we need to revert RegExp.prototype to being a RegExp instance.(with initialize RegExp internal slots) (maybe not, and alternatively I have very minor tweaks to the exec and test methods that will maintain the most likely such legacy RegExp.prototype uses without needing those internal slots) RegExp.prototype.compile https://people.mozilla.org/~jorendorff/es6-draft.html#sec-regexp.prototype.compile is a visible side effect that survives Object.freeze. It is only not a global communications channel because there is no longer a primordial RegExp instance. So we cannot consider making RegExp.prototype a RegExp unless Object.freeze must disable RegExp.prototype.compile on RegExp instances. Good. I alwasys remember Date.prototype but tend to forget about compile. I think we can keep RegExp as a plain vanilla object (RegExp instances are ordinary, but not plain vanilla) and still have good enough legacy compat for RegExp misuse via my exec and test tweaks. (they basically just test if they are being called with %RegExpProtoype% as their this object. Doesn't catch cross-realm, but probably still good enough) Allen ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
ES6 Spec Release Candidate 1
The last ES6 draft is now available at http://wiki.ecmascript.org/doku.php?id=harmony:specification_drafts#february_20_2015_rev_34_release_candidate_1 The is the Rev34 draft of February 20, 2015. This is release candidate 1. It is the draft that TC39 members will review before our TC39 member where we are planning to voting to refer it to the Ecma General Assembly. During the release candidacy period I will continue to fix editorial and technical bugs as they are reported. So please keep reporting them. Changes in Rev34 include: For legacy compatibility, Array.prototype goes back to being an Array exotic object (Array.isArray(Array.prototype) answers true). For legacy compatibility, RegExp.prototype.exec.call/test.call act as if %RegExpPrototype% was still an RegExp instance TypedArray slice, copyWith, set(TypedArray) do encoding preserving (memcopy) transfers when the source and target element types are the same. The ‘next’ method of internally generated list iterator objects and the ‘revoke’ method of the object returned by Proxy.revocable are now non-enumerable, consistent with other built-in methods Renamed Put() abstract operation to Set() Eliminate the [lexical goal] grammar annotation. Instead clarified the explanation of lexical goals in clause 11 Eliminated Annexes D.2, D.3, E.2 that copying the ES5/51 Annex D/E into ES6. Too confusing because of section number mismatches. People should just look at Annex D/E of Es 5/5.1 Resolved bugs: 4012, 4010, 4005- 4002, 3999, 3995-3992, 3990-3985, 3983-3935, 3933- 3931, 3929-3902, 3900-3880, 3878-3861, 3859-3858, 3856-3846, 3791, 3759, 3753, 3751-3746, 3724, 3694, 3596, 3504, 3490, 3294, 3279, 3138-3137, 3114, 3074, 2916, 2401, 2215, 1801, 1782, 1778, 1770, 1522-1521, 1075, 1059, 635, 172, 116 ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Possible bugs in 12.1.1 Early Errors of Identifier
The second section under 12.1.1 https://people.mozilla.org/~jorendorff/es6-draft.html#sec-identifiers-static-semantics-early-errors says: IdentifierReference[Yield] *:* yield BindingIdentifier[Yield] *:* yield LabelIdentifier[Yield] *:* yield - It is a Syntax Error if this production has a [Yield] parameter. However, they are guarded by the [~Yield] condition. Is this section informative or outdated? The third section says: *IdentifierReference*[Yield] *:* *Identifier* *BindingIdentifier*[Yield] *:* *Identifier* *LabelIdentifier*[Yield] *:* *Identifier* - It is a Syntax Error if this production has a [Yield] parameter and StringValue of Identifier is yield. Is it possible to have the StringValue of an Identifier to be yield? Same applies to the second item of the the fourth section. The note below says (Unicode)... escapes cannot be used to write an *Identifier* whose code point sequence is the same as a *ReservedWord*.. These two combined seem to imply that it is possible to have a StringValue of an Identifier to be as same as a *ReservedWord*, but you cannot do it though some certain way, which is bothering. (like saying: I know you cannot do it though this way, but I'm not going to tell you how to do it or whether you can do it at all). If it is not possible, we should remove the third section and the second item of the fourth section. If it is possible, we should note how it is possible. Thanks, Bei ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Array.prototype change (Was: @@toStringTag spoofing for null and undefined)
On Feb 11, 2015, at 8:30 AM, Allen Wirfs-Brock wrote: TC39 members were aware that changing to using ordinary objects as the prototypes of the legacy built-ins was a breaking change (for example, it changes the prototypes {}.toString value). What we agreed to do was to make that change but to undo it for individual legacy built-ins if we discovered that it would cause actual significant web breakage. We discovered that this was the case for Function.prototype and so it remains a function instances in the ES6 spec What we need for the other legacy built-ins is real evidence that there is a problem, rather than speculation. Let us know if you are aware of a significant Web site or widely used framework that depends upon String.prototype being a String instance or any other similar dependency. So: @awbjs example: a.reduce((c,v)=gt;{if (!~c.indexOf(v)) return c. concat(v)else return c}, Array.prototype) Original Tweet: https://twitter.com/getify/status/568440928433602560 and @awbjs @getify I'd say specially for `.concat()` is quite common pattern so instead of `[].concat()` few of us go `Array.prototype.concat` Original Tweet: https://twitter.com/WebReflection/status/568443370089123842 This looks like the sort of evidence we asked for. None of the fixes I have thought of are as simple as simply saying that Array.prototype is an Array exotic object. So unless, I hear an uproar in the next few hours, I'm going to change the ES6 draft to say that. Allen ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: Array.prototype change (Was: @@toStringTag spoofing for null and undefined)
From: es-discuss [mailto:es-discuss-boun...@mozilla.org] On Behalf Of Allen Wirfs-Brock This looks like the sort of evidence we asked for. I don't really think so. This is some tweets and books, not evidence of real-world usage that would break popular websites and cause browser game theory to kick in. Such evidence is best gathered by browser vendors making the change and seeing what it impacts. I believe IE12/Spartan might already be doing so---Brian, confirm/deny? ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Object.freeze(Object.prototype) VS reality
Hi, Half a million times the following meta-exchange happened on es-discuss: - if an attacker modifies Object.prototype, then you're doomed in all sorts of ways - Don't let anyone modify it. Just do Object.freeze(Object.prototype)! I've done it on client-side projects with reasonable success. I've just tried on a Node project and lots of dependencies started throwing errors. (I imagine the difference is that in Node, it's easy to create projects with a big tree of dependencies which I haven't done too much on the client side). I tracked down a few of these errors and they all seem to relate to the override mistake [1]. * In jsdom [2], trying to add a constructor property to an object fails because Object.prototype.constructor is configurable: false, writable: false * in tough-cookie [3] (which is a dependency of the popular 'request' module), trying to set Cookie.prototype.toString fails because Object.prototype.toString is configurable: false, writable: false Arguably, they could use Object.defineProperty, but they won't because it's less natural and it'd be absurd to try to fix npm. The Cookie.prototype.toString case is interesting. Of all the methods being added, only toString causes a problem. Using Object.defineProperty for this one would be an awkward inconsistency. So, we're in a state where no module needs to modify Object.prototype, but I cannot freeze it because the override mistake makes throw any script that tries to set a toString property to an object. Because of the override mistake, either I have to let Object.prototype mutable (depite no module needing it to be mutable) or freeze it first hand and not use popular modules like jsdom or request. It's obviously possible to replace all built-in props by accessors [4], of course, but this is a bit ridiculous. Can the override mistake be fixed? I imagine no web compat issues would occur since this change is about throwing less errors. David [1] http://wiki.ecmascript.org/doku.php?id=strawman:fixing_override_mistake [2] https://github.com/tmpvar/jsdom/blob/6c5fe5be8cd01e0b4e91fa96d025341aff1db291/lib/jsdom/utils.js#L65-L95 [3] https://github.com/goinstant/tough-cookie/blob/c66bebadd634f4ff5d8a06519f9e0e4744986ab8/lib/cookie.js#L694 [4] https://github.com/rwaldron/tc39-notes/blob/c61f48cea5f2339a1ec65ca89827c8cff170779b/es6/2012-07/july-25.md#fix-override-mistake-aka-the-can-put-check ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Re-export default?
Just curious if this meets the use cases being discussed here, @caridy @jason ? On Thu, Feb 19, 2015 at 9:22 AM, Matthew Robb matthewwr...@gmail.com wrote: import a from a; import b from b; export { a, b }; - Matthew Robb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Re-export default?
Why not simply import a from a; import b from b; export { a, b }; On Feb 19, 2015 8:18 AM, Jason Kuhrt jasonku...@me.com wrote: I hear the verdict but not any substantial rationale; why is it “confusing”?’ @caridy regarding your examples for JS2016 wouldn’t this export default from “foo”; just re-export one module’s default as another module’s default, right? In my use-case, in order to map n-number of default-export functions to named-export functions I would have to do this ad-infinitum: export {default as a} from “./a” export {default as b} from “./b” export {default as c} from “./c” export {default as d} from “./d” export {default as e} from “./e” ... I’m not saying my syntax for my use-case is amazing, I’m just working within the confines of JS. Other languages such as Go have their own interesting approaches to modules that we cannot really consider in JS due to needing a high level of semantic mapping to legacy CJS Modules. On Feb 19, 2015, at 1:31 AM, caridy car...@gmail.com wrote: Yes, that syntax is incorrect and confusing. There was an overside from our end to provide a way to re-export only the default export from another module, and this is something we plan to revisit for ES7/2016. Probably something like this: `export default from “foo”;` this is just sugar for: `export {default} from “foo”;` which is perfectly supported in ES6, including the ability to rename it: `export {default as something} from “foo”;` /caridy On Feb 18, 2015, at 9:08 PM, Jason Kuhrt jasonku...@me.com wrote: I was prompted to bring this issue to es-discuss. https://github.com/babel/babel/issues/826 It is my confusion about why this syntax does not work: export foo from ‘./foo' More details are in the issue but the gist is that sometimes it is actually quite handy to export just defaults internally and then re-export thing as a “bag” of named exports. This is not currently “easy”. I assume this was discussed/considered. I’d be curious what the rationale was. Thanks! Jason ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Array.prototype change (Was: @@toStringTag spoofing for null and undefined)
not evidence of real-world usage that would break popular websites the Web is (still and thankfully) not about popular websites only. Using the `Array.prototype` instead of creating instances in the wild has been seen for long time, same way you don't do `{}.toString.call` but `Object.prototype.toString.call` instead. When a method like `concat` has no side effect to the prototype but can be used as empty starting point for an Array creation, it's perfectly fine to use it as such utility. I am not sure that's the only exception though, and I don't have strong opinion about this specific matter (there must be reasons to change and software needs updates anyway) but I agree with Kyle that if ES6 claims backward compatibility, it should stick with it. This is a breaking change, small or big (famous/populare websites) is sort of less relevant. In github, as example, there's some usage already showing up: https://github.com/search?utf8=%E2%9C%93q=%22Array.prototype.concat%28%22type=Coderef=searchresults I've also seen many `Array.prototype.concat.call([], ...)` which is extremely pointless since that is the equivalent of `[].concat(...)` but from time to time I use similar logic shown in Kyle example with reduce. Again, I don't remember why these builtins needed such change, but things like these should be probably announced as potential breaking so that developers can be aware and eventually fix things here or there. Regards On Thu, Feb 19, 2015 at 4:38 PM, Domenic Denicola d...@domenic.me wrote: From: es-discuss [mailto:es-discuss-boun...@mozilla.org] On Behalf Of Allen Wirfs-Brock This looks like the sort of evidence we asked for. I don't really think so. This is some tweets and books, not evidence of real-world usage that would break popular websites and cause browser game theory to kick in. Such evidence is best gathered by browser vendors making the change and seeing what it impacts. I believe IE12/Spartan might already be doing so---Brian, confirm/deny? ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Array.prototype change (Was: @@toStringTag spoofing for null and undefined)
I think I do understand ... is this operation valid in ES6 ? `var oneTwoThree = Array.prototype.concat(1, 2, 3); // [1, 2, 3]` 'cause that was the initial concern, and as far as I understand that will break. Or does it? On Thu, Feb 19, 2015 at 4:59 PM, Domenic Denicola d...@domenic.me wrote: Andrea, you seem to not understand what change is being discussed here. Nobody is talking about removing or changing the behavior of Array.prototype.concat. Please re-read. -- From: Andrea Giammarchi andrea.giammar...@gmail.com Sent: 2015-02-19 11:57 To: Domenic Denicola d...@domenic.me Cc: Allen Wirfs-Brock al...@wirfs-brock.com; es-discuss@mozilla.org list es-discuss@mozilla.org Subject: Re: Array.prototype change (Was: @@toStringTag spoofing for null and undefined) not evidence of real-world usage that would break popular websites the Web is (still and thankfully) not about popular websites only. Using the `Array.prototype` instead of creating instances in the wild has been seen for long time, same way you don't do `{}.toString.call` but `Object.prototype.toString.call` instead. When a method like `concat` has no side effect to the prototype but can be used as empty starting point for an Array creation, it's perfectly fine to use it as such utility. I am not sure that's the only exception though, and I don't have strong opinion about this specific matter (there must be reasons to change and software needs updates anyway) but I agree with Kyle that if ES6 claims backward compatibility, it should stick with it. This is a breaking change, small or big (famous/populare websites) is sort of less relevant. In github, as example, there's some usage already showing up: https://github.com/search?utf8=%E2%9C%93q=%22Array.prototype.concat%28%22type=Coderef=searchresults I've also seen many `Array.prototype.concat.call([], ...)` which is extremely pointless since that is the equivalent of `[].concat(...)` but from time to time I use similar logic shown in Kyle example with reduce. Again, I don't remember why these builtins needed such change, but things like these should be probably announced as potential breaking so that developers can be aware and eventually fix things here or there. Regards On Thu, Feb 19, 2015 at 4:38 PM, Domenic Denicola d...@domenic.me wrote: From: es-discuss [mailto:es-discuss-boun...@mozilla.org] On Behalf Of Allen Wirfs-Brock This looks like the sort of evidence we asked for. I don't really think so. This is some tweets and books, not evidence of real-world usage that would break popular websites and cause browser game theory to kick in. Such evidence is best gathered by browser vendors making the change and seeing what it impacts. I believe IE12/Spartan might already be doing so---Brian, confirm/deny? ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Array.prototype change (Was: @@toStringTag spoofing for null and undefined)
On Feb 19, 2015, at 9:01 AM, Andrea Giammarchi wrote: I think I do understand ... is this operation valid in ES6 ? `var oneTwoThree = Array.prototype.concat(1, 2, 3); // [1, 2, 3]` you would get: [Array.prototype, 1, 2, 3] That's what convinced me. allen ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Array.prototype change (Was: @@toStringTag spoofing for null and undefined)
I remember once upon a time double quotes meant explicit intent of exact match, t least in Google, IIRC, dunno when that good idea got lost. Yes, it's hard to find for exact matches but if you also check the reduce example, `Array.prototype` is simply passed around. Again, I don't know how much would break here, all I know is that it would be **excellent** to have a list of potentially breaking changes like this one. We can debate for days how breaking this is, but as a change ... it breaks, as Allen confirmed. Can we have either a list of these changes (I'm sure I've missed many, like this one, for example) or can we just stick with the ES6 is backward compat umbrella? Best Regards On Thu, Feb 19, 2015 at 5:21 PM, Mark S. Miller erig...@google.com wrote: On Thu, Feb 19, 2015 at 8:57 AM, Andrea Giammarchi andrea.giammar...@gmail.com wrote: not evidence of real-world usage that would break popular websites the Web is (still and thankfully) not about popular websites only. Using the `Array.prototype` instead of creating instances in the wild has been seen for long time, same way you don't do `{}.toString.call` but `Object.prototype.toString.call` instead. When a method like `concat` has no side effect to the prototype but can be used as empty starting point for an Array creation, it's perfectly fine to use it as such utility. I am not sure that's the only exception though, and I don't have strong opinion about this specific matter (there must be reasons to change and software needs updates anyway) but I agree with Kyle that if ES6 claims backward compatibility, it should stick with it. This is a breaking change, small or big (famous/populare websites) is sort of less relevant. In github, as example, there's some usage already showing up: https://github.com/search?utf8=%E2%9C%93q=%22Array.prototype.concat%28%22type=Coderef=searchresults Take a look again at those results. Although you are indeed searching for Array.prototype.concat(, the first four pages of Github matches I saw were for Array.prototype.concat.apply(, which would still work fine. Anyone know how to do an exact match search on Github? Since these results are sorted by best match, perhaps this indicates that there are no exact matches for Array.prototype.concat( ? I've also seen many `Array.prototype.concat.call([], ...)` which is extremely pointless since that is the equivalent of `[].concat(...)` but from time to time I use similar logic shown in Kyle example with reduce. Again, I don't remember why these builtins needed such change, but things like these should be probably announced as potential breaking so that developers can be aware and eventually fix things here or there. Regards On Thu, Feb 19, 2015 at 4:38 PM, Domenic Denicola d...@domenic.me wrote: From: es-discuss [mailto:es-discuss-boun...@mozilla.org] On Behalf Of Allen Wirfs-Brock This looks like the sort of evidence we asked for. I don't really think so. This is some tweets and books, not evidence of real-world usage that would break popular websites and cause browser game theory to kick in. Such evidence is best gathered by browser vendors making the change and seeing what it impacts. Agree with Domenic. The other thing needed quickly is for someone to add tests for this to test262, so that there is browser game theory pressure in the right direction. I believe IE12/Spartan might already be doing so---Brian, confirm/deny? Indeed. If there is already a browser testing the waters, that would be exactly the kind of evidence we need. -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Object.freeze(Object.prototype) VS reality
On Thu, Feb 19, 2015 at 9:23 AM, David Bruant bruan...@gmail.com wrote: Hi, Half a million times the following meta-exchange happened on es-discuss: - if an attacker modifies Object.prototype, then you're doomed in all sorts of ways - Don't let anyone modify it. Just do Object.freeze(Object.prototype)! I've done it on client-side projects with reasonable success. I've just tried on a Node project and lots of dependencies started throwing errors. (I imagine the difference is that in Node, it's easy to create projects with a big tree of dependencies which I haven't done too much on the client side). I tracked down a few of these errors and they all seem to relate to the override mistake [1]. * In jsdom [2], trying to add a constructor property to an object fails because Object.prototype.constructor is configurable: false, writable: false * in tough-cookie [3] (which is a dependency of the popular 'request' module), trying to set Cookie.prototype.toString fails because Object.prototype.toString is configurable: false, writable: false Arguably, they could use Object.defineProperty, but they won't because it's less natural and it'd be absurd to try to fix npm. The Cookie.prototype.toString case is interesting. Of all the methods being added, only toString causes a problem. Using Object.defineProperty for this one would be an awkward inconsistency. So, we're in a state where no module needs to modify Object.prototype, but I cannot freeze it because the override mistake makes throw any script that tries to set a toString property to an object. Because of the override mistake, either I have to let Object.prototype mutable (depite no module needing it to be mutable) or freeze it first hand and not use popular modules like jsdom or request. It's obviously possible to replace all built-in props by accessors [4], of course, but this is a bit ridiculous. It is indeed ridiculous. Not fixing this in the ES5 timeframe was my single biggest failure and disappointment as a member of TC39. For reference, Caja's implementation of the technique described in [4] is at https://code.google.com/p/google-caja/source/browse/trunk/src/com/google/caja/ses/repairES5.js#278 As it states, our term for freezing an object so that it does not provoke this problem is tamper proofing. Can the override mistake be fixed? I imagine no web compat issues would occur since this change is about throwing less errors. There was a time when some of the browsers did not suffer from the override mistake, and in so doing, were technically out of conformance with the ES5 spec. During this window, it was clearly still web compatible to fix the override mistake. It was during this window that I raised the issue and argued that it be fixed. I brought this up in meetings several times and never made any progress. Once all browsers suffered equally from the override mistake, it was no longer *clearly* web compatible to fix it, so I gave up and focussed on other things instead. However, I agree with your suspicion that it actually would still be web compatible to fix this. Unfortunately, the only way to find out at this point is for a browser to try deploying without the override mistake. I don't have much hope. Instead, I suggest you promote tamper proofing to those audiences to which you currently promote freezing. Though the need for it is indeed ridiculous, it actually works rather well. We've been using it successfully for many years now. David [1] http://wiki.ecmascript.org/doku.php?id=strawman:fixing_ override_mistake [2] https://github.com/tmpvar/jsdom/blob/6c5fe5be8cd01e0b4e91fa96d02534 1aff1db291/lib/jsdom/utils.js#L65-L95 [3] https://github.com/goinstant/tough-cookie/blob/ c66bebadd634f4ff5d8a06519f9e0e4744986ab8/lib/cookie.js#L694 [4] https://github.com/rwaldron/tc39-notes/blob/ c61f48cea5f2339a1ec65ca89827c8cff170779b/es6/2012-07/july- 25.md#fix-override-mistake-aka-the-can-put-check ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: Array.prototype change (Was: @@toStringTag spoofing for null and undefined)
From: Andrea Giammarchi [mailto:andrea.giammar...@gmail.com] Can we have either a list of these changes (I'm sure I've missed many, like this one, for example) https://people.mozilla.org/~jorendorff/es6-draft.html#sec-in-the-6th-edition ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Object.freeze(Object.prototype) VS reality
this, and the fact descriptors suffer inheritance which for 3 boolean properties or a method are absolutely not helpful and make the env doomed by `Object.prototype.writable = true` shenanigans. Yes, I'd personally +1 all these fixes that made these ES5 features not the easiest one to play with On Thu, Feb 19, 2015 at 5:41 PM, Mark S. Miller erig...@google.com wrote: On Thu, Feb 19, 2015 at 9:23 AM, David Bruant bruan...@gmail.com wrote: Hi, Half a million times the following meta-exchange happened on es-discuss: - if an attacker modifies Object.prototype, then you're doomed in all sorts of ways - Don't let anyone modify it. Just do Object.freeze(Object.prototype)! I've done it on client-side projects with reasonable success. I've just tried on a Node project and lots of dependencies started throwing errors. (I imagine the difference is that in Node, it's easy to create projects with a big tree of dependencies which I haven't done too much on the client side). I tracked down a few of these errors and they all seem to relate to the override mistake [1]. * In jsdom [2], trying to add a constructor property to an object fails because Object.prototype.constructor is configurable: false, writable: false * in tough-cookie [3] (which is a dependency of the popular 'request' module), trying to set Cookie.prototype.toString fails because Object.prototype.toString is configurable: false, writable: false Arguably, they could use Object.defineProperty, but they won't because it's less natural and it'd be absurd to try to fix npm. The Cookie.prototype.toString case is interesting. Of all the methods being added, only toString causes a problem. Using Object.defineProperty for this one would be an awkward inconsistency. So, we're in a state where no module needs to modify Object.prototype, but I cannot freeze it because the override mistake makes throw any script that tries to set a toString property to an object. Because of the override mistake, either I have to let Object.prototype mutable (depite no module needing it to be mutable) or freeze it first hand and not use popular modules like jsdom or request. It's obviously possible to replace all built-in props by accessors [4], of course, but this is a bit ridiculous. It is indeed ridiculous. Not fixing this in the ES5 timeframe was my single biggest failure and disappointment as a member of TC39. For reference, Caja's implementation of the technique described in [4] is at https://code.google.com/p/google-caja/source/browse/trunk/src/com/google/caja/ses/repairES5.js#278 As it states, our term for freezing an object so that it does not provoke this problem is tamper proofing. Can the override mistake be fixed? I imagine no web compat issues would occur since this change is about throwing less errors. There was a time when some of the browsers did not suffer from the override mistake, and in so doing, were technically out of conformance with the ES5 spec. During this window, it was clearly still web compatible to fix the override mistake. It was during this window that I raised the issue and argued that it be fixed. I brought this up in meetings several times and never made any progress. Once all browsers suffered equally from the override mistake, it was no longer *clearly* web compatible to fix it, so I gave up and focussed on other things instead. However, I agree with your suspicion that it actually would still be web compatible to fix this. Unfortunately, the only way to find out at this point is for a browser to try deploying without the override mistake. I don't have much hope. Instead, I suggest you promote tamper proofing to those audiences to which you currently promote freezing. Though the need for it is indeed ridiculous, it actually works rather well. We've been using it successfully for many years now. David [1] http://wiki.ecmascript.org/doku.php?id=strawman:fixing_ override_mistake [2] https://github.com/tmpvar/jsdom/blob/6c5fe5be8cd01e0b4e91fa96d02534 1aff1db291/lib/jsdom/utils.js#L65-L95 [3] https://github.com/goinstant/tough-cookie/blob/ c66bebadd634f4ff5d8a06519f9e0e4744986ab8/lib/cookie.js#L694 [4] https://github.com/rwaldron/tc39-notes/blob/ c61f48cea5f2339a1ec65ca89827c8cff170779b/es6/2012-07/july- 25.md#fix-override-mistake-aka-the-can-put-check ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Array.prototype change (Was: @@toStringTag spoofing for null and undefined)
Annex E ... I've never reached that part ... Thanks! On Thu, Feb 19, 2015 at 5:42 PM, Domenic Denicola d...@domenic.me wrote: From: Andrea Giammarchi [mailto:andrea.giammar...@gmail.com] Can we have either a list of these changes (I'm sure I've missed many, like this one, for example) https://people.mozilla.org/~jorendorff/es6-draft.html#sec-in-the-6th-edition ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Object.freeze(Object.prototype) VS reality
On Thu, Feb 19, 2015 at 9:54 AM, Andrea Giammarchi andrea.giammar...@gmail.com wrote: Just as workaround, if you really need that much to freeze the `Object.prototype`, you could: ```js Object .getOwnPropertyNames(Object.prototype) .filter((name) = !/^constructor|toString|valueIOf$/.test(name)) .forEach((name) = Object.defineProperty( Object.prototype, name, {value: Object.prototype[name]} )) Your defineProperty call above has no effect. When doing a defineProperty on an existing property, recall that omitting attributes means that the setting of these attributes should not be changed. Omitted attributes only default to false when the property does not already exist. Interesting that I've seen this bug several times now, by several different authors. Apparently, it is an unanticipated footgun in the ES5 reflection API. ; Object.preventExtensions(Object.prototype); ``` You can eventually fix those 3 properties somehow via accessors. Not ideal, but it should hopefully make your project work (at least) Best Regards On Thu, Feb 19, 2015 at 5:23 PM, David Bruant bruan...@gmail.com wrote: Hi, Half a million times the following meta-exchange happened on es-discuss: - if an attacker modifies Object.prototype, then you're doomed in all sorts of ways - Don't let anyone modify it. Just do Object.freeze(Object.prototype)! I've done it on client-side projects with reasonable success. I've just tried on a Node project and lots of dependencies started throwing errors. (I imagine the difference is that in Node, it's easy to create projects with a big tree of dependencies which I haven't done too much on the client side). I tracked down a few of these errors and they all seem to relate to the override mistake [1]. * In jsdom [2], trying to add a constructor property to an object fails because Object.prototype.constructor is configurable: false, writable: false * in tough-cookie [3] (which is a dependency of the popular 'request' module), trying to set Cookie.prototype.toString fails because Object.prototype.toString is configurable: false, writable: false Arguably, they could use Object.defineProperty, but they won't because it's less natural and it'd be absurd to try to fix npm. The Cookie.prototype.toString case is interesting. Of all the methods being added, only toString causes a problem. Using Object.defineProperty for this one would be an awkward inconsistency. So, we're in a state where no module needs to modify Object.prototype, but I cannot freeze it because the override mistake makes throw any script that tries to set a toString property to an object. Because of the override mistake, either I have to let Object.prototype mutable (depite no module needing it to be mutable) or freeze it first hand and not use popular modules like jsdom or request. It's obviously possible to replace all built-in props by accessors [4], of course, but this is a bit ridiculous. Can the override mistake be fixed? I imagine no web compat issues would occur since this change is about throwing less errors. David [1] http://wiki.ecmascript.org/doku.php?id=strawman:fixing_ override_mistake [2] https://github.com/tmpvar/jsdom/blob/6c5fe5be8cd01e0b4e91fa96d02534 1aff1db291/lib/jsdom/utils.js#L65-L95 [3] https://github.com/goinstant/tough-cookie/blob/ c66bebadd634f4ff5d8a06519f9e0e4744986ab8/lib/cookie.js#L694 [4] https://github.com/rwaldron/tc39-notes/blob/ c61f48cea5f2339a1ec65ca89827c8cff170779b/es6/2012-07/july- 25.md#fix-override-mistake-aka-the-can-put-check ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
ReverseIterable interface
Hello all, I’m working on a spec proposal that I’d like to present as a strawman (stage 0) for reverse iteration. https://github.com/leebyron/ecmascript-reverse-iterator The TL;DR is adding a new well known symbol `Symbol.reverseIterator` and adding methods to the collection prototypes that can be efficiently iterated in reverse. It also suggests adding `reverse()` to %IteratorPrototype% as an API sugar. I’m looking for broad feedback as well as stakeholders if this functionality is important to you. Thanks Lee Byron ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: ReverseIterable interface
Cool, and very thorough! I'll repost if I can think of any questions. On Thu, Feb 19, 2015 at 6:16 PM, Lee Byron leeby...@fb.com wrote: Hello all, I’m working on a spec proposal that I’d like to present as a strawman (stage 0) for reverse iteration. https://github.com/leebyron/ecmascript-reverse-iterator The TL;DR is adding a new well known symbol `Symbol.reverseIterator` and adding methods to the collection prototypes that can be efficiently iterated in reverse. It also suggests adding `reverse()` to %IteratorPrototype% as an API sugar. I’m looking for broad feedback as well as stakeholders if this functionality is important to you. Thanks Lee Byron ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Re-export default?
Jason, the most important feature of ES modules is that they are statically verifiable. Something like `import * from “./foo”` goes against that principle because you cannot know ahead of time what are those specifiers. Essentially, you will have to type those specifiers no matter what :), no sugar will save you from that. /caridy On Feb 19, 2015, at 8:02 PM, Jason Kuhrt jasonku...@me.com wrote: Hi Caridy, I think you misunderstood my comment about import * from ‘./foo’ I am aware of import * as foo from ‘./foo’ and that is fine. My former example is the desire to have `foo`’s exports injected as-is into the module’s scope (bar vs foo.bar, etc.). There are times where this is desirable, wherein enumerating { bar1, bar2, bar3, barN... } is just a waste of time and maintenance headache. As for refactoring hazards I can appreciate that JavaScript has a lot more to protect against than strongly typed languages. Refactoring in JavaScript is generally unsafe for any number of reasons. Jason On Feb 19, 2015, at 7:55 PM, caridy car...@gmail.com mailto:car...@gmail.com wrote: inline On Feb 19, 2015, at 7:50 PM, Jason Kuhrt jasonku...@me.com mailto:jasonku...@me.com wrote: Hey Matthew, This is another pattern I could take yup. Kevin pointed that if I suck it up and move all my modules toward named-exports then my problems go away too. The reason I am using default internally was that I had modules depending on others which are all uniformly single-function modules (react components to be specific). So it felt confusing to have this syntax internally: import { foo } from ‘../foo’ When what I’m really trying to express is: import foo from ‘../foo’ But ultimately if I am willing to accept that internally I use the former syntax then my re-export expressions are fine: export * from ‘./foo’ In my mind, this is good for proxy modules, shims, and other edge cases, but keep in mind that excessive usage of this (e.g.: multiple export *… in the same module) can become a refactor hazard. These are small details but added up they matter. Generally I’m happy with modules though. The only other gripe I have is not being able to import each export naked into a namespace like this: import * from ‘./foo’ that’s exactly what `import * as foo from “./foo”` does it :) /caridy ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Array.prototype change (Was: @@toStringTag spoofing for null and undefined)
1) The ES6 class pattern makes abstractions whose .prototype is an ordinary object. This change makes the builtin abstractions more consistent with class-based abstractions, minimizing surprise for future JS programmers who learn the language at ES6 or later. 2) From a security perspective, the one ES5 builtin abstraction that opened a global communications channel through .prototype was Date, since Date.prototype was a Date instance, and Date instances have mutable state which remains observably mutable after Object.freeze. With the addition of RegExp.prototype.compile, RegExp joins the set of problematic ES5 abstractions. Neither of these argue against making Array.prototype specifically be an Array instance. I prefer that it not be on esthetic grounds only, and am willing to switch given evidence. I concede that Kyle's book is sufficient evidence. On Thu, Feb 19, 2015 at 1:08 PM, Michał Wadas michalwa...@gmail.com wrote: Is there a good reason behind making prototypes ordinary objects? On the margin - I would assume Array.empty to be static method to clean array. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Re-export default?
Hey Matthew, This is another pattern I could take yup. Kevin pointed that if I suck it up and move all my modules toward named-exports then my problems go away too. The reason I am using default internally was that I had modules depending on others which are all uniformly single-function modules (react components to be specific). So it felt confusing to have this syntax internally: import { foo } from ‘../foo’ When what I’m really trying to express is: import foo from ‘../foo’ But ultimately if I am willing to accept that internally I use the former syntax then my re-export expressions are fine: export * from ‘./foo' These are small details but added up they matter. Generally I’m happy with modules though. The only other gripe I have is not being able to import each export naked into a namespace like this: import * from ‘./foo’ Haskell etc. allow this (actually its a bit richer/better but yeah, basically). Often namespacing is what you want, not always. Jason On Feb 19, 2015, at 12:29 PM, Matthew Robb matthewwr...@gmail.com wrote: Just curious if this meets the use cases being discussed here, @caridy @jason ? On Thu, Feb 19, 2015 at 9:22 AM, Matthew Robb matthewwr...@gmail.com mailto:matthewwr...@gmail.com wrote: import a from a; import b from b; export { a, b }; - Matthew Robb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Re-export default?
Hi Caridy, I think you misunderstood my comment about import * from ‘./foo’ I am aware of import * as foo from ‘./foo’ and that is fine. My former example is the desire to have `foo`’s exports injected as-is into the module’s scope (bar vs foo.bar, etc.). There are times where this is desirable, wherein enumerating { bar1, bar2, bar3, barN... } is just a waste of time and maintenance headache. As for refactoring hazards I can appreciate that JavaScript has a lot more to protect against than strongly typed languages. Refactoring in JavaScript is generally unsafe for any number of reasons. Jason On Feb 19, 2015, at 7:55 PM, caridy car...@gmail.com wrote: inline On Feb 19, 2015, at 7:50 PM, Jason Kuhrt jasonku...@me.com wrote: Hey Matthew, This is another pattern I could take yup. Kevin pointed that if I suck it up and move all my modules toward named-exports then my problems go away too. The reason I am using default internally was that I had modules depending on others which are all uniformly single-function modules (react components to be specific). So it felt confusing to have this syntax internally: import { foo } from ‘../foo’ When what I’m really trying to express is: import foo from ‘../foo’ But ultimately if I am willing to accept that internally I use the former syntax then my re-export expressions are fine: export * from ‘./foo’ In my mind, this is good for proxy modules, shims, and other edge cases, but keep in mind that excessive usage of this (e.g.: multiple export *… in the same module) can become a refactor hazard. These are small details but added up they matter. Generally I’m happy with modules though. The only other gripe I have is not being able to import each export naked into a namespace like this: import * from ‘./foo’ that’s exactly what `import * as foo from “./foo”` does it :) /caridy ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Array.prototype change (Was: @@toStringTag spoofing for null and undefined)
Just curious… for RegExp, Date, String and the others that *are* changing to plain objects… does that mean `Object.prototype.toString.call( .. )` will return [object Object] on them? Sorry, I've kinda gotten lost on what the default @@toStringTag behavior is going to be here. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Re-export default?
inline On Feb 19, 2015, at 7:50 PM, Jason Kuhrt jasonku...@me.com wrote: Hey Matthew, This is another pattern I could take yup. Kevin pointed that if I suck it up and move all my modules toward named-exports then my problems go away too. The reason I am using default internally was that I had modules depending on others which are all uniformly single-function modules (react components to be specific). So it felt confusing to have this syntax internally: import { foo } from ‘../foo’ When what I’m really trying to express is: import foo from ‘../foo’ But ultimately if I am willing to accept that internally I use the former syntax then my re-export expressions are fine: export * from ‘./foo’ In my mind, this is good for proxy modules, shims, and other edge cases, but keep in mind that excessive usage of this (e.g.: multiple export *… in the same module) can become a refactor hazard. These are small details but added up they matter. Generally I’m happy with modules though. The only other gripe I have is not being able to import each export naked into a namespace like this: import * from ‘./foo’ that’s exactly what `import * as foo from “./foo”` does it :) /caridy ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Re-export default?
Seems like more maintenance given the duplication and your spreading the footprint of something that should be expressed in one line if it really is a simple re-export semantic that is trying to be expressed. On Feb 19, 2015, at 9:22 AM, Matthew Robb matthewwr...@gmail.com wrote: Why not simply import a from a; import b from b; export { a, b }; On Feb 19, 2015 8:18 AM, Jason Kuhrt jasonku...@me.com mailto:jasonku...@me.com wrote: I hear the verdict but not any substantial rationale; why is it “confusing”?’ @caridy regarding your examples for JS2016 wouldn’t this export default from “foo”; just re-export one module’s default as another module’s default, right? In my use-case, in order to map n-number of default-export functions to named-export functions I would have to do this ad-infinitum: export {default as a} from “./a” export {default as b} from “./b” export {default as c} from “./c” export {default as d} from “./d” export {default as e} from “./e” ... I’m not saying my syntax for my use-case is amazing, I’m just working within the confines of JS. Other languages such as Go have their own interesting approaches to modules that we cannot really consider in JS due to needing a high level of semantic mapping to legacy CJS Modules. On Feb 19, 2015, at 1:31 AM, caridy car...@gmail.com mailto:car...@gmail.com wrote: Yes, that syntax is incorrect and confusing. There was an overside from our end to provide a way to re-export only the default export from another module, and this is something we plan to revisit for ES7/2016. Probably something like this: `export default from “foo”;` this is just sugar for: `export {default} from “foo”;` which is perfectly supported in ES6, including the ability to rename it: `export {default as something} from “foo”;` /caridy On Feb 18, 2015, at 9:08 PM, Jason Kuhrt jasonku...@me.com mailto:jasonku...@me.com wrote: I was prompted to bring this issue to es-discuss. https://github.com/babel/babel/issues/826 https://github.com/babel/babel/issues/826 It is my confusion about why this syntax does not work: export foo from ‘./foo' More details are in the issue but the gist is that sometimes it is actually quite handy to export just defaults internally and then re-export thing as a “bag” of named exports. This is not currently “easy”. I assume this was discussed/considered. I’d be curious what the rationale was. Thanks! Jason ___ es-discuss mailing list es-discuss@mozilla.org mailto:es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org mailto:es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Re-export default?
It doesn’t seem like an impossible problem since other platforms solve this fine without compromising on static analyzability (e.g. Haskell I imagine). But I must admit I’m completely unfamiliar what particular sticking points in the JavaScript platform particularly rule out the possibility of this feature. Jason On Feb 19, 2015, at 8:12 PM, caridy car...@gmail.com wrote: Jason, the most important feature of ES modules is that they are statically verifiable. Something like `import * from “./foo”` goes against that principle because you cannot know ahead of time what are those specifiers. Essentially, you will have to type those specifiers no matter what :), no sugar will save you from that. /caridy On Feb 19, 2015, at 8:02 PM, Jason Kuhrt jasonku...@me.com mailto:jasonku...@me.com wrote: Hi Caridy, I think you misunderstood my comment about import * from ‘./foo’ I am aware of import * as foo from ‘./foo’ and that is fine. My former example is the desire to have `foo`’s exports injected as-is into the module’s scope (bar vs foo.bar, etc.). There are times where this is desirable, wherein enumerating { bar1, bar2, bar3, barN... } is just a waste of time and maintenance headache. As for refactoring hazards I can appreciate that JavaScript has a lot more to protect against than strongly typed languages. Refactoring in JavaScript is generally unsafe for any number of reasons. Jason On Feb 19, 2015, at 7:55 PM, caridy car...@gmail.com mailto:car...@gmail.com wrote: inline On Feb 19, 2015, at 7:50 PM, Jason Kuhrt jasonku...@me.com mailto:jasonku...@me.com wrote: Hey Matthew, This is another pattern I could take yup. Kevin pointed that if I suck it up and move all my modules toward named-exports then my problems go away too. The reason I am using default internally was that I had modules depending on others which are all uniformly single-function modules (react components to be specific). So it felt confusing to have this syntax internally: import { foo } from ‘../foo’ When what I’m really trying to express is: import foo from ‘../foo’ But ultimately if I am willing to accept that internally I use the former syntax then my re-export expressions are fine: export * from ‘./foo’ In my mind, this is good for proxy modules, shims, and other edge cases, but keep in mind that excessive usage of this (e.g.: multiple export *… in the same module) can become a refactor hazard. These are small details but added up they matter. Generally I’m happy with modules though. The only other gripe I have is not being able to import each export naked into a namespace like this: import * from ‘./foo’ that’s exactly what `import * as foo from “./foo”` does it :) /caridy ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss