Re: Jan 18 meeting notes
Le 20/01/2012 00:54, Brendan Eich a écrit : David Bruant mailto:bruan...@gmail.com January 19, 2012 1:15 AM Le 19/01/2012 02:27, Waldemar Horwat a écrit : Brendan: Kill typeof null. Replace it with Ojbect.isObject? What would be the semantics of this? It was not obvious but the precedent stems from the strawman that led to my proposal to change typeof null: http://wiki.ecmascript.org/doku.php?id=strawman:object_isobjectrev=1295471005 This week we considered the draft spec: Object.isObject = function isObject(value) { return typeof value === 'object' value !== null; } to be deficient because a function is also an object, so one might rather have Object.isObject = function isObject(value) { return (typeof value === 'object' value !== null) || typeof value == 'function'; } That would be perfect (for me at least). -- Object.isObject(null); // false Object.isObject({}); // true // so far so good :-) Object.isObject(function(){}) // ? -- I'd like to advocate true for the last case. For now, the best way to test if something is of type Object (as defined in ES5.1 - 8.6, so including function) is to do o === Object(o) (an alternative being o !== null (typeof o === 'object' || typeof o === 'function'), which is rather long and I have not seen much) which is a bit hacky and not straightforward to read for those who are not familiar with this trick. If an Object.isObject is introduced, I'd be interested in seeing it covering the 8.6 definition. Or maybe introduce another function for this? That came up too: Object.type(x) would be the new typeof. But it will take a while to get adoption, it's not built-in so monkey-patchable etc. If Object.isObject has the second definition you showed, I don't think an Object.type will be necessary, because every type will be testable in one instruction. Strings, numbers, booleans have typeof, undefined and null are unique values (testable with ===) and Object.isObject will test for ES5.1 - 8.6 definition of objects. It won't be consistent as an Object.type method would be, but as far as I'm concerned, I don't care. David ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Block lambda is cool, its syntax isn't
But notice that throughout this, no one advancing a proposal advocated freezing by default. JS developers use function objects as mutable objects. Not just to set .prototype, also to decorate with ad-hoc and meta-data properties. Freezing is not wanted by default. Another example: when defining parser combinators, I've re-defined .toString, to make it easier to identify the parser combination in question during debugging. This would be less of an issue if core JS operations weren't biased towards mutation. If it was easy to create modified function objects without in-place mutation, freezing functions would be more acceptable. Claus ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Block lambda is cool, its syntax isn't
On 19/01/2012, at 22:14, Axel Rauschmayer wrote: Suggestion: a community-edited page where we collect the rejected syntaxes (= less running in circles) – simply copying emails (such as yours below) there would probably suffice. Has a backtick/accent grave ever been considered and/or rejected ? Anonymous function expression: setTimeout( '(){ ... }, 1e3); Named function expression: setTimeout( 'name(){ ... }, 1e3); Declarations: `(){ ... } // error: can't declare anonymous functions `name(){ ... } -- Jorge. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Jan 18 meeting notes
Le 20/01/2012 00:57, Brendan Eich a écrit : David Bruant mailto:bruan...@gmail.com January 19, 2012 1:43 AM Every time I've been thinking of an issue like this, the solution I've found was whoever runs first wins. This is not relevant to the example I showed. All in all, regardless of data or accessor, or the guarantee you put in which object can or cannot have its prototype changed, it seems that at the very least, security relies (at least partly) on __proto__ being deletable (configurable). And deleting it is something that the first code that runs gets to decide. If it's trusted code, it can delete it, if it's an attacker, it can make it non-configurable. We have a de-facto standard with SpiderMonkey I'm not sure I agree with the idea of a de-facto standard with SpiderMonkey. In Chrome (V8): - var o = Object.create(null); console.log(o.a); // undefined o.__proto__ = {a:1}; console.log(o.a); // 1 - If something is de-facto, it's SpiderMonkey implementation, not a standard. And as I showed in an earlier message, there is out there code running in node.js (V8) using __proto__, hence making V8's version also worth not breaking. that protects an object from having its [[Prototype]] changed once it has cut itself off from Object.prototype. Reflecting __proto__ as an accessor breaks this guarantee. In the strawman [1], the security of an object is not bound to what is or is not in the prototype chain, but rather whether or not the object is extensible or not. Why wouldn't that be enough? Does this matter? Clearly, it does cross-frame in the web embedding I'm not sure I understand. Can you provide an example please? Specifically, an example that would show a threat for the accessor property case, but not the data property case. Regarding cross-frame issues, I can't think of how one case is worse than the other. Data or accessor, a new frame defines a new Object, a new Object.prototype and a new Object.prototype.__proto__. This one has to be deleted by the parent. If in the parent, trusted code run first, it can make sure to be the only entity allowed to dynamically create frames and to be the first to access them (to delete Object.prototype.__proto__). If in the parent, an attacker runs first, it can make sure to be the first one to access the frame.Object.prototype and do whatever it wants to its __proto__ property. David [1] http://wiki.ecmascript.org/doku.php?id=strawman:magic_proto_property ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Does private(expr) create a private storage block?
Sorry, misunderstood the question. Andrea Giammarchi wrote: On Fri, Jan 20, 2012 at 2:24 AM, Herby Vojčík he...@mailbox.sk mailto:he...@mailbox.sk wrote: Let the object created is foo. When calling foo.method(), it is accessing private(foo), not private(objectWithPrivates), since this is foo. If yes does not happen. Errors may happen since foo probably does not have private space (my proposal in this thread is touching this issue). 2. what if Object.create(objectWithPrivates, descriptor) ? would descriptor methods be able to invoke objectWithPrivates.method() with private(this) access in the function body? If yes, would that private(this) refer to the objectWithPrivates? This would violate the objectWithPrivates private concept, isn't it? Object.create accept the __proto__ and a descriptor, I am not sure a descriptor will/should ever have a private(this) configured unless there is not a class for the descriptor but the list of configurations won't make much sense, i.e. {value: function () { this instanceof OuterClass /* not possible, it's just an object */ }} It is an error to use private keyword outside the class block. So, no extension with private(this) using methods at all outside it. If aforementioned Object.create would appear inside class block, then according to actual state of the proposal, as I understand it, it is an error to use private keyword, too. It can only be used in methods (and constructor). But with I am less sure. My proposal is to make use of private keyword much more liberated, in that case if your Object.create would appear inside (any) class block, it would work and added (that class's whose the class block is) private access, outside class block it would not. Herby ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: January 19 meeting notes
Jon Zeppieri wrote: Is there a version of this desugaring that deals with recursive bindings in the initializer expression of the loop? How about something like this? (given for (let varName = initExpr; testExpr; updateExpr) { body } ) { let varName = initExpr; while(true) { if (!testExpr) { break breakTarget; } let tempVar = varName; { // There might be a better way to copy values to/from shadowed variables // (using temporaries seems a bit weak) let varName = tempVar; continueTarget: { body } tempVar = varName; } varName = tempVar; updateExpr; } } That way, all of the variable references in initExpr, testExpr and updateExpr refer to a singular copy and all of the variable references in body refer to the iteration-scoped ones. So, looking at your example: for (let [i, inc] = [0, function() {i++;}]; i n; inc()) ... I think it now has the desired behaviour. However, people calling inc from inside the body will still be surprised. I think solving that probably requires something more advanced than a desugaring, as it means the loop variables captured by that function (or, alternatively, ones captured inside the body) need to point at different variables at different times. There's also an abstraction leakage if one breaks in the body, in that the inner varName doesn't get copied to the outer one. All in all, not a great desugaring, but I thought it might be worth offering. Maybe disallowing capture in the for (let ...;...;...) head would be easier. Regards, Grant Husbands. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Block lambda is cool, its syntax isn't
I must say you globally got my point (even if, after re-reading it, it wasn't as clear as I intended). I hope others did, too. To respond to your questions : (1) On the usage of the arobase (@) symbol The @ is used in some languages as a function introductory keyword. Have a look at the very popular (among engineers) Matlab/Octav, for exemple. To me, it also carry a vlid semantic since At X corresponds X.toString() is a nice way to say @(X) X.toString(). I've had a look at the current private name proposal, and, since last time I checked, there's still no mention of the @ symbol in it. If I guess correctly, it could replace the # sign used currently on the page. In that case, I don't see where's the problem with using the @() syntax since you can't actuall call the # symbol in the current proposal, you just need to access his ‘properties’. By the way, I don't say we should use @, just that it's a possible choice (and that if # has a semantic issue that would make it a bad choice, it can be used instead). I’ve been using the @ symbol quite a lot in the past to introduce functions so it feels natural for me (don’t take me responsible if I continue to use it in my mails) but if the comitee choose to use # (or another symbol like %, µ or § (which is the key just after the opening parenthesis on my keyboard BTW)), I would be perfectly happy. (2) Arrow between args and body Would be complex to parse. I don’t think it’s possible, and even if it is, it could be horribly confusing in some cases : ? array.filter((x)=x5) ? array.filter((x)=(x5)) ? array.filter((x)={return x5;}) var list = { ... append: (x) = { list.add(x,list.length); } ... } ? (2) Function, block-lambda semantics Maybe I wasn’t that clear on the point, but something I hate is non-future-proof/unstable coding. When I write a piece of code, I want it to be as maintainable as possible. By maintainable, I mean that if I need to change the code, a small change should never trigger changes at different locations in my code. Small change, small fix. The problem with the block-lambda used as a ‘local function’ (sorry, I don’t see a better way to define the concept, ie a function which is only used in an action-related, controlled context) is that a small change could require major rewrite. Let’s imagine that I wrote that code : arrary.map({|x|while(x.previousSibling) x=x.previousSibling;}); Then, let’s imagine that I should change my code to include an early return. Using block-lambda, it can be rather complex. array.map({|x| let shouldReturn=false; while(!shouldReturn x.previousSibling) { if(isValidStart(x)) { shouldReturn=true; } else { x=x.previousSibling; } } x; }) Boom, the code has become very complex and is not easily readable anymore. Even if I wanted to modify my code to transform the block-lambda in a function, it would involve a lot of rewrite (changes are highlighted here, but I think if I face the case, I just delete the whole code and restart from scratch) : array.map(function(x) { while(x.previousSibling) { if(isValidStart(x)) return x; x=x.previousSibling; } return x; }); But, according to me, if a small change can trigger a block-lambda to become a function, it’s because it should not have been a block lambda from start. It should have been a function. Lets consider the case where we use a short function notation instead, from beginning : array.map(@(x) { while(x.previousSibling) { x=x.previousSibling; } return x; } It’s a big longer but it’s futur-proof. To make my small change, I just have to add one line of code. array.map(@(x) { while(x.previousSibling) { if(isValidStart(x)) return x; x=x.previousSibling; } return x; }); For the first time, the code was stable. A small change only shifted slightly the balance. I can acomodate with ‘function’, but, let’s face it, in some simpler cases, if I don’t have a short function notation, I’ll use a block-lambda and will face the problem. And be sure I’ll dislike it :-D Even allowing the @(x) x.toString() syntax is not a problem since if I need to change the expression into a list of statement, there’s just one place to perform the changes (I have to replace x.toString() with a new code), so I can write my code in one continuous typing stream, and I don’t have to use the mouse (or CTRL+Arrows) to move the spot to different places. An expression has to be small anyway so I don’t loose a lot of code even if I choose to scratch redo. The @ and the arguments are already there. (3) Short function ‘desugaring’ preference If I could choose, I would set the short function syntax to imply automatic binding. But since it makes them unusable for script
Re: January 19 meeting notes
A couple of remarks/questions... On 20 January 2012 01:40, Waldemar Horwat walde...@google.com wrote: Allen: Do top-level let and const create properties of the global object? DaveH (channeling Andreas): No, but functions do. If that is referring to me then there might have been a misunderstanding. I don't think I ever suggested making a distinction between different forms of static bindings. That would be terrible. :) Sam: If they don't then the T-shirt Erik is currently wearing wouldn't work. Many agreed that we can't break the T-shirt. Let me guess: that T-shirt is saying let is the new var? DaveH: What if there are duplicate top-level bindings? MarkM: Top-level let should behave as much as possible the same as concatenated scripts. There are some serious issues lurking here. I would like to float another idea for reforming the top-level, but I'll do so in a separate post. Also, function (e) {let e;} should always be an error. Is there a good reason to do this? It would be an unnecessary irregularity with block scoping, and seems like overly nanny-ish (in stark contrast to other parts of the language). Discussion about scope of for-bindings. for (var x = ...;;) {...} will, of course, retain ES1 semantics. for (let x = ...;;) {...} Allen: This will behave as in C++: x is bound once in a new scope immediately surrounding just the for statement. DaveH: Strangely enough, this creates a new x binding in Dart at each iteration. Why strange? [...] Those opposed earlier to new-binding-per-iteration hop back onto the fence. Waldemar, Brendan, and DaveH hop off the fence to now support it, as it will cure an annoying gotcha in practice. Looks like we have support for it now. I'm happy to hear that. Given lexical closures, I think it clearly is the far superior semantics. Just need to get the V8 implementation in line... /Andreas ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
The global object as the global scope instance object
From the TC39 notes: DaveH: What if there are duplicate top-level bindings? MarkM: Top-level let should behave as much as possible the same as concatenated scripts. It's my claim that it is impossible to reconcile all of the following three goals in a way that is even remotely sane: 1. Top-level bindings are aliased as data properties of the global object. 2. Top-level bindings allow redefinition of existing properties of the global object. 3. Top-level let/const have a temporal dead-zone. Abandoning (3) essentially means abandoning a reasonable const semantics for the toplevel (and future hostile to guards), so we don't want to do that. (For V8, we had long struggles with defining and implementing a const for the (current notion of) top-level that actually makes any sense. We failed.) Hence, I would like to suggest another, more moderate idea for a global scope reform: treat the global object similar to a module instance objects. That is: - Top-level bindings (other than var) are reflected as accessor properties on the global object. - They are defined on the global object before the script starts executing. - Their getters/setters simply delegate to the bound variables. - For const bindings, there are no setters. - These properties are non-configurable. - Unlike a module instance object, the global object is extensible (multiple scripts!). This disallows lexical bindings to redefine existing non-configurable properties of the global object (including ones reflecting bindings from earlier scripts), which is checked before the script starts executing. Likewise, let/const-defined properties cannot later be deleted from the global object. Apart from that, not much should change in practical terms. You should pretty much be able to replace var with let. At the same time, static scoping actually is maintained, and there is no issue with temporal dead zones. Moreover, concatenating scripts would not affect the meaning or validity of bindings, AFAICS. Regarding scope pollution, I think this is best solved by making the global object be a fresh empty object that has the object containing all primordials as its prototype. Overriding is allowed according to the standard defineProperty semantics. No special rules necessary. /Andreas ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: January 19 meeting notes
Andreas Rossberg wrote: On 20 January 2012 01:40, Waldemar Horwatwalde...@google.com wrote: Also, function (e) {let e;} should always be an error. Is there a good reason to do this? It would be an unnecessary irregularity with block scoping, and seems like overly nanny-ish (in stark contrast to other parts of the language). +1. I see no point why let e; should not shadow argument e here. Herby ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: January 19 meeting notes
On 20 January 2012 09:22, Herby Vojčík he...@mailbox.sk wrote: +1. I see no point why let e; should not shadow argument e here. I do. It is a virtual certainty that this form was used accidentally by the developer, which indicates a flaw in the developer's thinking -- probably due to cut-paste/refactor code having a variable name collision. It should be an early error/warning, just like it is in C. Wes -- Wesley W. Garland Director, Product Development PageMail, Inc. +1 613 542 2787 x 102 ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: January 19 meeting notes
On 19 January 2012 23:02, Brendan Eich bren...@mozilla.org wrote: Yes kids, this means we are going with MarkM's lambda desugaring from: https://mail.mozilla.org/**pipermail/es-discuss/2008-**October/007819.htmlhttps://mail.mozilla.org/pipermail/es-discuss/2008-October/007819.html So any closures formed in the body of such a for(let...;...;...) loop will capture the binding created afresh for that iteration. Thank you, Lord! \o/Can I get a Hallelujah? \o/ for (i=0; i alerts.length; i++) { setTimeout(function(i) { return function() { m.add(alerts[i]) } }(i), (i+1) * 10); } Here ^^ is a real loop I wrote last week, weeping the entire time. Wes -- Wesley W. Garland Director, Product Development PageMail, Inc. +1 613 542 2787 x 102 ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: January 19 meeting notes
So any closures formed in the body of such a for(let...;...;...) loop will capture the binding created afresh for that iteration. Thank you, Lord! \o/Can I get a Hallelujah? \o/ for (i=0; i alerts.length; i++) { setTimeout(function(i) { return function() { m.add(alerts[i]) } }(i), (i+1) * 10); } Here ^^ is a real loop I wrote last week, weeping the entire time. I agree. If you are willing to add two more lines, you can make the code a little more readable: for (i=0; i alerts.length; i++) { (function (i) { setTimeout(function() { m.add(alerts[i]) }, (i+1) * 10); }(i)); } -- Dr. Axel Rauschmayer a...@rauschma.de home: rauschma.de twitter: twitter.com/rauschma blog: 2ality.com ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: The global object as the global scope instance object
On Fri, Jan 20, 2012 at 5:55 AM, Andreas Rossberg rossb...@google.comwrote: [...] Regarding scope pollution, I think this is best solved by making the global object be a fresh empty object that has the object containing all primordials as its prototype. [...] very pedantic -- you've been warned Just a pedantic terminology point for now: Presumably you mean global primordials other than the global object itself. Object.prototype.toString is a primordial, but presumably there is no direct binding from your proposed object to Object.prototype.toString. (An alternate interpretation of your containing might be reachable, in which case it would apply to Object.prototype.toString, but IMO that's a confusing way to specify things.) I would classify Object as a global primordial, because it is initially bound, according to ES specification, to the global variable named Object. The global object itself is bound to top level this, which isn't exactly a global variable, so it is unclear whether the unqualified phrase global primordials should include it. Hence the qualification. Although the global object is often also bound to a global variable like window, this does *not* make it a global primordial, since that binding derives from the hosting environment rather than any ES spec. Were we to adopt your proposal, this new object would itself be a new primordial, reachable directly from the global object but not named by any global variable. Indeed, it would be one of the very few primordials not named by a naming path rooted in a global variable. (Another example is the ThrowTypeError object of 13.2.3. Are there any others? I can't think of any.) /very pedantic -- you've been warned Substantive comments later after I've mulled over your very interesting suggestion. -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Jan 18 meeting notes
Andy Wingo mailto:wi...@igalia.com January 20, 2012 7:43 AM I had a hard time following the conclusions here. There does seem to be some uncertainty regarding ES6 features in non-strict code, but is in strict mode and in modules is this (DaveH's new proposal) the consensus? Thanks, Andy I listed every harmony:proposals (eventually -- some eluded me) on the white board and we worked through them, evaluating how they could work in non-strict code. That was the list with ? or x next to any proposal with questions or overt (we thought) compatibility problems. We eventually solved all the cases that survived (typeof null == null died). This means new ES6 features work in non-strict code. Great news! We need some experiments to prove that those early x marks can be removed. For instance, const and function-in-block require experimentation by SpiderMonkey and JavaScriptCore in nightly builds to switch to the ES6 semantics in non-strict code and see what breaks. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Jan 18 meeting notes
David Bruant mailto:bruan...@gmail.com January 20, 2012 12:51 AM Le 20/01/2012 00:54, Brendan Eich a écrit : That came up too: Object.type(x) would be the new typeof. But it will take a while to get adoption, it's not built-in so monkey-patchable etc. If Object.isObject has the second definition you showed, I don't think an Object.type will be necessary, because every type will be testable in one instruction. Strings, numbers, booleans have typeof, undefined and null are unique values (testable with ===) and Object.isObject will test for ES5.1 - 8.6 definition of objects. It won't be consistent as an Object.type method would be, but as far as I'm concerned, I don't care. We want consistency along the major dimensions for new features, if we can. Having a bunch of isFoo predicates does not help switch on an enumerated type value. On the other hand, we can't make a categorical sum for all types or classes without a catch-call category within which further subtype tests will be required anyway. I think given existing practice we might justify Object.typeOf(x) - typeof with Object.typeOf(null) == null. Object.classOf(x) - Object.prototype.toString.call(x).slice(8, -1) using the original value of O.p.toString. Comments? /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: January 19 meeting notes
On Jan 20, 2012, at 6:22 AM, Herby Vojčík wrote: Andreas Rossberg wrote: On 20 January 2012 01:40, Waldemar Horwatwalde...@google.com wrote: Also, function (e) {let e;} should always be an error. Is there a good reason to do this? It would be an unnecessary irregularity with block scoping, and seems like overly nanny-ish (in stark contrast to other parts of the language). +1. I see no point why let e; should not shadow argument e here. In general, the binding rules for function parameters were decided at the Nov. 2011 meeting (see Nov 16 meeting notes): MarkM: Two-scope model (one scope for parameters, an independent inner scope for let, const, and var bindings). This model is upwards-compatible with ES5.1 strict because the latter disallows shadowing of a parameter by a binding in function scope. Allen: Two-scope model, but with inner scope prohibited from shadowing parameters. MarkM: Likes this. Any program that is accepted works with either of the two-scope model intuitions. Whether you view this has two scopes with static semantic rules that prohibit inner declarations from shadowing or a single scope with appropriate static semantic rules that prevent redeclaration of formals, the effect is essentially the same. The current specification draft actually uses a single environment record and appropriate static semantic rules. However you model it in terms of scopes, the intent is that the function formal parameters and the top level declarations are treated as a single naming contour for the purposes of allowing or disallowing duplicate declarations. Also we have the following rules such such naming contours: We don't allow duplicate let declarations for the same name. We don't allow a let binding and a var declarations for the same name. There may be multiple var declarations for the same name. They all refer to the same binding. Given those rules, how to we think about formal parameters? If they are equivalent to let declarations, then the first rule would disallow function(d) {let e}. If they are equivalent to var declarations, then the second rule would disallow that function. Allen Herby ___ 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: Jan 18 meeting notes
Object.classOf(x) - Object.prototype.toString.call (x).slice(8, -1) using the original value of O.p.toString. Comments? Including the name of the module that the class comes from might be nice. We do that for classes implemented in C in GPSEE modules today by being bad -- we modify JSClass::name after JS_InitClass() returns -- and it's helpful during debugging. Wes -- Wesley W. Garland Director, Product Development PageMail, Inc. +1 613 542 2787 x 102 ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Multi-line quasi literals
One of the valuable use cases for quasis that we've discussed is multi-line string literals. It was just pointed out to me that the current proposal page mentions an open issue which calls into question multi-line string literals and the exact semantics of them. This is in http://wiki.ecmascript.org/doku.php?id=harmony:quasis Line Continuation and Line Terminators. The concern raised there is about trailing whitespace at the end of lines, and in particular issues related to source control and end-of-line escapes. My feeling is that: a) Multi-line string literals are important and should be supported in quasis. b) Trailing whitespace should be allowed and preserved. It is a useful for quasis to be as literal as possible. This came up in side conversation at the TC39 meeting today - wanted to send mail to see if the open issue can be resolved. Luke ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Fixing instanceof (Array.isArray() etc.)?
This JavaScript pitfall is still mind-boggling to me. It is clear what happens (each frame has a different copy of Array etc.), but I find it hard to wrap my mind around the consequences in practice. Is there a plan on how to make this less painful in the long run? Initially, a cross-frame version of instanceof might help (as opposed to Function.isFunction, Date.isDate, RegExp.isRegexp etc.). -- Dr. Axel Rauschmayer a...@rauschma.de home: rauschma.de twitter: twitter.com/rauschma blog: 2ality.com ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
shortcut for private(this)
Hello, I think private itself could be used as a shortcut to private(this). It may look for example like this: class Foo { ... leq(other) { return private.weight = private(other).weight; } ... } It is not unprecedented, there already is a keyword that represents this as well as other object in a strange manner (super). So private can also be such a word. I don't see any grammatical/parsing/syntanctic problems with this for the moment. Maybe you find one. Herby P.S.: Since it is very similar (and private.foo works everywhere, not only in constructor), it may be though of to remove 'private foo = bar;' in constructor in favour of 'private.foo = bar;'. But it is only sort of afterthought. Also, 'public baz = moo;' could then be changed by simple 'this.baz = moo;' to make code in constructor more akin to code used everywhere else. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: January 19 meeting notes
On Jan 20, 2012, at 7:13 AM, Wes Garland wrote: On 20 January 2012 09:22, Herby Vojčík he...@mailbox.sk wrote: +1. I see no point why let e; should not shadow argument e here. I do. It is a virtual certainty that this form was used accidentally by the developer, which indicates a flaw in the developer's thinking -- probably due to cut-paste/refactor code having a variable name collision. It should be an early error/warning, just like it is in C. This was essentially the conclusion that was reached when this was discussed at the Nov. TC39 meeting. Allen ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Multi-line quasi literals
2012/1/20 Luke Hoban lu...@microsoft.com: My feeling is that: a) Multi-line string literals are important and should be supported in quasis. b) Trailing whitespace should be allowed and preserved. It is a useful for quasis to be as literal as possible. This came up in side conversation at the TC39 meeting today - wanted to send mail to see if the open issue can be resolved. +1. Some IDEs provide mechanisms that automatically strip whitespace on save, but I think those will have to change for ES.next anyway. http://www.velocityreviews.com/forums/t144789-eclipse-stripping-whitespace-at-eol.html For javascript got to 'save actions' select Perform the selected actions on save Check Additional Actions and click on configure. choose the code organizing tab Check Remove trailing whitespace This will remove trailing white space from all lines every time you save. You can optionally ignore empty lines. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: January 19 meeting notes
Allen Wirfs-Brock wrote: On Jan 20, 2012, at 6:22 AM, Herby Vojčík wrote: +1. I see no point why let e; should not shadow argument e here. In general, the binding rules for function parameters were decided at the Nov. 2011 meeting (see Nov 16 meeting notes): MarkM: Two-scope model (one scope for parameters, an independent inner scope for let, const, and var bindings). This model is upwards-compatible with ES5.1 strict because the latter disallows shadowing of a parameter by a binding in function scope. Allen: Two-scope model, but with inner scope prohibited from shadowing parameters. MarkM: Likes this. Any program that is accepted works with either of the two-scope model intuitions. Whether you view this has two scopes with static semantic rules that prohibit inner declarations from shadowing or a single scope with appropriate static semantic rules that prevent redeclaration of formals, the effect is essentially the same. The current specification draft actually uses a single environment record and appropriate static semantic rules. However you model it in terms of scopes, the intent is that the function formal parameters and the top level declarations are treated as a single naming contour for the purposes of allowing or disallowing duplicate declarations. ... Single scope, args are lets view is making sense of this. Ok, thanks. Allen Herby ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: January 19 meeting notes
On Fri, Jan 20, 2012 at 9:57 AM, Herby Vojčík he...@mailbox.sk wrote: Single scope, args are lets view is making sense of this. Ok, thanks. Another case together with this one seems to force us into Single scope, args are vars: function foo(e) { var e ... } The var e is currently accepted in both strict and non-strict as a redundant declaration of the same variable, no shadowing or error. We can't break this. And we can't explain it if params are let bindings. If it turns out to be practically backwards compatible, we would like to explain } catch (e) { as a let binding of e, leading to a simpler explanation of its block-local scope. The hard case is } catch (e) { var e ... } which would have to become an error. We don't yet know if this new breakage would create actual problems in practice. -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Block lambda is cool, its syntax isn't
Jorge mailto:jo...@jorgechamorro.com January 20, 2012 1:22 AM Has a backtick/accent grave ever been considered and/or rejected ? Rejected, that is used by wiki.ecmascript.org/doku.php?id=harmony:quasis already. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: January 19 meeting notes
On 20 January 2012 18:26, Allen Wirfs-Brock al...@wirfs-brock.com wrote: On 20 January 2012 01:40, Waldemar Horwatwalde...@google.com wrote: Also, function (e) {let e;} should always be an error. Is there a good reason to do this? It would be an unnecessary irregularity with block scoping, and seems like overly nanny-ish (in stark contrast to other parts of the language). In general, the binding rules for function parameters were decided at the Nov. 2011 meeting (see Nov 16 meeting notes): MarkM: Two-scope model (one scope for parameters, an independent inner scope for let, const, and var bindings). This model is upwards-compatible with ES5.1 strict because the latter disallows shadowing of a parameter by a binding in function scope. Allen: Two-scope model, but with inner scope prohibited from shadowing parameters. MarkM: Likes this. Any program that is accepted works with either of the two-scope model intuitions. Whether you view this has two scopes with static semantic rules that prohibit inner declarations from shadowing or a single scope with appropriate static semantic rules that prevent redeclaration of formals, the effect is essentially the same. The current specification draft actually uses a single environment record and appropriate static semantic rules. However you model it in terms of scopes, the intent is that the function formal parameters and the top level declarations are treated as a single naming contour for the purposes of allowing or disallowing duplicate declarations. Here is a simple model: a function expression introduces one local scope(*), which contains the parameters and the var variables hoisted from its body (as in ES5). The function is evaluated by evaluating its body _as a block_ (which it is, syntactically). This is a simpler, more compositional rule with fewer special cases. In effect, you have two scopes, but there is nothing special at all about the inner one. In particular, var-bound vars are hoisted out of this block like they are hoisted out of inner blocks. This is fully backwards compatible, AFAICS. (*) Ignoring the extra scope for the optional function name. /Andreas ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: January 19 meeting notes
On 20 January 2012 18:28, Allen Wirfs-Brock al...@wirfs-brock.com wrote: On Jan 20, 2012, at 7:13 AM, Wes Garland wrote: On 20 January 2012 09:22, Herby Vojčík he...@mailbox.sk wrote: +1. I see no point why let e; should not shadow argument e here. I do. It is a virtual certainty that this form was used accidentally by the developer, which indicates a flaw in the developer's thinking -- probably due to cut-paste/refactor code having a variable name collision. It should be an early error/warning, just like it is in C. This was essentially the conclusion that was reached when this was discussed at the Nov. TC39 meeting. How is function(x) { let x } any different in this respect from { let x { let x } } ? The same argument can be made in either case. The latter is allowed, the former isn't. In both cases, a block-local let shadows a variable from outer scope. /Andreas ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: January 19 meeting notes
Mark S. Miller mailto:erig...@google.com January 20, 2012 10:15 AM On Fri, Jan 20, 2012 at 9:57 AM, Herby Vojčík he...@mailbox.sk mailto:he...@mailbox.sk wrote: Single scope, args are lets view is making sense of this. Ok, thanks. Another case together with this one seems to force us into Single scope, args are vars: function foo(e) { var e ... } The var e is currently accepted in both strict and non-strict as a redundant declaration of the same variable, no shadowing or error. We can't break this. And we can't explain it if params are let bindings. Exactly -- sorry I didn't raise this yesterday. Allen, IIRC we've discussed it. This was the reason ES4 equated let and var at top of function body or Program production (but that was in the bad old days). If it turns out to be practically backwards compatible, we would like to explain } catch (e) { as a let binding of e, ES5 doesn't include let but essentially specifies this, and engines do it (those that support 'let' use exactly the same machinery). leading to a simpler explanation of its block-local scope. The hard case is } catch (e) { var e ... } which would have to become an error. We don't yet know if this new breakage would create actual problems in practice. Pretty sure we can break this. We should. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: January 19 meeting notes
Andreas Rossberg mailto:rossb...@google.com January 20, 2012 10:17 AM Here is a simple model: a function expression introduces one local scope(*), which contains the parameters and the var variables hoisted from its body (as in ES5). The function is evaluated by evaluating its body _as a block_ (which it is, syntactically). This is a simpler, more compositional rule with fewer special cases. In effect, you have two scopes, but there is nothing special at all about the inner one. In particular, var-bound vars are hoisted out of this block like they are hoisted out of inner blocks. This is fully backwards compatible, AFAICS. (*) Ignoring the extra scope for the optional function name. +1. I do not see how we can make parameters be let-bound, given function f(x) { var x; ... } being allowed in ES5 non-strict and strict. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: shortcut for private(this)
Let's not bikeshed class private syntax just yet. I mean, we could (es-discuss, right?) but I don't think it is productive. And again, we do not want a reified private state object, so private could not be a free expression. This also hurts private(other).weight -- 'weight' is not an identifier in a private state object, it has to be a private name object binding. Therefore we should avoid any syntax suggesting a first-class reflection of a private state object. This is why @foo for private name object bound to lexical identifier foo has been proposed. It also has the benefits of being shorter and matching some other languages near to JS. /be Herby Vojčík mailto:he...@mailbox.sk January 19, 2012 9:58 AM Hello, I think private itself could be used as a shortcut to private(this). It may look for example like this: class Foo { ... leq(other) { return private.weight = private(other).weight; } ... } It is not unprecedented, there already is a keyword that represents this as well as other object in a strange manner (super). So private can also be such a word. I don't see any grammatical/parsing/syntanctic problems with this for the moment. Maybe you find one. Herby P.S.: Since it is very similar (and private.foo works everywhere, not only in constructor), it may be though of to remove 'private foo = bar;' in constructor in favour of 'private.foo = bar;'. But it is only sort of afterthought. Also, 'public baz = moo;' could then be changed by simple 'this.baz = moo;' to make code in constructor more akin to code used everywhere else. ___ 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: Fixing instanceof (Array.isArray() etc.)?
Axel Rauschmayer wrote: This JavaScript pitfall is still mind-boggling to me. It is clear what happens (each frame has a different copy of Array etc.), but I find it hard to wrap my mind around the consequences in practice. Is there a plan on how to make this less painful in the long run? Initially, a cross-frame version of instanceof might help (as opposed to Function.isFunction, Date.isDate, RegExp.isRegexp etc.). Inspired by Smalltalk messages like #isInteger (defined in Object as returning false, defined in Integer as returning true) one possible solution would be to use variation of it. Its problem (or advantage, as one sees at it) is that it is designed for overwriting and possibility have forest, not only tree of objects that return isXxx as true; the is, for duck-typing. But if recent discussion of read-only inheritance proves true, then it can be protected by defining isArray property on (every) Object.prototype as non-writable, non-configurable, value:false, and similar one with value:true on (every) Array.prototype so one can not shadow it by mere assignment, but only by (explicit or implicit) defineProperty. From the point of security, it is probably too liberal. :-( -- Dr. Axel Rauschmayer a...@rauschma.de mailto:a...@rauschma.de Herby ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: shortcut for private(this)
Brendan Eich wrote: And again, we do not want a reified private state object, so private could not be a free expression. This also hurts private(other).weight -- 'weight' is not an identifier in a private state object, it has to be a private name object binding. Therefore we should avoid any syntax suggesting a first-class reflection of a private state object. How do I do private(foo)[expression]? Or I don't (yes, it can be worked around by foo.@store[expression], but)? This is why @foo for private name object bound to lexical identifier foo has been proposed. It also has the benefits of being shorter and matching some other languages near to JS. I did not know. I have read the class proposal (I need to rework Empowered Data not to use @). I am all for @bar (or something), I like the concise syntax for private property name concept. In fact I wanted it, and wanted to propose something lot crazier (private keyword itself being modifier of the property name, so foo.private bar, foo[private expr]; but @ is better (except I don't know if it is []-friendly). /be Herby ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: shortcut for private(this)
Herby Vojčík mailto:he...@mailbox.sk January 20, 2012 10:39 AM Brendan Eich wrote: And again, we do not want a reified private state object, so private could not be a free expression. This also hurts private(other).weight -- 'weight' is not an identifier in a private state object, it has to be a private name object binding. Therefore we should avoid any syntax suggesting a first-class reflection of a private state object. How do I do private(foo)[expression]? Or I don't (yes, it can be worked around by foo.@store[expression], but)? No problem -- @foo[bar] is the same in abstract syntax as (@foo)[bar]. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: shortcut for private(this)
Brendan Eich wrote: Herby Vojčík mailto:he...@mailbox.sk January 20, 2012 10:39 AM Brendan Eich wrote: And again, we do not want a reified private state object, so private could not be a free expression. This also hurts private(other).weight -- 'weight' is not an identifier in a private state object, it has to be a private name object binding. Therefore we should avoid any syntax suggesting a first-class reflection of a private state object. How do I do private(foo)[expression]? Or I don't (yes, it can be worked around by foo.@store[expression], but)? No problem -- @foo[bar] is the same in abstract syntax as (@foo)[bar]. No, I asked for something else. How do it do: get a private property of foo whose name is computed by expression? Something like foo.@[expr]? Or is there no way to do it? In other words, what is [] syntax for foo.@bar? foo.@[bar]? foo[@bar]? Herby /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: January 19 meeting notes
On Jan 20, 2012, at 10:22 AM, Brendan Eich wrote: Mark S. Miller mailto:erig...@google.com January 20, 2012 10:15 AM On Fri, Jan 20, 2012 at 9:57 AM, Herby Vojčík he...@mailbox.sk mailto:he...@mailbox.sk wrote: Single scope, args are lets view is making sense of this. Ok, thanks. Another case together with this one seems to force us into Single scope, args are vars: function foo(e) { var e ... } The var e is currently accepted in both strict and non-strict as a redundant declaration of the same variable, no shadowing or error. We can't break this. And we can't explain it if params are let bindings. Exactly -- sorry I didn't raise this yesterday. Allen, IIRC we've discussed it. This was the reason ES4 equated let and var at top of function body or Program production (but that was in the bad old days). I think it did come up, which is why I would actually apply the Single scope, args are vars (which can not be redeclared via let) rule. In fact formals parameters are neither let or var bindings (and the specification doesn't even distinguish environment record bindings in that manner). Classic non-strict arguments are pretty var like, but strict mode forbids multiple formals with the same name ( a let-like characteristic) and we have agreed that new syntactic forms for formal (eg destructuring) will also preclude multiple declarations of the same name even in non-strict contexts. If it turns out to be practically backwards compatible, we would like to explain } catch (e) { as a let binding of e, ES5 doesn't include let but essentially specifies this, and engines do it (those that support 'let' use exactly the same machinery). leading to a simpler explanation of its block-local scope. The hard case is } catch (e) { var e ... } which would have to become an error. We don't yet know if this new breakage would create actual problems in practice. Pretty sure we can break this. We should. From the meeting, this was my understanding of how we will proceed. All of the breaking changes we discussed in the context of enabling ES6 features into non-strict code are subject to reconsideration if we discover actual web breakage. Allen ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: shortcut for private(this)
On Fri, Jan 20, 2012 at 10:46, Herby Vojčík he...@mailbox.sk wrote: No, I asked for something else. How do it do: get a private property of foo whose name is computed by expression? Something like foo.@[expr]? Or is there no way to do it? In other words, what is [] syntax for foo.@bar? foo.@[bar]? foo[@bar]? @bar is a shorthand[*] for this[bar] object.@bar is a shorthand[*] for object[bar] There is no way to compute a string bar to do the lookup since that would break private name encapsulation: let object = ... { let key = Name.create() let secret = {} object.@key = secret } There must be no way to get access to secret here. [*] Using @ does not really invoke []. That is important if private names are going to work with the extended collection proposals Allen proposed. http://wiki.ecmascript.org/doku.php?id=strawman:object_model_reformation -- erik ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: shortcut for private(this)
On Fri, Jan 20, 2012 at 10:59 AM, Erik Arvidsson erik.arvids...@gmail.com wrote: On Fri, Jan 20, 2012 at 10:46, Herby Vojčík he...@mailbox.sk wrote: No, I asked for something else. How do it do: get a private property of foo whose name is computed by expression? Something like foo.@[expr]? Or is there no way to do it? In other words, what is [] syntax for foo.@bar? foo.@[bar]? foo[@bar]? @bar is a shorthand[*] for this[bar] object.@bar is a shorthand[*] for object[bar] There is no way to compute a string bar to do the lookup since that would break private name encapsulation: let object = ... { let key = Name.create() let secret = {} object.@key = secret } There must be no way to get access to secret here. [*] Using @ does not really invoke []. That is important if private names are going to work with the extended collection proposals Allen proposed. http://wiki.ecmascript.org/doku.php?id=strawman:object_model_reformation Shorter Arv: Private Names are not strings, they're unforgeable objects. Thus, it's impossible by design to have an analog of foo[bar+baz] for Private Names. I wrote a blog post about the subject: http://www.xanthir.com/blog/b4FJ0 ~TJ ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Multi-line quasi literals
We should not have any doubts about this point. Quasis mean almost-verbatim, including literal unescaped newlines and *all* spaces. Mike, will you update the wiki? Thanks for bringing this up, Luke. /be Mike Samuel mailto:mikesam...@gmail.com January 20, 2012 9:47 AM +1. Some IDEs provide mechanisms that automatically strip whitespace on save, but I think those will have to change for ES.next anyway. http://www.velocityreviews.com/forums/t144789-eclipse-stripping-whitespace-at-eol.html For javascript got to 'save actions' select Perform the selected actions on save Check Additional Actions and click on configure. choose the code organizing tab Check Remove trailing whitespace This will remove trailing white space from all lines every time you save. You can optionally ignore empty lines. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss Luke Hoban mailto:lu...@microsoft.com January 19, 2012 11:11 PM One of the valuable use cases for quasis that we've discussed is multi-line string literals. It was just pointed out to me that the current proposal page mentions an open issue which calls into question multi-line string literals and the exact semantics of them. This is in http://wiki.ecmascript.org/doku.php?id=harmony:quasis Line Continuation and Line Terminators. The concern raised there is about trailing whitespace at the end of lines, and in particular issues related to source control and end-of-line escapes. My feeling is that: a) Multi-line string literals are important and should be supported in quasis. b) Trailing whitespace should be allowed and preserved. It is a useful for quasis to be as literal as possible. This came up in side conversation at the TC39 meeting today - wanted to send mail to see if the open issue can be resolved. Luke ___ 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: Multi-line quasi literals
2012/1/20 Brendan Eich bren...@mozilla.org: We should not have any doubts about this point. Quasis mean almost-verbatim, including literal unescaped newlines and *all* spaces. Mike, will you update the wiki? Will do. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: January 19 meeting notes
On Jan 20, 2012, at 10:19 AM, Andreas Rossberg wrote: On 20 January 2012 18:28, Allen Wirfs-Brock al...@wirfs-brock.com wrote: On Jan 20, 2012, at 7:13 AM, Wes Garland wrote: On 20 January 2012 09:22, Herby Vojčík he...@mailbox.sk wrote: +1. I see no point why let e; should not shadow argument e here. I do. It is a virtual certainty that this form was used accidentally by the developer, which indicates a flaw in the developer's thinking -- probably due to cut-paste/refactor code having a variable name collision. It should be an early error/warning, just like it is in C. This was essentially the conclusion that was reached when this was discussed at the Nov. TC39 meeting. How is function(x) { let x } any different in this respect from { let x { let x } } ? The same argument can be made in either case. The latter is allowed, the former isn't. In both cases, a block-local let shadows a variable from outer scope. /Andreas This is a suability issue. Languages with c-like syntax seem to generally disallow top level re-declarations of formal parameters, even when they other support block scoped declarations. Presumably because it is assume that shadowing probably not the user intent in most such situations. I researched this last year and captured it in a email exchange I had with Brendan: On Jun 8, 2011, at 11:23 AM, Allen Wirfs-Brock wrote: On Jun 8, 2011, at 10:48 AM, Brendan Eich wrote: On Jun 8, 2011, at 10:28 AM, Allen Wirfs-Brock wrote: Does the semantics have any utility: I don't believe there is any utility in: function (x) {let x=; ...} it simply makes the formal x inaccessible. In all probability this is really a coding or refactoring error. That's not the case that arises from the let* semantics we (almost, you demurred after the meeting) agreed on last September at Mozilla: function (x) {foo(x); let x = bar(); baz(x);} Here (and imagine it is a bigger function), the let semantics from last fall would make a new scope at the let x, as if there were an explicit { before it and one to balance at the end. Users of C++ would be surprised, I think, if they couldn't write something like this. Not that C++ users get undue weight, but you get my point: it depends on what language(s) you are coming from. According to the C++ specification rule I cited in my message the C++ equivalent to the above function would be an error because it redeclares a parameter name at the top level. Throw an extra level of { } around the function body and the results would be different. It would also be an error in Java and C#. I think there is strong precedent and good usability reasons for treating the formal parameter list and the top-level function scope as if they were the same lexical name space. EG, the top level function body is not allowed to shadow (or redeclare) formal parameters. Also, there are backwards compatibility requirements (even in strict mode) that function top level var statements and function declarations are able to change the values of formal parameters. These are defined as SetMutableBinding operations not as creating new bindings. This is a recurring discussion. The discussion always seems to resolve (perhaps with some unhappy acquiesce) that we want to follow the C++/Java/C# (and other similar language) precedent adjusted to deal with legacy var and function semantics. Allen ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: shortcut for private(this)
Erik Arvidsson wrote: let object = ... { let key = Name.create() let secret = {} object.@key = secret } Oh, so all that foo.@bar does is to have different syntax for foo[bar], bar being private name? Than it's not as cool as I thought at all. private keyword in class proposal did something a lot more convenient. It created private name behind the scenes and let people to use private properties with doing prvKeyA = Name.create(); prvKeyB = Name.create(); ... for all private keys they wanted to use. This was _the_ purpose of private keyword. It seems I was overjoyed prematurely... :-/ Herby P.S.: Why not to let obj[privateName]? It is fine. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Jan 18 meeting notes
On Wed, Jan 18, 2012 at 17:27, Waldemar Horwat walde...@google.com wrote: Octal constants: Useful as arguments to chmod. Proposal for 0o123 (as well as 0b01110). MarkM: Concerned about 0O123. Waldemar: Nothing unusul here. We've lived with 36l (meaning 36 long instead of 361) in Java and C++ for a long time. Alternative for octal: 8r123 (but then we'd also want 16r123, 2r0101, and maybe more). Decided to allow 0o and 0b. Unresolved whether to allow 0O and 0B. Persistent weak feelings on both sides on the upper case forms. On behalf of Node.js, thank you. This is the right call. FWIW (ie, not much), I'm personally 100% ambivalent about 0O and 0B. 0O is less visually distinctive than 0o, and caps support isn't really necessary. Nr### is not really necessary. Programming happens primarily in bases 2, 8, 10, and 16. (And 64, but that's mostly just for serializing.) If we have 0b, 0o, 0x, and the default base 10, then that's plenty. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Jan 18 meeting notes
Isaac Schlueter mailto:i...@izs.me January 20, 2012 1:00 PM On behalf of Node.js, thank you. This is the right call. On behalf of old Unix people, thank us -- and you! :-) FWIW (ie, not much), I'm personally 100% ambivalent about 0O and 0B. 0O is less visually distinctive than 0o, and caps support isn't really necessary. See second day notes: Revisited octal/binary constants. Waldemar: Note that we currenty allow both upper and lower cases for a, b, c, d, e, f in hex literals as well as e in exponents and x in hex literals. Breaking symmetry by forbidding upper case for b and o to avoid lookalikes would be nanny language design. We can't forbid lookalikes anyway: { let y = 3; { let у = 7; return y; } } This is a valid ES6 strict function body that returns 3, of course. The second let defines a local variable named with a Cyrillic letter. Decision: Allow upper case B and O to start binary or octal literals. Nr### is not really necessary. Programming happens primarily in bases 2, 8, 10, and 16. (And 64, but that's mostly just for serializing.) If we have 0b, 0o, 0x, and the default base 10, then that's plenty. Everyone agrees -- woohoo! /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Block lambda is cool, its syntax isn't
Just to add weight to my previous mail, you may find it interesting to notice that my proposed syntax match nearly exactly the proposed syntax of the new Mozilla-editored Rust programming language: http://doc.rust-lang.org/doc/tutorial.html#closure-compatibility call_twice({|| I am a stack closure; }); call_twice(fn@() { I am a boxed closure; }); It confirms my feeling about {|| ...}: it should only be allowed in a context where the function still exists; it's a way to return the control back to the calling function when you need to call a callback-able function for some reason. At every other place, you should use 'normal' closures (the language-agnostic equivalent of ECMAScript functions), for which we should have a simplified syntax (aka syntaxic sugar). I don't bother if it has to start by @, #, %, µ, § or anyting else, but I feel strongly about the fact we need it. Now, I think everyone got my point, I leave the final discussion to group members. But, at least, my message was sent. ;-) Best regards, François ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: January 19 meeting notes
On Fri, Jan 20, 2012 at 7:25 AM, Grant Husbands esdisc...@grant.x43.net wrote: Jon Zeppieri wrote: Is there a version of this desugaring that deals with recursive bindings in the initializer expression of the loop? How about something like this? (given for (let varName = initExpr; testExpr; updateExpr) { body } ) { let varName = initExpr; while(true) { if (!testExpr) { break breakTarget; } let tempVar = varName; { // There might be a better way to copy values to/from shadowed variables // (using temporaries seems a bit weak) let varName = tempVar; continueTarget: { body } tempVar = varName; } varName = tempVar; updateExpr; } } That way, all of the variable references in initExpr, testExpr and updateExpr refer to a singular copy and all of the variable references in body refer to the iteration-scoped ones. It doesn't satisfy Desirable Property #3 from the previously cited email: 3) The rewrite rules are the *same,* regardless of whether it's a for (var ...) or a for (let ...) loop. But that's the least important property. So, looking at your example: for (let [i, inc] = [0, function() {i++;}]; i n; inc()) ... I think it now has the desired behaviour. However, people calling inc from inside the body will still be surprised. Yeah, that's a problem. I think solving that probably requires something more advanced than a desugaring, as it means the loop variables captured by that function (or, alternatively, ones captured inside the body) need to point at different variables at different times. That's my suspicion, as well, and I'm curious whether this affects TC39 members' opinion. It's not entirely clear from Brendan's email what caused him, Waldemar, and David Herman to hop off the fence in support of the fresh-binding-per-iteration approach, but it sounds to me like they were initially concerned about needing to specify a complicated semantics and were persuaded by MarkM's argument that the problem could be solved syntactically. There's also an abstraction leakage if one breaks in the body, in that the inner varName doesn't get copied to the outer one. All in all, not a great desugaring, but I thought it might be worth offering. Maybe disallowing capture in the for (let ...;...;...) head would be easier. I still think there's something misleading about taking a loop with an imperative update and re-binding behind the scenes, despite the fact that the problem it's trying to solve is definitely a real problem (I've been bitten by it myself). It's one thing if the difference really isn't observable except in the case where a closure captures the iteration variable (as Sam suggests), since it's hard to imagine anyone wanting the current binding behavior in that case. But the recursive binding cases make me a bit uneasy. -Jon Regards, Grant Husbands. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: January 19 meeting notes
On Fri, Jan 20, 2012 at 5:08 PM, Jon Zeppieri zeppi...@gmail.com wrote: It's one thing if the difference really isn't observable except in the case where a closure captures the iteration variable (as Sam suggests), since it's hard to imagine anyone wanting the current binding behavior in that case. But the recursive binding cases make me a bit uneasy. Heh. Of course, the recursive binding cases *are* cases where a closure captures the iteration variable... The distinction I was trying to draw is between the normal case, where the binding is captured in the body, and the oddball cases I've mentioned, where it's captured in the loop initializer. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: January 19 meeting notes
On 01/19/2012 10:51 PM, Jon Zeppieri wrote: On Thu, Jan 19, 2012 at 11:02 PM, Brendan Eichbren...@mozilla.org wrote: Yes kids, this means we are going with MarkM's lambda desugaring from: https://mail.mozilla.org/pipermail/es-discuss/2008-October/007819.html Is there a version of this desugaring that deals with recursive bindings in the initializer expression of the loop? In my post (https://mail.mozilla.org/pipermail/es-discuss/2008-October/007826.html), I used an example like: for (let fn = function() { ... fn(); ...};;) There are other, related cases, like: for (let [i, inc] = [0, function() {i++;}]; i n; inc()) ... In that earlier post, I wrote that the modifications [to MarkM's desugaring] needed to make these work are pretty straightforward, though I can't recall what I had in mind at the time. Waldemar's option (above) solves the recursive function case, but not the local-inc case. Even as the loop rebinds i and inc, the latter will continue to refer to (and increment) the initial binding of i. Yeah, I know about that. If the updater is something like i++, you want the closures to capture the value of the i before the updater runs. I didn't bring up that case (and we didn't discuss it during the meeting) because, if we choose to do this approach, its resolution is pretty straightforward and we were short on time. I recall seeing Mark's desugaring that already handles it. We'll revisit the details in the future. Waldemar ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: The global object as the global scope instance object
On Jan 20, 2012, at 5:55 AM, Andreas Rossberg wrote: From the TC39 notes: DaveH: What if there are duplicate top-level bindings? MarkM: Top-level let should behave as much as possible the same as concatenated scripts. It's my claim that it is impossible to reconcile all of the following three goals in a way that is even remotely sane: 1. Top-level bindings are aliased as data properties of the global object. 2. Top-level bindings allow redefinition of existing properties of the global object. the rules are more complex than this. see https://bugs.ecmascript.org/show_bug.cgi?id=78 There are important distinctions between own and inherited properties of the global object and properties created using var/function declarations (all we have in ES5) and arbitrary properties directly created by the user or host. 3. Top-level let/const have a temporal dead-zone. Abandoning (3) essentially means abandoning a reasonable const semantics for the toplevel (and future hostile to guards), so we don't want to do that. (For V8, we had long struggles with defining and implementing a const for the (current notion of) top-level that actually makes any sense. We failed.) Temporal dead-zone initialization tracking requires extra state and checking (except for the common cases within functions where it can be statically determined that there are no possible references within the dead zone). This additional requirement is reflected in the specification in the ES5 definition of the CreateImmutableBinding and InitializeImmutableBinding environment record methods. In ES5 this mechanism (and state) was only needed within DeclarativeEnviornmentRecords for (the rarely used) immutable bindings. For the ES6 spec. this has been generalize to also apply to ObjectEnvironmentRecords and to track initialization of both mutable and immutable bindings. The specification doesn't address how an implementation might represent that state but it needs to be somewhere. Closure capturing the state in getter/setter functions may be one way to do this for the global scope. I imagine that there are other ways. For example, global object properties could potentially have an implementation specific not yet initialized bit associated with properties on the global object. Or you might shadow the entire global object with a special kind of environment record that that censors access to instantiated but initialized global bindings (add entry to the censor environment when the binding is instantiated, only create a property in the global object when it is initialized). However, I agree that there are still significant issues with rationally integrating the semantics of global object property access semantics and the ES global declaration semantics. Both for ES5 and ES6. Hence, I would like to suggest another, more moderate idea for a global scope reform: treat the global object similar to a module instance objects. That is: - Top-level bindings (other than var) are reflected as accessor properties on the global object. - They are defined on the global object before the script starts executing. - Their getters/setters simply delegate to the bound variables. whose access presumably perform the necessary checks to enforce the temporal deadzone. - For const bindings, there are no setters. - These properties are non-configurable. It is already the case (for ES5) that all properties created for global declarations are non-configurable (unless created by an eval). - Unlike a module instance object, the global object is extensible (multiple scripts!). This disallows lexical bindings to redefine existing non-configurable properties of the global object (including ones reflecting bindings from earlier scripts), which is checked before the script starts executing. Likewise, let/const-defined properties cannot later be deleted from the global object. I'm not yet convinced that you need to publicly expose such global object properties accessor properties. I think it is possible to hide the mechanisms. Apart from that, not much should change in practical terms. You should pretty much be able to replace var with let. At the same time, static scoping actually is maintained, and there is no issue with temporal dead zones. Moreover, concatenating scripts would not affect the meaning or validity of bindings, AFAICS. Independent of implementation schemes, I think we need to decide on the meaning of the following independent scripts (in different documents) script do not use strict; //window.foo does not exist at this point. foo = 10 const foo=5; //or let print(foo); /script script //window.foo does not exist at this point. window.foo = 10 const foo=5; //or let print(foo); /script script //window.foo does not exist at this point. print(foo); const foo=5; //or let print(foo); /script ... Regarding scope pollution, I think this is best solved by making the global
Re: Block lambda is cool, its syntax isn't
Rust is a static language with many guarantees. It's not really comparable to JS here. JS extended with block-lambdas has no way to force downward-funarg-only contract on functions called with block-lambda arguments. And indeed, nothing goes wrong if those block-lambdas escape via the heap and are called after the enclosing function's activation, which passed the block-lambda down, has returned. Only if the block-lambda does a control effect that would propagate to the enclosing function's activation is there a dynamic error. JS is a dynamic language. When you write it should only be allowed, are you seriously proposing a checkable syntax and static check of some kind? How would that work? (Aside: I wish I had used fn instead of function in 1995!) /be François REMY mailto:fremycompany_...@yahoo.fr January 20, 2012 1:38 PM Just to add weight to my previous mail, you may find it interesting to notice that my proposed syntax match nearly exactly the proposed syntax of the new Mozilla-editored Rust programming language: http://doc.rust-lang.org/doc/tutorial.html#closure-compatibility call_twice({|| I am a stack closure; }); call_twice(fn@() { I am a boxed closure; }); It confirms my feeling about {|| ...}: it should only be allowed in a context where the function still exists; it's a way to return the control back to the calling function when you need to call a callback-able function for some reason. At every other place, you should use 'normal' closures (the language-agnostic equivalent of ECMAScript functions), for which we should have a simplified syntax (aka syntaxic sugar). I don't bother if it has to start by @, #, %, µ, § or anyting else, but I feel strongly about the fact we need it. Now, I think everyone got my point, I leave the final discussion to group members. But, at least, my message was sent. ;-) Best regards, François François REMY mailto:fremycompany_...@yahoo.fr January 19, 2012 12:19 PM It may be just a personnal taste, but I've to agree the current proposal (#() ...) seems very appealing to me. I did not respond to your mail proposing to use the Arrow syntax because it seems obscure to me. The distinction between normal and fat arrow is thin, does not make sense. You either need a function-object (which doesn't have 'this' mapping, has expandos) or a local-function (which has 'this' mapping, just need to be a [Call] target). If you need the first, you need a traditionnal function since you need something not-frozen that can be added to objects as a property at a later time. If you want 'this' mapping, you need something that only makes sense in a local context. Additionnaly, the arrow syntax is illogical. You usually say I want a function of (X,Y) which returns X+Y or I want to transform X in X.toString, not From X, I want to get X.toString(). Freezing a local function seems as acceptable to me as it seemed to others. A LF should only be used in a controlled context where the function itself is just used as a function, not an object. But if it's not acceptable to other members, I'm not against a @(x) syntax that does not offer frozen functions (but I think it's a missed optimization opportunity). The point about Conditionnal Compiling in IE is not valid anymore since Microsoft has deleted HTML Conditionnal Comments because they were not standards (even if they were used a lot), so I don't think the obscure and fewly used JScript CC are meant to stay, especially if it hurts another proposal. In my view of the thing, a local function should be used as a function in the mathematical sense of the term: you give a parameter, it returns its image by the function. The cases we are trying to solve: var inc=#(x) x+1; array.map(#(x) x.toString()); array.filter(#(x) isValid(x)); array.map(#(x) { while(x.previousSibling) x=x.previousSibling; return x; }); For example, I don't see this as a good use-case of a LocalFunction : ... refreshLayout: function(e) { ... requestAnimationFrame(#(e) this.refreshLayout(e)); } ... It should be a block lambda instead, because it's meant to 'continue' the current function in a sort of async while(true) loop. ... refreshLayout: function(e) { ... requestAnimationFrame({|e| this.refreshLayout(e) }); } ... For all of the use cases where a mathematical function is requied, you just need some valid [Call]-able item. You will never add expandos on an function you don't know (ie that you received as a parameter). You'll wrap it before, if you really need that. If you want the full flexibility of a function-as-an-object, it means you need a 'true function'; LF are not meant to replace functions in the long run, they are made to serve the case where you want a short, action-related, contextual function. That means 'this' binding, if needed, just like it's in languages like dotNET. However, I would like
Re: Block lambda is cool, its syntax isn't
(Aside: I wish I had used fn instead of function in 1995!) How much does the fact that a symbol *could* be used (in theory) matter in practice? Most regexes I see for valid identifiers are still of the ^[a-zA-Z_$][0-9a-zA-Z_$]*$ variety. I’d expect λ to be in use in Greece, but how about ƒ (which has been mentioned many times)? It seems very appropriate and is even easy to type on a Mac (easier than square brackets on a German keyboard!). -- Dr. Axel Rauschmayer a...@rauschma.de home: rauschma.de twitter: twitter.com/rauschma blog: 2ality.com ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Block lambda is cool, its syntax isn't
On Jan 20, 2012, at 5:08 PM, Brendan Eich wrote: ... (Aside: I wish I had used fn instead of function in 1995!) At the TC39 meeting we were trying to think of pragma candidates. It wouldn't surprise me if JS programmer would happily trade one: use fn; per file in exchange for being able to use fn as a synonym for function. In terms of character counts, you come out ahead starting with the second function definition. Allen ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Block lambda is cool, its syntax isn't
Allen Wirfs-Brock January 20, 2012 5:41 PM At the TC39 meeting we were trying to think of pragma candidates.It wouldn't surprise me if JS programmer would happily trade one:use fn;per file in exchange for being able to use "fn" as a synonym for "function". In terms of character counts, you come out ahead starting with the second function definition.Allen I have considered this in the past. It always seemed too little, due to return. If it enabled another production: AssignmentExpression : fn Identifieropt ( FormalParameterListopt ) AssignmentExpression (or we just added this unconditionally, without the pragma -- but the pragma is good too) then I'd be happy, finally. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Block lambda is cool, its syntax isn't
On 20/01/2012, at 19:17, Brendan Eich wrote: Jorge mailto:jo...@jorgechamorro.com January 20, 2012 1:22 AM Has a backtick/accent grave ever been considered and/or rejected ? Anonymous function expression: setTimeout( `(){ ... }, 1e3); Named function expression: setTimeout( `name(){ ... }, 1e3); Declarations: `(){ ... } // error: can't declare anonymous functions `name(){ ... } Rejected, that is used by wiki.ecmascript.org/doku.php?id=harmony:quasis already. 1.- There are not quasi literals in the language yet 2.- quasi literals could as well use something else (the acute accent ?) instead 3.- a shorter function syntax is almost at the top in the programmers' wish list for ES.next (unlike quasis) Isn't it -perhaps- too soon to reject ` for functions in favor of quasis ? -- Jorge. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Block lambda is cool, its syntax isn't
Jorge mailto:jo...@jorgechamorro.com January 20, 2012 6:46 PM 1.- There are not quasi literals in the language yet No, quasi-literals are approved for ES6. Already. 2.- quasi literals could as well use something else (the acute accent ?) instead No, that is used for string literals, since JS1 in 1995! 3.- a shorter function syntax is almost at the top in the programmers' wish list for ES.next (unlike quasis) So what? No one except you is asking for ` and quasis won. Please adjust your expecations accordingly. Isn't it -perhaps- too soon to reject ` for functions in favor of quasis ? No. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Block lambda is cool, its syntax isn't
On 21/01/2012, at 02:34, Axel Rauschmayer wrote: how about ƒ (which has been mentioned many times)? It seems very appropriate and is even easy to type on a Mac (easier than square brackets on a German keyboard!). setTimeout( ƒ () { ... }, 1e3) setTimeout( `() { ... }, 1e3) setTimeout( ƒ name () { ... }, 1e3) setTimeout( `name () { ... }, 1e3) ƒ name () { ... } `name () { ... } -- Jorge. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Block lambda is cool, its syntax isn't
On 21/01/2012, at 03:59, Brendan Eich wrote: 2.- quasi literals could as well use something else (the acute accent ?) instead No, that is used for string literals, since JS1 in 1995! Sorry, I don't follow, with that you mean something else or the acute accent ? str = ´agudo´ Error • message: Invalid character '\u0180' -- Jorge. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Block lambda is cool, its syntax isn't
Jorge mailto:jo...@jorgechamorro.com January 20, 2012 7:15 PM Sorry, I don't follow, with that you mean something else or the acute accent ? Oh, not ' but the diacritical on é, you mean? How do I type that on a US or UK keyboard? We are not going to use non-ASCII characters, so you are still barking up the wrong tree. /be str = ´agudo´ Error • message: Invalid character '\u0180' Brendan Eich mailto:bren...@mozilla.org January 20, 2012 6:59 PM Jorge mailto:jo...@jorgechamorro.com January 20, 2012 6:46 PM 1.- There are not quasi literals in the language yet No, quasi-literals are approved for ES6. Already. 2.- quasi literals could as well use something else (the acute accent ?) instead No, that is used for string literals, since JS1 in 1995! 3.- a shorter function syntax is almost at the top in the programmers' wish list for ES.next (unlike quasis) So what? No one except you is asking for ` and quasis won. Please adjust your expecations accordingly. Isn't it -perhaps- too soon to reject ` for functions in favor of quasis ? No. /be Jorge mailto:jo...@jorgechamorro.com January 20, 2012 1:22 AM Has a backtick/accent grave ever been considered and/or rejected ? Anonymous function expression: setTimeout( '(){ ... }, 1e3); Named function expression: setTimeout( 'name(){ ... }, 1e3); Declarations: `(){ ... } // error: can't declare anonymous functions `name(){ ... } Brendan Eich mailto:bren...@mozilla.com January 19, 2012 11:27 AM Axel Rauschmayer mailto:a...@rauschma.de January 19, 2012 9:31 AM Rationale: wouldn’t freezing by default be OK for 98% of the cases? If you want anything else, you can use a traditional function. Then the above syntax as the only function shorthand would be OK. First, #(params) { body } was proposed by Arv and Alex: http://wiki.ecmascript.org/doku.php?id=strawman:shorter_function_syntax Arv and Alex feel strongly that the shorter function syntax (anything shortening 'function' syntax) must not freeze by default. There was lack of clarity about whether completion value as implicit return value was part of the proposal. If so, controvery, since there is a completion value leak hazard. TC39 seems to agree the solution there is something with different look feel, such as block-lambdas. But, making a one-char grawlix shorthand for 'function' while still requiring 'return' is not considered enough of a shorthand. A possible cure here is to support an alternative body syntax: #(params) expr. However, this inverts precedence if done naively. It also runs into trouble trying to prefer an object literal over a block statement. I've worked on both of these in the context of http://wiki.ecmascript.org/doku.php?id=strawman:arrow_function_syntax This superseded shorter_function_syntax, but ran into grammatical issues that have vexed it. But notice that throughout this, no one advancing a proposal advocated freezing by default. JS developers use function objects as mutable objects. Not just to set .prototype, also to decorate with ad-hoc and meta-data properties. Freezing is not wanted by default. I agree that for block-lambdas it's easier to say freeze by default. For merely shorter function syntax, no. Functions are mutable objects by default in JS. This matters for minifiers, which may not be able to see all the mutations but would love to use shorter syntax for 'function' syntax, blindly. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss Axel Rauschmayer mailto:a...@rauschma.de January 19, 2012 9:31 AM Rationale: wouldn’t freezing by default be OK for 98% of the cases? If you want anything else, you can use a traditional function. Then the above syntax as the only function shorthand would be OK. -- Dr. Axel Rauschmayer a...@rauschma.de mailto:a...@rauschma.de home: rauschma.de http://rauschma.de twitter: twitter.com/rauschma http://twitter.com/rauschma blog: 2ality.com http://2ality.com ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Block lambda is cool, its syntax isn't
Axel Rauschmayer January 20, 2012 5:34 PM How much does the fact that a symbol *could* be used (in theory) matter in practice? Most regexes I see for valid identifiers are still of the ^[a-zA-Z_$][0-9a-zA-Z_$]*$ variety.I’d expect λ to be in use in Greece, but how about ƒ (which has been mentioned many times)? It seems very appropriate and is even easy to type on a Mac (easier than square brackets on a German keyboard!). It's hard to type λ on many keyboards. ƒ is easier, but neither is backward-compatible: js ƒ = 1 1 js ƒ 1 js λ = 2 2 js λ 2 We rejected these already for these reasons. I think "use fn;" (real pragma syntax), with the low-precedence assignment-_expression_ fn (params) assign-expr production, wins. What do you think? /be___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Block lambda is cool, its syntax isn't
Various thoughts: How much does the fact that a symbol *could* be used (in theory) matter in practice? Most regexes I see for valid identifiers are still of the ^[a-zA-Z_$][0-9a-zA-Z_$]*$ variety. I’d expect λ to be in use in Greece, but how about ƒ (which has been mentioned many times)? It seems very appropriate and is even easy to type on a Mac (easier than square brackets on a German keyboard!). It's hard to type λ on many keyboards. ƒ is easier, but neither is backward-compatible: js ƒ = 1 1 js ƒ 1 js λ = 2 2 js λ 2 We rejected these already for these reasons. My thinking was: If no one ever uses λ as an identifier (not likely in Greece) or ƒ as an identifier (likely, given that most people seem to think JS identifiers must adhere to the regexes shown above) then one would be free to make them reserved tokens in ES6. Counter arguments: - Hard to type: reading is far more important than typing, it is very easy to adapt tools to help with typing. - Not ASCII: I hardy every encounter non-UTF text files, any more. Non-ASCII seems to work well for Fortress. I think use fn; (real pragma syntax), with the low-precedence assignment-expression fn (params) assign-expr production, wins. What do you think? Having fn would be sweet. For many kinds of pragmas, it would be great if one could configure these per project (or per directory). Then one could put legacy code in one directory and ES6 code in another. And the weight of the pragmas would be negligible. Not sure how to do this, though; reminds me very loosely of CSS (centralized management of style). Would fn make sense as an ES6 breaking change? I’d expect many people to be strongly in favor, possibly as many strongly opposed. Possible research (applies to ƒ, too): - Poll people for their opinion - Search JS code bases for how often the identifier fn is used (how?). -- Dr. Axel Rauschmayer a...@rauschma.de home: rauschma.de twitter: twitter.com/rauschma blog: 2ality.com ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Block lambda is cool, its syntax isn't
Axel Rauschmayer mailto:a...@rauschma.de January 20, 2012 9:24 PM - Hard to type: reading is far more important than typing, it is very easy to adapt tools to help with typing. ƒ is not particularly readable IMHO. It's florin, not mathematical notation I've ever seen. Anyway we can't assume the compatibility break is ok since it can occur in operand context in any expression. - Not ASCII: I hardy every encounter non-UTF text files, any more. Non-ASCII seems to work well for Fortress. Fortress, please. I invite @samth to comment now. I admire Fortress, but it is not an exemplar or nearby language for JS. I think use fn; (real pragma syntax), with the low-precedence assignment-expression fn (params) assign-expr production, wins. What do you think? Having fn would be sweet. For many kinds of pragmas, it would be great if one could configure these per project (or per directory). Then one could put legacy code in one directory and ES6 code in another. And the weight of the pragmas would be negligible. Not sure how to do this, though; reminds me very loosely of CSS (centralized management of style). You make a good point: use fn; may be too much to require in every script element content. Would fn make sense as an ES6 breaking change? I’d expect many people to be strongly in favor, possibly as many strongly opposed. Don't forget that JQuery uses fn as an identifier (and not just following a dot) all over. Possible research (applies to ƒ, too): - Poll people for their opinion These are not decisive. I've been straw-polling audiences for a while. Block-lambdas are doing well, but one must ask nothing, just 'function' and usually get a stronger response than any new syntax. - Search JS code bases for how often the identifier fn is used (how?). See JQuery sources. Unconditionally reserving 'fn' is a non-starter IMHO. Recall also that we are trying to hew to One JavaScript -- few to no refactoring woes moving code in and out of a module {...} container or use strict; code block. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss