Fun impossible Firefox JS challenge
Hey all Just thought I'd post a bit of fun related to the Firefox JS parser. !function(){ function true(){alert('Call me');}; /* YOUR CODE */ }(); The trick is to execute the function true from within the function expression. Rules: 1. Your code must be within the function expression as indicated by the comment. 2. You cannot redefine true anywhere else including window etc. 3. You must call the actual function as defined in the original code. This is just for fun and should be impossible but it does highlight a couple of things, 1) JavaScript has no way to reference inner functions that are not a property of the object without directly calling their name. 2) Mozilla JS devs are crazy (in a nice way) Cheers Gareth ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Fun impossible Firefox JS challenge
On Thu, Apr 12, 2012 at 2:58 PM, gaz Heyes gazhe...@gmail.com wrote: function true(){alert('Call me');}; Is this a deliberate Mozilla change, or just a bug (true being a keyword and not valid as a function name in plain ECMAScript)? And, btw, /* MY CODE */ tru\u0065(); /L ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Fun impossible Firefox JS challenge
On 12 April 2012 14:51, Lasse Reichstein reichsteinatw...@gmail.com wrote: On Thu, Apr 12, 2012 at 2:58 PM, gaz Heyes gazhe...@gmail.com wrote: function true(){alert('Call me');}; Is this a deliberate Mozilla change, or just a bug (true being a keyword and not valid as a function name in plain ECMAScript)? And, btw, /* MY CODE */ tru\u0065(); Haha nice try even with unicode escapes it still refers to true the boolean not the function. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Fun impossible Firefox JS challenge
On 12 April 2012 16:11, gaz Heyes gazhe...@gmail.com wrote: On 12 April 2012 14:51, Lasse Reichstein reichsteinatw...@gmail.com wrote: On Thu, Apr 12, 2012 at 2:58 PM, gaz Heyes gazhe...@gmail.com wrote: function true(){alert('Call me');}; Is this a deliberate Mozilla change, or just a bug (true being a keyword and not valid as a function name in plain ECMAScript)? And, btw, /* MY CODE */ tru\u0065(); Haha nice try even with unicode escapes it still refers to true the boolean not the function. That's another FF deviation from the standard, though. /Andreas ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Fun impossible Firefox JS challenge
On 12 April 2012 15:12, Andreas Rossberg rossb...@google.com wrote: That's another FF deviation from the standard, though. Well it's possible to do as I've just done it but deviation from the standard isn't a valid answer sorry :P ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Fun impossible Firefox JS challenge
On Thu, Apr 12, 2012 at 4:12 PM, Andreas Rossberg rossb...@google.com wrote: Haha nice try even with unicode escapes it still refers to true the boolean not the function. That's another FF deviation from the standard, though. Identifiers with unicode escapes have the meaning of their canonical value. So wouldn't that (tru\u0065 referring to the bool) be valid and according to the spec? - peter ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Fun impossible Firefox JS challenge
!function(){ function true(){alert('Call me');}; /* YOUR CODE */ new Function('(' + ('' + arguments.callee).match(/function.+?\{\s*([\s\S]*?\})/)[1] + '())')() }() It calls *a* function `true` but maybe not *the* function `true` On Thu, Apr 12, 2012 at 9:27 AM, Peter van der Zee e...@qfox.nl wrote: On Thu, Apr 12, 2012 at 4:12 PM, Andreas Rossberg rossb...@google.com wrote: Haha nice try even with unicode escapes it still refers to true the boolean not the function. That's another FF deviation from the standard, though. Identifiers with unicode escapes have the meaning of their canonical value. So wouldn't that (tru\u0065 referring to the bool) be valid and according to the spec? - peter ___ 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: Fun impossible Firefox JS challenge
On 12 April 2012 15:34, crypticswarm crypticsw...@gmail.com wrote: !function(){ function true(){alert('Call me');}; /* YOUR CODE */ new Function('(' + ('' + arguments.callee).match(/function.+?\{\s*([\s\S]*?\})/)[1] + '())')() }() It calls *a* function `true` but maybe not *the* function `true` That is lame. Try harder. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Fun impossible Firefox JS challenge
On Thu, Apr 12, 2012 at 3:51 PM, Lasse Reichstein wrote: /* MY CODE */ tru\u0065(); That would only work if the `true` function was defined with at least one Unicode escape in the name (not necessarily the same one). See http://mathiasbynens.be/notes/javascript-identifiers#valid-identifier-names: […] This means that you can use `var \u0061` and `var a` interchangeably. Similarly, since `var 1` is invalid, so is `var \u0031`. For web browsers, there is an exception to this rule, namely when reserved words are used. Browsers must support identifiers that unescape to a reserved word, as long as at least one character is escaped using a Unicode escape sequence. For example, `var var;` wouldn’t work, but e.g. `var v\u0061r;` would — even though strictly speaking, the ECMAScript spec disallows it. Subsequent use of such identifiers must also have at least one character escaped (otherwise the reserved word will be used instead), but it doesn’t have to be the same character(s) that were originally used to create the identifier. For example, `var v\u0061r = 42; alert(va\u0072);` would alert `42`. P.S. If you’re wondering why `function true() {}` is allowed in Firefox, see https://bugzilla.mozilla.org/show_bug.cgi?id=638667. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Fun impossible Firefox JS challenge
On 12 April 2012 16:27, Peter van der Zee e...@qfox.nl wrote: On Thu, Apr 12, 2012 at 4:12 PM, Andreas Rossberg rossb...@google.com wrote: Haha nice try even with unicode escapes it still refers to true the boolean not the function. That's another FF deviation from the standard, though. Identifiers with unicode escapes have the meaning of their canonical value. So wouldn't that (tru\u0065 referring to the bool) be valid and according to the spec? Yes, but keywords (and other verbatim tokens, like 'true') are recognized _before_ canonicalization. At least that is the intention of the spec, Waldemar told me. (I filed https://bugs.ecmascript.org/show_bug.cgi?id=277 a few weeks ago as a request for making the wording clearer.) /Andreas ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Fun impossible Firefox JS challenge
For those interested, Spidermonkey doesn’t handle the following correctly: function \u0074rue() { alert('PASS'); } \u0074rue(); function \u0074rue() { alert('PASS'); } tru\u0065(); Both these examples should alert 'PASS' in web browsers. I filed this as bug 744784: https://bugzilla.mozilla.org/show_bug.cgi?id=744784 ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: Fun impossible Firefox JS challenge
The real question is, are there test-262's for this behavior? Or for the original nonconforming `function true() { }`? From: es-discuss-boun...@mozilla.org [es-discuss-boun...@mozilla.org] on behalf of Mathias Bynens [math...@qiwi.be] Sent: Thursday, April 12, 2012 11:06 To: Lasse Reichstein Cc: es-discuss Steen Subject: Re: Fun impossible Firefox JS challenge For those interested, Spidermonkey doesn’t handle the following correctly: function \u0074rue() { alert('PASS'); } \u0074rue(); function \u0074rue() { alert('PASS'); } tru\u0065(); Both these examples should alert 'PASS' in web browsers. I filed this as bug 744784: https://bugzilla.mozilla.org/show_bug.cgi?id=744784 ___ 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: Fun impossible Firefox JS challenge
On 12 April 2012 17:19, Domenic Denicola dome...@domenicdenicola.com wrote: The real question is, are there test-262's for this behavior? Or for the original nonconforming `function true() { }`? No, there aren't. IIRC, I had filed a bug for that, too. :) /Andreas ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Fun impossible Firefox JS challenge
On Apr 12, 2012, at 8:06 AM, Andreas Rossberg wrote: On 12 April 2012 16:27, Peter van der Zee e...@qfox.nl wrote: On Thu, Apr 12, 2012 at 4:12 PM, Andreas Rossberg rossb...@google.com wrote: Haha nice try even with unicode escapes it still refers to true the boolean not the function. That's another FF deviation from the standard, though. Identifiers with unicode escapes have the meaning of their canonical value. So wouldn't that (tru\u0065 referring to the bool) be valid and according to the spec? Yes, but keywords (and other verbatim tokens, like 'true') are recognized _before_ canonicalization. At least that is the intention of the spec, Waldemar told me. (I filed https://bugs.ecmascript.org/show_bug.cgi?id=277 a few weeks ago as a request for making the wording clearer.) A couple points: Floating around this area (in Mathias' blog post and Andreas' bug report, etc)) there are references to http://wiki.whatwg.org/wiki/Web_ECMAScript#Identifiers . It should be used justify any particular interpretation of the ES specification. There is nothing normative about that document and the section on Identifiers is actually labelled as this is very rough. Nobody should be making implementation decisions on the basis of that document. There may well be web compatibility requirements that are not covered by the current ES5.1 spec. We should try to understand those requirements before implementations start trying to match each others deviations from the spec. Difference between implementations suggest areas where there currently isn't complete interoperability in this area so we shouldn't be creating interoperability among spec. deviations (and future compatibility requirements) unless we actually decide we want those deviations to be part of the standard language. Waldemar's observation may well be correct for ES=3. He would know, and if that was the intent then I can see how the spec. could be read in that manner. But for ES5 we rewrote that portion of the specification and introduced the concept of IdentifierName as a lexical category that includes both ReservedWord and Identifier and all the escape and canonicalization language was applied to IdentifierName rather than Identifier. This was all intentional. We certainly didn't expect true and tru\u0065 to be recognized as different identifier names in newly allowed contexts such as: obj.true == obj.tru\u0065 I'm pretty sure that no reviewers brought up issues related to a ES3 interpretation of unicode escapes as keyword escapes. At this point I think we need to do two things: 1) Understand the actual browser interop situation. For example, do all major browsers accept: var tru\u0065; 2) Within the constraints of 1) decide what we actually want to specify. Do we want console.log(fals\u0065) to print false or undefined? 3) For ES6 we have to decide how \{0065} fits in. Allen ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: undefined being treated as a missing optional argument
This is also a shortcut to making a dense array of a given size. Array.apply(null, Array(5)) // [undefined, undefined, undefined, undefined, undefined] Array(5).map(...) // won't do anything with a sparse array Array.apply(null, Array(5)).map(Function.prototype.call.bind(Number)) // [0,1,2,3,4,5] ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Fun impossible Firefox JS challenge
On Thu, Apr 12, 2012 at 6:13 PM, Allen Wirfs-Brock al...@wirfs-brock.com wrote: At this point I think we need to do two things: Add a third to that, because I don't think Gaz was talking about unicode escapes (Haha nice try). I'm still curious to the answer :) - peter ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Fun impossible Firefox JS challenge
Lasse Reichstein wrote: Is this a deliberate Mozilla change This is a hold-over from the past. It dates from ES4 days when the draft spec in TC39 proposed unreserving keywords not only after . in expressions and before : in object literal property assignments, but also after 'function'. We have a bug on this: https://bugzilla.mozilla.org/show_bug.cgi?id=638667. In it you'll see comments from dherman and me last year trying to hold off on fixing the bug, in case Harmony adopts this proposal. If TC39 can decisively reject it, we'll fix the bug. Maybe we should just fix the bug anyway but I suspect we'll break some Mozilla-only code out there, so this won't happen quickly. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Fun impossible Firefox JS challenge
On Apr 12, 2012, at 9:13 , Allen Wirfs-Brock wrote: At this point I think we need to do two things: 1) Understand the actual browser interop situation. For example, do all major browsers accept: var tru\u0065; 2) Within the constraints of 1) decide what we actually want to specify. Do we want console.log(fals\u0065) to print false or undefined? 3) For ES6 we have to decide how \{0065} fits in. I think \u{0065} should behave exactly like \u0065 wherever it's syntactically allowed. It should be just a new notation; not a way to add or remove capabilities. Norbert ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Fun impossible Firefox JS challenge
Norbert Lindenberg wrote: On Apr 12, 2012, at 9:13 , Allen Wirfs-Brock wrote: At this point I think we need to do two things: 1) Understand the actual browser interop situation. For example, do all major browsers accept: var tru\u0065; 2) Within the constraints of 1) decide what we actually want to specify. Do we want console.log(fals\u0065) to print false or undefined? 3) For ES6 we have to decide how \{0065} fits in. I think \u{0065} should behave exactly like \u0065 wherever it's syntactically allowed. It should be just a new notation; not a way to add or remove capabilities. +1 /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Fun impossible Firefox JS challenge
Allen Wirfs-Brock wrote: Floating around this area (in Mathias' blog post and Andreas' bug report, etc)) there are references to http://wiki.whatwg.org/wiki/Web_ECMAScript#Identifiers . It should be used justify any particular interpretation of the ES specification. Missing not after should in last sentence. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Fun impossible Firefox JS challenge
indeed! On Apr 12, 2012, at 10:19 AM, Brendan Eich wrote: Allen Wirfs-Brock wrote: Floating around this area (in Mathias' blog post and Andreas' bug report, etc)) there are references to http://wiki.whatwg.org/wiki/Web_ECMAScript#Identifiers . It should be used justify any particular interpretation of the ES specification. Missing not after should in last sentence. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Fun impossible Firefox JS challenge
Allen Wirfs-Brock wrote: 1) Understand the actual browser interop situation. For example, do all major browsers accept: var tru\u0065; SpiderMonkey shell: js var tru\u0065; typein:1: SyntaxError: missing variable name: typein:1: var tru\u0065; typein:1: ^ It looks like Carakan (Opera), JSC and V8 allow this. I can't test IE. 2) Within the constraints of 1) decide what we actually want to specify. Do we want console.log(fals\u0065) to print false or undefined? Carakan, JSC and V8 alert undefined. Anyone have IE results? Looks like SpiderMonkey implemented ES5 not ES3, probably accidentally and ahead of time. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: Fun impossible Firefox JS challenge
var tru\u0065; = Expected identifier error in IE9. console.log(fals\u0065) = Syntax error in IE9. Can test IE10 when I get home from work. From: es-discuss-boun...@mozilla.org [es-discuss-boun...@mozilla.org] on behalf of Brendan Eich [bren...@mozilla.org] Sent: Thursday, April 12, 2012 13:38 To: Allen Wirfs-Brock Cc: es-discuss Steen Subject: Re: Fun impossible Firefox JS challenge Allen Wirfs-Brock wrote: 1) Understand the actual browser interop situation. For example, do all major browsers accept: var tru\u0065; SpiderMonkey shell: js var tru\u0065; typein:1: SyntaxError: missing variable name: typein:1: var tru\u0065; typein:1: ^ It looks like Carakan (Opera), JSC and V8 allow this. I can't test IE. 2) Within the constraints of 1) decide what we actually want to specify. Do we want console.log(fals\u0065) to print false or undefined? Carakan, JSC and V8 alert undefined. Anyone have IE results? Looks like SpiderMonkey implemented ES5 not ES3, probably accidentally and ahead of time. /be ___ 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: Fun impossible Firefox JS challenge
Yes! IE and Firefox agree! :-P I'm not suggesting we win, just glad not to be all alone on this one. ;-) Thanks for testing. Allen, your thoughts? /be Domenic Denicola wrote: var tru\u0065; = Expected identifier error in IE9. console.log(fals\u0065) = Syntax error in IE9. Can test IE10 when I get home from work. From: es-discuss-boun...@mozilla.org [es-discuss-boun...@mozilla.org] on behalf of Brendan Eich [bren...@mozilla.org] Sent: Thursday, April 12, 2012 13:38 To: Allen Wirfs-Brock Cc: es-discuss Steen Subject: Re: Fun impossible Firefox JS challenge Allen Wirfs-Brock wrote: 1) Understand the actual browser interop situation. For example, do all major browsers accept: var tru\u0065; SpiderMonkey shell: js var tru\u0065; typein:1: SyntaxError: missing variable name: typein:1: var tru\u0065; typein:1: ^ It looks like Carakan (Opera), JSC and V8 allow this. I can't test IE. 2) Within the constraints of 1) decide what we actually want to specify. Do we want console.log(fals\u0065) to print false or undefined? Carakan, JSC and V8 alert undefined. Anyone have IE results? Looks like SpiderMonkey implemented ES5 not ES3, probably accidentally and ahead of time. /be ___ 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: Fun impossible Firefox JS challenge
On Apr 12, 2012, at 10:51 AM, Brendan Eich wrote: Yes! IE and Firefox agree! :-P I'm not suggesting we win, just glad not to be all alone on this one. ;-) Thanks for testing. Allen, your thoughts? The IE9 console.log syntax error (I see it too) seem like a bug under any interpretation of the ES5.1 spec. My second test case actually isn't very good. console.log(fals\u0065) is actually a reference error in chrome and safari. This is the expected behavior when referencing an undeclared variable. So they are also de-keywordizing in that context. FF alerts false so it it interpreting the fals\u0065 in this context as the keyword and not as an Identifier. So, FF (= 4??) and IE9 don't seem to support unicode escape based de-keywordization and the web doesn't appear to have collapsed. That seems like a good indication that this isn't a major interp. concern and we can think about what we want such unicode escapes to mean rather than being forced to adopt something. Personally, I think the de-keywordization interpretation is pretty ugly. It is taking something (unicode escapes) that presumably exist for specific purpose (a way to insert arbitrary Unicode code units into source text) and loads a secondary semantics upon them. I think that ES5 has already covered the important use cases for contextual non-keyword interpretation of reserved words. If we want to allow declarations that create bindings for reserved words (not something I favor) then we should address that head-on rather than via a ugly backdoor. I think we should stick with the ES5 intent (Unicode escapes don't change the meaning of an IdentiferName, including keywords) and possibly clarify the Es6 spec. language to make this intent even clearer. Allen /be Domenic Denicola wrote: var tru\u0065; = Expected identifier error in IE9. console.log(fals\u0065) = Syntax error in IE9. Can test IE10 when I get home from work. From: es-discuss-boun...@mozilla.org [es-discuss-boun...@mozilla.org] on behalf of Brendan Eich [bren...@mozilla.org] Sent: Thursday, April 12, 2012 13:38 To: Allen Wirfs-Brock Cc: es-discuss Steen Subject: Re: Fun impossible Firefox JS challenge Allen Wirfs-Brock wrote: 1) Understand the actual browser interop situation. For example, do all major browsers accept: var tru\u0065; SpiderMonkey shell: js var tru\u0065; typein:1: SyntaxError: missing variable name: typein:1: var tru\u0065; typein:1: ^ It looks like Carakan (Opera), JSC and V8 allow this. I can't test IE. 2) Within the constraints of 1) decide what we actually want to specify. Do we want console.log(fals\u0065) to print false or undefined? Carakan, JSC and V8 alert undefined. Anyone have IE results? Looks like SpiderMonkey implemented ES5 not ES3, probably accidentally and ahead of time. /be ___ 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: Fun impossible Firefox JS challenge
Allen Wirfs-Brock wrote: The IE9 console.log syntax error (I see it too) seem like a bug under any interpretation of the ES5.1 spec. My second test case actually isn't very good. console.log(fals\u0065) is actually a reference error in chrome and safari. This is the expected behavior when referencing an undeclared variable. So they are also de-keywordizing in that context. Try running with 'var fals\u0065;' prepended -- have to test both ways. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Fun impossible Firefox JS challenge
On Apr 12, 2012, at 12:23 PM, Brendan Eich wrote: Allen Wirfs-Brock wrote: The IE9 console.log syntax error (I see it too) seem like a bug under any interpretation of the ES5.1 spec. My second test case actually isn't very good. console.log(fals\u0065) is actually a reference error in chrome and safari. This is the expected behavior when referencing an undeclared variable. So they are also de-keywordizing in that context. Try running with 'var fals\u0065;' prepended -- have to test both ways. var fals\u0065; console.log(fals\u0065); var fals\u0065; console.log(fals\u0065); var fals\u0065; console.log(fals\u0065); Right chrome and safari log undefined in that case. FF and IE9 syntax error out on the var declaration. Allen ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: Fun impossible Firefox JS challenge
So, FF (= 4??) and IE9 don't seem to support unicode escape based de-keywordization and the web doesn't appear to have collapsed. That seems like a good indication that this isn't a major interp. concern and we can think about what we want such unicode escapes to mean rather than being forced to adopt something. Personally, I think the de-keywordization interpretation is pretty ugly. It is taking something (unicode escapes) that presumably exist for specific purpose (a way to insert arbitrary Unicode code units into source text) and loads a secondary semantics upon them. I think that ES5 has already covered the important use cases for contextual non-keyword interpretation of reserved words. If we want to allow declarations that create bindings for reserved words (not something I favor) then we should address that head-on rather than via a ugly backdoor. I think we should stick with the ES5 intent (Unicode escapes don't change the meaning of an IdentiferName, including keywords) and possibly clarify the Es6 spec. language to make this intent even clearer. +1. Having Unicode escapes have no impact on the interpretation of an IdentifierName seems like a simpler model for the language, and the one that the ES5 spec text currently suggests. FWIW - I tested IE8 as well, and it also doesn't support Unicode escape de-keywordization, so I suspect this behavior has been around in browsers for quite a while. Luke ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: Fun impossible Firefox JS challenge
IE10 (Windows 8 Consumer Preview edition): var tru\u0065; = The use of a keyword for an identifier is invalid console.log(fals\u0065) = Syntax error So same thing but better error message for the former case. -Original Message- From: es-discuss-boun...@mozilla.org [mailto:es-discuss-boun...@mozilla.org] On Behalf Of Domenic Denicola Sent: Thursday, April 12, 2012 13:49 To: Brendan Eich; Allen Wirfs-Brock Cc: es-discuss Steen Subject: RE: Fun impossible Firefox JS challenge var tru\u0065; = Expected identifier error in IE9. console.log(fals\u0065) = Syntax error in IE9. Can test IE10 when I get home from work. From: es-discuss-boun...@mozilla.org [es-discuss-boun...@mozilla.org] on behalf of Brendan Eich [bren...@mozilla.org] Sent: Thursday, April 12, 2012 13:38 To: Allen Wirfs-Brock Cc: es-discuss Steen Subject: Re: Fun impossible Firefox JS challenge Allen Wirfs-Brock wrote: 1) Understand the actual browser interop situation. For example, do all major browsers accept: var tru\u0065; SpiderMonkey shell: js var tru\u0065; typein:1: SyntaxError: missing variable name: typein:1: var tru\u0065; typein:1: ^ It looks like Carakan (Opera), JSC and V8 allow this. I can't test IE. 2) Within the constraints of 1) decide what we actually want to specify. Do we want console.log(fals\u0065) to print false or undefined? Carakan, JSC and V8 alert undefined. Anyone have IE results? Looks like SpiderMonkey implemented ES5 not ES3, probably accidentally and ahead of time. /be ___ 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: undefined being treated as a missing optional argument
The wiki says that this should fill the array with 'undefined' (I believe the spec draft aims to say the same, but I can't tell where this is established). The same runtime semantics routines are used for both default parameter initialization and for initializing array destructurings in let/const declarations (and hence same semantics for places). For formal parameters it starts in the Runtime Semantics of 13.1 and (in theory) for individual formal parameters of the form (id=expr) will eventually reach Keyed Binding Initialisation for the production singeNameBind : BindingIdentifier Initialiser in 12.2.4. It's in theory because it looks like the current draft is missing a couple intermediate steps in 13.1. Got it. That's where I was looking, but didn't see the place where (id=expr) was explicitly handled and passed into Keyed Binding Initialisation. Sounds like that is the step that is missing in current drafts. 1) Existing uses of default value patterns in JavaSscript use undefined as the sentinel for not present, so a semantics for default values in ES6 that behaves differently will not be usable as a shorthand for any of these existing APIs without changing semantics. Undefined is not always such a sentential. Some examples of built-ins that treat undefined different form a missing parameter: ... The examples cited are arguably cases where the built-in behaviour is unintuitive to many JavaScript developers, because it doesn't match their expectation with user code functions and most other built-ins. I don't view any of the cases listed as validation that we would *want* that behaviour by default, just that there are a non-zero number of cases where it exists today. I suggest that the appropriate way to think of about the current behavior, in the context of ES6, is that function f(a) {...} is equivalent to function f(a=undefined) {...} In other words, there is a default initialization expression, if one is not specified. So, f() and f(undefined) appear to produce the same result. This is a good way of explaining the proposed semantics, but... But I see why somebody calling a function defined as function(a={ }){...} explicitly as f(undefined) would expect to trigger the default value initializer. Right. This is exactly the sort of thing I'm worried about, and seems like the practical common case for default values. 2) The fact that JavaScript (at least for user objects) currently doesn't differentiate between missing arguments and undefined arguments is a nice simplifying rule in the language that is easy to understand.. It does differentiate, at least in regard to the arguments object. True. But this is uncommon enough as to not be something most developers deal with. Default values aim to be a much more commonly used tool. 3) The example above, of wanting to have an API that allows explicitly passing in undefined to override a default value, seems outside of the common case (out of curiosity - are there any realistic example of this?). If truly desired, it is easy to not use default values. But the common case seems more likely to be to emulate what is done today - and avoid having any undefined values flow into the API call. Why is the example, outside of common sense. It is a straightforward function to fill every element of an array with a common value. Undefined is certain something that can be stored in arrays so why wouldn't there be situations where where you would want to pass undefined. Particularly if the fill function was written by an unreformed Java programmer who used a peculiar default fill value. The last point was why I considered it outside of the common case. It seems unusual to intentionally want to fill with null by default, but still allow overriding with an undefined fill. Not impossible, but I would expect this to be rare enough that I don't mind making it the one case where default values can't be used. I agree that there is some confusion among some JS programmer about the current missing argument default value rules. However, I don't think what you are suggesting is going to reduce that confusion. I think it will increase it. At the end of the day - I see value in enabling the patterns developers are using today to be refactorable into default values. I worry that the current proposed semantics are too far away from what is used today to make that practical. Of course, there is enough inconsistency in what is used currently anyway - so this may be a difficult goal to achieve fully. But I suspect that treating undefined the same as not present at least keeps things close enough the common forms below could reasonably consider migrating to default values. // All fairly common.. if(!param) { param = 3; } if(param == null) { param = 3; } if(typeof param == 'undefined') { param = 3; } param = param || 3; var param =
Re: undefined being treated as a missing optional argument
The examples cited are arguably cases where the built-in behaviour is unintuitive to many JavaScript developers, because it doesn't match their expectation with user code functions and most other built-ins. I don't view any of the cases listed as validation that we would *want* that behaviour by default, just that there are a non-zero number of cases where it exists today. I suggest that the appropriate way to think of about the current behavior, in the context of ES6, is that function f(a) {...} is equivalent to function f(a=undefined) {...} In other words, there is a default initialization expression, if one is not specified. So, f() and f(undefined) appear to produce the same result. This is a good way of explaining the proposed semantics, but... But I see why somebody calling a function defined as function(a={ }){...} explicitly as f(undefined) would expect to trigger the default value initializer. Right. This is exactly the sort of thing I'm worried about, and seems like the practical common case for default values. 2) The fact that JavaScript (at least for user objects) currently doesn't differentiate between missing arguments and undefined arguments is a nice simplifying rule in the language that is easy to understand.. It does differentiate, at least in regard to the arguments object. True. But this is uncommon enough as to not be something most developers deal with. Default values aim to be a much more commonly used tool. 3) The example above, of wanting to have an API that allows explicitly passing in undefined to override a default value, seems outside of the common case (out of curiosity - are there any realistic example of this?). If truly desired, it is easy to not use default values. But the common case seems more likely to be to emulate what is done today - and avoid having any undefined values flow into the API call. Why is the example, outside of common sense. It is a straightforward function to fill every element of an array with a common value. Undefined is certain something that can be stored in arrays so why wouldn't there be situations where where you would want to pass undefined. Particularly if the fill function was written by an unreformed Java programmer who used a peculiar default fill value. The last point was why I considered it outside of the common case. It seems unusual to intentionally want to fill with null by default, but still allow overriding with an undefined fill. Not impossible, but I would expect this to be rare enough that I don't mind making it the one case where default values can't be used. I agree that there is some confusion among some JS programmer about the current missing argument default value rules. However, I don't think what you are suggesting is going to reduce that confusion. I think it will increase it. At the end of the day - I see value in enabling the patterns developers are using today to be refactorable into default values. I worry that the current proposed semantics are too far away from what is used today to make that practical. Of course, there is enough inconsistency in what is used currently anyway - so this may be a difficult goal to achieve fully. But I suspect that treating undefined the same as not present at least keeps things close enough the common forms below could reasonably consider migrating to default values. // All fairly common.. if(!param) { param = 3; } if(param == null) { param = 3; } if(typeof param == 'undefined') { param = 3; } param = param || 3; var param = arguments[1] || 3; // Not sure I've ever seen this... which seems to be the proposed default value semantics if(arguments.length f.length) { param = 3; } At first the answer to this didn't really matter to me, because how often does someone pass undefined to a function like foo(undefined). I know I don't, though I'm sure it happens occasionally. Then I thought about it and realized that it happens in my code all the time, just not like that. A much more common case is a pass through of an argument to another function. function fadeIn(duration=200){...} function fadeOut(duration=200){...} function fadeToggle(duration){ if(visible){ fadeOut(duration); }else{ fadeIn(duration); } } Here, the argument duration is always passed through fadeToggle to fadeIn or fadeOut. Someone writing fadeIn would always expect to have a default of 200. fadeToggle does not care about the duration so much as it wants to pass it on and use the defaults of the functions it calls. If passing undefined does not trigger the default, it would have to be rewritten like: function fadeToggle(duration){ var hasDuration = typeof duration != undefined; if(visible){ if(hasDuration){ fadeOut(duration); }else{ fadeOut(); } }else{