Re: Block lambda is cool, its syntax isn't
About 'ƒ': on my keyboard, there's no way to type it. I have to use ALT+its UTF8 keycode, and it doesn't work in all programs. BTW, since the default file format on Windows is not UTF8, expect many developers to use ISO-8859-1 for their JS files. Personnaly, I use Notepad++ which allow me to use UTF8 as default encoding, but I don't expect all devs to do that. About the 'fn' proposal, I'm happy with it. Asking a 'use' statement just for that feature may prove a little excessive but if it can be merged with other can-be-breaking syntax reforms ('use es6'), why not. But, seriously, what really makes it impossible to use # or @? Those would have no compat issues, would require no header. Even if @ would be used in private-name, it would be in a completely different context. It's like the SQL guys who used '%' as wildchar in LIKE strings because '*' was already used as a shortcut in the SELECT operand; those use of the '*' symbol were completely orthogonal, and it would have been possible to allow both. François -Message d'origine- From: Jorge Sent: Saturday, January 21, 2012 4:01 AM To: es-discuss Steen Subject: 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 ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Block lambda is cool, its syntax isn't
This seems pretty easy to enforce to me. function a(x) { let count = 0; [ (x+1)^(x-1), (x*x), (2*x-1) ]; arr.forEach({|x| if((x1)==0) count++; }); return count; } -Message d'origine- From: Brendan Eich Sent: Saturday, January 21, 2012 2:08 AM To: François REMY Cc: es-discuss Subject: 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
Re: Block lambda is cool, its syntax isn't
(sorry, last mail was sent by mistake) This seems pretty easy to enforce to me. function a(x) { let count = 0; let arr = [ (x+1)^(x-1), (x*x), (2*x-1) ] arr.forEach({|x| if((x1)==0) count++; }); return count; } can be compiled as : function a(x) { let count=0; let arr = [...]; let $lambda = { [Call]: {|| ... } }; arr.forEach($lambda); $lambda.[Call] = function() { throw new InvalidTargetException(); } return count; } So, if the 'Array.prototype.forEach' function of has been modified to call the iter function asynchronously, it will not work. As a plus, it allows a very powerful optimisation (block-lambda running in the same frame as the function itself). Regards, François -Message d'origine- From: Brendan Eich Sent: Saturday, January 21, 2012 7:17 AM To: Axel Rauschmayer Cc: es-discuss Subject: 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 ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Block lambda is cool, its syntax isn't
François REMY wrote: About the 'fn' proposal, I'm happy with it. Asking a 'use' statement just for that feature may prove a little excessive but if it can be merged with other can-be-breaking syntax reforms ('use es6'), why not. But, seriously, what really makes it impossible to use # or @? Those would have no compat issues, would require no header. Even if @ would be used in private-name, it would be in a completely different context. It's like the SQL guys who used '%' as wildchar [and may have used *]. True for @, but not so for #. The latter is used to specify freeze. That is, you probably can write #@(x) {x+1}, but ##(x) {x+1} would be ridiculous. François Herby ___ 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 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. From the Haskell experience again: there, one can have language feature options - as pragmas in source code [1] - as options in package descriptor files [2] The former is better for source readability, and for being specific about which files depend on which extensions. The latter is better for avoiding repetition if every source in a package uses the same set of options, and for package readability (making package feature dependencies obvious without having to scan source files). In-source pragmas override package-wide options. One thing that Haskell doesn't have, which I have often wanted, is the ability to define extension groups on a per-project basis: if I always use the same sets of extensions (eg, yield and block scoping, or modules and classes, or ..), then it would be nice to define pragma groups in the package file, and just refer to the group pragma in the source files. That way, use of language features would be explicit in the source, but without repetitive details. However, this is less of an issue in JS than in Haskell (the latter has far more language extensions, with a very conservative base standard, while all ES extensions currently under discussion will be grouped in ES6). Claus [1] http://www.haskell.org/ghc/docs/latest/html/users_guide/pragmas.html [2] extensions: identifier list A list of Haskell extensions used by every module. Extension names are the constructors of the Extension type. http://hackage.haskell.org/packages/archive/Cabal/1.6.0.3/doc/html/Language-Haskell-Extension.html ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Block lambda is cool, its syntax isn't
(sorry, last mail was sent by mistake) This seems pretty easy to enforce to me. function a(x) { let count = 0; let arr = [ (x+1)^(x-1), (x*x), (2*x-1) ]; arr.forEach({|x| if((x1)==0) count++; }); return count; } can be compiled as : function a(x) { let count=0; let arr = [...]; let $lambda = { [Call]: {|| ... } }; arr.forEach($lambda); $lambda.[Call] = function() { throw new InvalidTargetException(); } return count; } So, if the 'Array.prototype.forEach' function of has been modified to call the iter function asynchronously, it will not work. As a plus, it allows a very powerful optimisation (block-lambda running in the same frame as the function itself). Regards, François -Message d'origine- From: Brendan Eich Sent: Saturday, January 21, 2012 7:17 AM To: Axel Rauschmayer Cc: es-discuss Subject: 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 ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Block lambda is cool, its syntax isn't
Great stuff. I’m equally intrigued by the `use fn` pragma: It allows one to selectively break compatibility. Caveat: This kind of pragma introduces a lot of new complexity. Pragmas would indeed become less burdensome if one could configure them on a per-project basis. It corresponds to Eclipse setting different Java versions per source directory. Ideas (not sure that they are worth the added complexity, but wanted to mention them): - Meta-tag points to file that configures pragmas based on paths - Custom, user-defined meta-pragmas that group several pragmas - A pragma that points to a file with several pragmas On Jan 21, 2012, at 11:09 , Claus Reinke wrote: From the Haskell experience again: there, one can have language feature options - as pragmas in source code [1] - as options in package descriptor files [2] The former is better for source readability, and for being specific about which files depend on which extensions. The latter is better for avoiding repetition if every source in a package uses the same set of options, and for package readability (making package feature dependencies obvious without having to scan source files). In-source pragmas override package-wide options. One thing that Haskell doesn't have, which I have often wanted, is the ability to define extension groups on a per-project basis: if I always use the same sets of extensions (eg, yield and block scoping, or modules and classes, or ..), then it would be nice to define pragma groups in the package file, and just refer to the group pragma in the source files. That way, use of language features would be explicit in the source, but without repetitive details. However, this is less of an issue in JS than in Haskell (the latter has far more language extensions, with a very conservative base standard, while all ES extensions currently under discussion will be grouped in ES6). Claus [1] http://www.haskell.org/ghc/docs/latest/html/users_guide/pragmas.html [2] extensions: identifier list A list of Haskell extensions used by every module. Extension names are the constructors of the Extension type. http://hackage.haskell.org/packages/archive/Cabal/1.6.0.3/doc/html/Language-Haskell-Extension.html -- 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: Fixing instanceof (Array.isArray() etc.)?
with postMessage and other standard/secure ways to pass data around the cross frame problem is slowly disappearing unless it's meant to sandbox the Array, as example, of that frame. A classic example is indeed the freedom to extend the way we like a sandboxed Array which hopefully will never interferes with others defined elsewhere, either Array public static methods or those attached to the prototype. If I define Array.prototype.doMyStuff in my frame I *don't* want to affect external environment anyhow plus if the top frame performs an instanceof check against my Array, and the result is true, I may expect that frame to execute my doStuff method which may points to sandboxed, private, properties I don't want other frames to access or change in untrusted code. Array.isArray is OK for Array like objects so that we know that common operation are allowed while instanceof should act exactly as it does now so no confusion cross frame will be possible. Same function/constructor in two different worlds aren't same thing because of the different surrounding world ... same is for Array.isArray unable to grant that object is inheriting the prototype I have enriched in that frame. If I want to be sure an Array comes from my world, instanceof is what I need ... if I want to be sure I can use at least native methods in a generic Array with unknown origin, Array.isArray is the way to go. If instanceof acts like Array.isArray we'll end up with less control and more error prone logic in our applications. br On Fri, Jan 20, 2012 at 7:28 PM, Herby Vojčík he...@mailbox.sk wrote: 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-discusshttps://mail.mozilla.org/listinfo/es-discuss ___ 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 21, 2012, at 12:25 AM, Andreas Rossberg wrote: On 21 January 2012 01:23, Allen Wirfs-Brock al...@wirfs-brock.com wrote: 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. In my proposal, I think you wouldn't need this generalisation. Uninitialised state needs to be tracked for environment bindings only, not for objects. The indirection through accessors makes the latter unnecessary. Yes, but you still have the state because you are creating an actual environment binding for the global variable. BTW, I tried to express you approach (as I understand it) as a desugaring, Here it is script print(foo); let foo=initialized; /script desugars into something like: script { //need to wrap a block around entire top level // declaration instantiation for global let and const binding in this program const __getter_foo = function() {return __foo}; const __setter_foo = function(v) {__foo = v}; Object.defineOwnProperty(this,'foo', {get:__getter_foo, set: __setter_foo,enumerable: true, configurable: false}); //end of declaration instantiation print(foo); //this.foo get accessor, but __foo will be uninitialized so it will actually throw reference error (temporal dead zone let __foo = initialized; //declare and initialize backing store for global variable foo } script ... 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. I don't think so, at least not as cleanly. With accessors, you avoid the whole notion of uninitialised object property, which is painful and pretty intrusive. I sounds to me like you are making an ease of implementation argument. I'm saying that an implementor could hide your proposed mechanism or some other semantically equivalent mechanisms to just expose the mechanism. No double that is true, but it isn't clear to me that hiding the mechanism would be impossible or even excessively burdensome. From a user perspective, it would certainly be better to have it be hidden. In any case, we should do the same for the toplevel and for modules. I believe that the current plan intentionally requires different semantic for the top level and for the top interior level of modules. I agree that there that a scheme that minimized the difference is desirable. It isn't clear to me that eliminating all differences is possible given legacy top level semantics. Independent of implementation schemes, I think we need to decide on the meaning of the following independent scripts (in different documents) Those are the kinds of examples I was alluding to. And the main point of my proposal, and the use of accessors, is that those examples get a natural and coherent meaning, without requiring any special rules. Namely: I just want to make sure we know what we want these to do, independent of implementation strategy, I don't think we should be using accessors or any other implementation tricks in deciding the user facing semantics. script do not use strict; //window.foo does not exist at this point. foo = 10 const foo=5; //or let print(foo); /script The effect of this will be the same as in any other scope, e.g.: { foo = 10 const foo=5; //or let print(foo); } I.e., the first assignment is an (early) error, because you can't assign to a const. If it was a let, it would still be a temporal dead zone violation. The global object doesn't enter the picture at all. I might agree, but first we also would have to consider what the semantics are if window.foo already existed prior to starting the script block and whether or not it is acceptable for breaking the script into two scripts (split after the foo=10 statement) produces a different result. script //window.foo does not exist at this point. window.foo = 10 const foo=5; //or let print(foo); /script This behaves the same as: module W { W.foo = 10 Is the above legal in the module system? The
Re: Block lambda is cool, its syntax isn't
François REMY mailto:fremycompany_...@yahoo.fr January 21, 2012 2:14 AM function a(x) { let count=0; let arr = [...]; let $lambda = { [Call]: {|| ... } }; arr.forEach($lambda); $lambda.[Call] = function() { throw new InvalidTargetException(); } No, we are not specifying dynamic semantics based on a mutation to the [[Call]] internal property. I wrote When you write it should only be allowed, are you seriously proposing a checkable syntax and static check of some kind? I was alluding to ideas such as Ruby's yield operator, which is the only way to name the extra downward-funarg-only block argument, preventing heap escape (but of course, Ruby grew params and so on, so had to deal with escape anyway). This is no static check. It is unacceptable both as semantics and in real implementation costs. Again, in general a block-lambda that escapes and is called after its parent function activation has deactivated is not a bug. It should not be forbidden uncondionally. The only requirement is that control cannot flow back to the defunct activation. Only such attempts via break/continue/return will throw. /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
François REMY mailto:fremycompany_...@yahoo.fr January 21, 2012 1:47 AM (sorry, last mail was sent by mistake) You sent your reply twice, to this thread and another. I replied to the other. As a plus, it allows a very powerful optimisation (block-lambda running in the same frame as the function itself). That optimization is possible in any event, and optimizations are not semantics -- they are unobservable. What you are proposing is an unnecessary semantic restriction. /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
François REMY mailto:fremycompany_...@yahoo.fr January 21, 2012 1:34 AM About the 'fn' proposal, I'm happy with it. Asking a 'use' statement just for that feature may prove a little excessive but if it can be merged with other can-be-breaking syntax reforms ('use es6') Please read the notes from the tc39 meeting, and the recent threads. We are not requiring version opt-in. New syntax is its own opt-in. The problem here is that 'fn' is not new syntax without complex parsing hacks. It's an unreserved identifier in ES1-5. why not. But, seriously, what really makes it impossible to use # or @? We've been over this already. # is for freezing, @ is for private names. The Matlab precedent of @ for function is quite weak (thanks for pointing it out). /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
shortcuts for defining block-local private names, plays nicely with @foo syntax
Hello, since @-prefixed syntax to access private-named properties seems to win in the private grounds (and it is good thing), I'd like kill two birds with one stone: - private keyword seemed to lose its role - to access property via @foo, I must 'let foo = Name.create()' first So let us allow: ... { private foo, bar; ... agent.@foo = ...; ... more uses of @foo and @bar ... } in imperative (code-containing, semicolon-delimited) blocks and ... { private [foo, bar], ... @foo: Date.now(), @bar: cowboys.length, ... aMethod () { ... use @foo and @bar } } in declarative (data-describing, comma-delimited) blocks. In both cases let it be the declaration of (one-time lexical block-local) private names foo and bar. For any curly block. Without need to define these singletons explicitly and wrap them so they are only visible where due, Herby ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
__proto__ security
Hi, This is an attempt to list and discuss how threats of a mutable __proto__ can be prevented and how it is different in the data and accessor property cases. ## One frame Assuming code from 2 parties are running in the same frame (one set of built-ins) - var o = Object.create(Object.freeze({a:1})); o.a = 1; // and may assume it will keep being this way unless shadowing 'a' // passing o to malicious code: o.__proto__ = {a:2}; // back in normal code: o.a; // 2. hey! WTF! - ### How to prevent this? delete Object.prototype.__proto__ Unconditionnally prevents using __proto__ (setting and getting!) for everyone (even those who would have legitimate use cases). In case the property is a configurable accessor, the prototype setting capability can be removed, getting can be left and the property can be made non-configurable. The party who does this can keep the prototype setting capability to herself and share with whoever she trusts. It is also possible to share an attenuated version of the capability (allowing to change the prototype of some objects and not some others) non-extensible as protection Object.preventExtensions(o) would protect just o. This technique and the previous one could be used together. ## Several Object.prototype.__proto__ in the same Vat (synchronous access to several Object.prototype.__proto__) ### Startup If there are several Object.prototype at startup, the work to secure all of them is just the work to secure one (delete or finer-grained version of the accessor case), but repeated. ### Dynamic creation of Object.prototype.__proto__ instances If a new Object.prototype.__proto__ becomes reachable (by opening a same-origin iframe, for instance), if the parent can run before any script in the child, she can do whatever she wants: - deleting childframe.Object.prototype.__proto__ if she wants to defend against what the child could do - redefine any built-ins to attack the child. If the child can run some code before the parent is notified that a new Object.prototype.__proto__ is reachable, she can protect herself against the parent or attack (redefine any built-in) of her parent. ## Questions * What are all the cases in nowadays browsers where a new Object.prototype.__proto__ can be dynamically created? (The only one I can think of is same-domain iframe, but I think there exists some weird rules for one frame to access another by changing its own domain to a subdomain, or something like this) * For each case, who has access to the other first? The creater or the creature? * One difference that is made in the accessor case is that if one party runs before the other, then this first one can keep a reference to the setter. Does this increase the already existing attack surface? David ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
| and function declarations
Hello, there is possibility to use | with function expressions: SuperFun | function Fun () { ... } and it creates parallel constructor and prototype chaining. Would it be possible to allow: function SuperFun | Fun () { ... } to use | in function _declarations_ as well? For simplicity, SuperFun may be PrimaryExpression, not MemberExpression, if problematic. Herby ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: shortcuts for defining block-local private names, plays nicely with @foo syntax
This was already proposed. See the whole strawman, but in particular these sections: http://wiki.ecmascript.org/doku.php?id=strawman:private_names#the_private_declaration http://wiki.ecmascript.org/doku.php?id=strawman:private_names#private_declaration_scoping http://wiki.ecmascript.org/doku.php?id=strawman:private_names#private_declarations_exist_in_a_separate_name_space_parallel_to_the_variable_binding_environment The last really was too much for some folks. It makes the meaning of an identifier after . or before : in an object literal depend on a binding declaration, possibly far above. We could revive this, but deferring it and simplifying led to http://wiki.ecmascript.org/doku.php?id=harmony:private_name_objects which is in ES6. /be Herby Vojčík mailto:he...@mailbox.sk January 20, 2012 3:34 PM Hello, since @-prefixed syntax to access private-named properties seems to win in the private grounds (and it is good thing), I'd like kill two birds with one stone: - private keyword seemed to lose its role - to access property via @foo, I must 'let foo = Name.create()' first So let us allow: ... { private foo, bar; ... agent.@foo = ...; ... more uses of @foo and @bar ... } in imperative (code-containing, semicolon-delimited) blocks and ... { private [foo, bar], ... @foo: Date.now(), @bar: cowboys.length, ... aMethod () { ... use @foo and @bar } } in declarative (data-describing, comma-delimited) blocks. In both cases let it be the declaration of (one-time lexical block-local) private names foo and bar. For any curly block. Without need to define these singletons explicitly and wrap them so they are only visible where due, 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: Block lambda is cool, its syntax isn't
On 21/01/2012, at 05:31, Brendan Eich wrote: 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? Yes, the acute accent. For example. Or something else. You can choose almost any character you want. How do I type that on a US or UK keyboard? I don't know, my keyboard is spanish. Here it's next to the P. We are not going to use non-ASCII characters, so you are still barking up the wrong tree. Aren't you discussing the possibility of using ƒ or λ for functions in this same thread ? Well, the florín is not an ASCII character either. -- 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 21, 2012 12:14 PM On 21/01/2012, at 05:31, Brendan Eich wrote: We are not going to use non-ASCII characters, so you are still barking up the wrong tree. Aren't you discussing the possibility of using ƒ or λ for functions in this same thread ? No. I shot those down in the thread for several reasons. One is inability to type on many keyboards. Another is incompatibility (these are both identifier characters per ES3-5). Well, the florín is not an ASCII character either. Right! /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
-Message d'origine- From: Brendan Eich François REMY mailto:fremycompany_...@yahoo.fr January 21, 2012 1:34 AM About the 'fn' proposal, I'm happy with it. Asking a 'use' statement just for that feature may prove a little excessive but if it can be merged with other can-be-breaking syntax reforms ('use es6') Please read the notes from the tc39 meeting, and the recent threads. We are not requiring version opt-in. New syntax is its own opt-in. The problem here is that 'fn' is not new syntax without complex parsing hacks. It's an unreserved identifier in ES1-5. If it's the case, we should avoid that. Avoiding 'use' for the whole syntax and requiring it just for 'fn' is weird. But I understand we can't use 'fn' per se since it breaks compat. We should try to find something else (it's possible, at least). why not. But, seriously, what really makes it impossible to use # or @? We've been over this already. # is for freezing, @ is for private names. The Matlab precedent of @ for function is quite weak (thanks for pointing it out). Yes, but you didn't respond about where @ is used in private name, and why it makes the @() syntax ambiguous with that use. Since the @ is never used in the private name proposal, I can't check that on my own. My guess is that they don't collide. Anyway, there are still other chars left, we should check if they are easy to type on various keyboards (on my keyboard they are): ['6', '~', 'µ', '£']. Regards, François (BTW, I got the idea about the un-necessary restriction for out-of-scope {|| ...}; instead of making them break, you can restrict them) ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: shortcuts for defining block-local private names, plays nicely with @foo syntax
Brendan Eich wrote: This was already proposed. See the whole strawman, but in particular these sections: http://wiki.ecmascript.org/doku.php?id=strawman:private_names#the_private_declaration http://wiki.ecmascript.org/doku.php?id=strawman:private_names#private_declaration_scoping http://wiki.ecmascript.org/doku.php?id=strawman:private_names#private_declarations_exist_in_a_separate_name_space_parallel_to_the_variable_binding_environment The last really was too much for some folks. It makes the meaning of an identifier after . or before : in an object literal depend on a binding declaration, possibly far above. Thank you. I did not know of these. The problem in the third one (and the solution) are really crazy... I would do the early error if there would be a clash (akin to double let). We could revive this, but deferring it and simplifying led to http://wiki.ecmascript.org/doku.php?id=harmony:private_name_objects I was not trying to revive them (not even after reading part of them). I was reacting to actual situation, that being: privates should be realized through foo.@bar syntax, where bar is identifier (must be declared in some scope) and must have name.create() as its value. Definitely there can be some cases where explicitly creating name.value() and playing with it is beneficial, but most of the time (imnsho) it's the case that you need to use name.create() just as a key in foo.@bar. You should restrict the scope where it is known, and not to export it, since your privacy is gone. The solution that spring to mind is straightforward the use of now-orphaned private keyword for it seems just right. I only proposed (as of actual situation, not as revival of old strawman; as a shortcut for actual calling name.create() at the start of the program or simulated in compilation phase) to use private to declare such identifiers, each pre-filled with name.create() once, with block visibility. For foo.@bar it is very convenient. I really believe big percentage of name.create() is of this sort. Not going against harmony:private_name_objects, just add a convenient use. which is in ES6. /be Herby Herby Vojčík mailto:he...@mailbox.sk January 20, 2012 3:34 PM Hello, since @-prefixed syntax to access private-named properties seems to win in the private grounds (and it is good thing), I'd like kill two birds with one stone: - private keyword seemed to lose its role - to access property via @foo, I must 'let foo = Name.create()' first So let us allow: ... { private foo, bar; ... agent.@foo = ...; ... more uses of @foo and @bar ... } in imperative (code-containing, semicolon-delimited) blocks and ... { private [foo, bar], ... @foo: Date.now(), @bar: cowboys.length, ... aMethod () { ... use @foo and @bar } } in declarative (data-describing, comma-delimited) blocks. In both cases let it be the declaration of (one-time lexical block-local) private names foo and bar. For any curly block. Without need to define these singletons explicitly and wrap them so they are only visible where due, 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: Block lambda is cool, its syntax isn't
François REMY mailto:fremycompany_...@yahoo.fr January 21, 2012 1:00 PM -Message d'origine- From: Brendan Eich François REMY mailto:fremycompany_...@yahoo.fr January 21, 2012 1:34 AM About the 'fn' proposal, I'm happy with it. Asking a 'use' statement just for that feature may prove a little excessive but if it can be merged with other can-be-breaking syntax reforms ('use es6') Please read the notes from the tc39 meeting, and the recent threads. We are not requiring version opt-in. New syntax is its own opt-in. The problem here is that 'fn' is not new syntax without complex parsing hacks. It's an unreserved identifier in ES1-5. If it's the case, we should avoid that. Avoiding 'use' for the whole syntax and requiring it just for 'fn' is weird. Weird doesn't quite dismiss the idea, since JS has 'function' and a shorthand for it -- along with a crucial new production adding an expression-bodied alternative short-function-expression -- is something users keep requesting. If the goal is to shorten 'function' yet keep a mnemonic shorter prefix, nothing grawlix will do. Why not 'fn'? But I understand we can't use 'fn' per se since it breaks compat. We should try to find something else (it's possible, at least). Some here are positive on 'fn'. We have been searching for usable shorter syntax for a while. We should not dismiss 'fn' so quickly. why not. But, seriously, what really makes it impossible to use # or @? We've been over this already. # is for freezing, @ is for private names. The Matlab precedent of @ for function is quite weak (thanks for pointing it out). Yes, but you didn't respond about where @ is used in private name, and why it makes the @() syntax ambiguous with that use. You have to follow the strawmen that haven't made it, in particular http://wiki.ecmascript.org/doku.php?id=strawman:instance_variables and http://wiki.ecmascript.org/doku.php?id=strawman:classes_with_trait_compositionrev=1305852025#private_state and es-discuss threads about foo@bar vs. foo.@bar, just @bar for this-relative addressing, etc. Since the @ is never used in the private name proposal, I can't check that on my own. My guess is that they don't collide. They collide conceptually by overloading @ for two quite different things. If we want shorter *named* function expression syntax, then they collide syntactically with a fatal ambiguity absent more restricted productions: @foo(bar) { expr; } Is this an @-function-expression or a call to private this-relative foo passing bar? Anyway, there are still other chars left, we should check if they are easy to type on various keyboards (on my keyboard they are): ['6', '~', 'µ', '£']. Please re-read the recent messages on this thread: no non-ASCII. Also, ~ is in JS already! /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: shortcuts for defining block-local private names, plays nicely with @foo syntax
Herby Vojčík mailto:he...@mailbox.sk January 21, 2012 1:33 PM Brendan Eich wrote: This was already proposed. See the whole strawman, but in particular these sections: http://wiki.ecmascript.org/doku.php?id=strawman:private_names#the_private_declaration http://wiki.ecmascript.org/doku.php?id=strawman:private_names#private_declaration_scoping http://wiki.ecmascript.org/doku.php?id=strawman:private_names#private_declarations_exist_in_a_separate_name_space_parallel_to_the_variable_binding_environment The last really was too much for some folks. It makes the meaning of an identifier after . or before : in an object literal depend on a binding declaration, possibly far above. Thank you. I did not know of these. The problem in the third one (and the solution) are really crazy... I would do the early error if there would be a clash (akin to double let). The way to resolve the two-lexical-binding-chains issue for private declarations is not to overload . (member expression; also : in object literals), by requiring @ instead: private foo; @foo = bar; // this-relative private foo return @foo === other.@foo; return {@foo: bar}; I *think* we may be pretty close to consensus on this, but I'm not sure. Not in ES6 at this point. The solution that spring to mind is straightforward the use of now-orphaned private keyword for it seems just right. I only proposed (as of actual situation, not as revival of old strawman; as a shortcut for actual calling name.create() at the start of the program or simulated in compilation phase) to use private to declare such identifiers, each pre-filled with name.create() once, with block visibility. For foo.@bar it is very convenient. I really believe big percentage of name.create() is of this sort. Not going against harmony:private_name_objects, just add a convenient use. I quite agree. Requiring Name.create() or new Name() all over is a drag. We should keep honing in on more convenient private name object binding-declaration and binding-use syntax. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: shortcuts for defining block-local private names, plays nicely with @foo syntax
Brendan Eich wrote: Herby Vojčík mailto:he...@mailbox.sk January 21, 2012 1:33 PM Brendan Eich wrote: http://wiki.ecmascript.org/doku.php?id=strawman:private_names#private_declarations_exist_in_a_separate_name_space_parallel_to_the_variable_binding_environment The last really was too much for some folks. It makes the meaning of an identifier after . or before : in an object literal depend on a binding declaration, possibly far above. Thank you. I did not know of these. The problem in the third one (and the solution) are really crazy... I would do the early error if there would be a clash (akin to double let). The way to resolve the two-lexical-binding-chains issue for private declarations is not to overload . (member expression; also : in object literals), by requiring @ instead: private foo; @foo = bar; // this-relative private foo return @foo === other.@foo; return {@foo: bar}; This helps a lot, but there still _is_ (I only proposed a convenient shortcut, not some magic special names for private names) an identifier foo having that private name in its value. So it _would_ clash if foo was defined in code. But I believe that this can be solved by applying analogies from let, var, scopes, shadowing etc. all that machinery. I *think* we may be pretty close to consensus on this, but I'm not sure. Not in ES6 at this point. Well, I am pretty hoping for this. It makes thing much more straightforward (when compared to private in actual class proposal with private store etc. - private names work and are generic). The solution that spring to mind is straightforward the use of now-orphaned private keyword for it seems just right. I only proposed (as of actual situation, not as revival of old strawman; as a shortcut for actual calling name.create() at the start of the program or simulated in compilation phase) to use private to declare such identifiers, each pre-filled with name.create() once, with block visibility. For foo.@bar it is very convenient. I really believe big percentage of name.create() is of this sort. Not going against harmony:private_name_objects, just add a convenient use. I quite agree. Requiring Name.create() or new Name() all over is a drag. We should keep honing in on more convenient private name object binding-declaration and binding-use syntax. /be Herby ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: shortcuts for defining block-local private names, plays nicely with @foo syntax
Herby Vojčík mailto:he...@mailbox.sk January 21, 2012 1:56 PM Brendan Eich wrote: Herby Vojčík mailto:he...@mailbox.sk January 21, 2012 1:33 PM Brendan Eich wrote: http://wiki.ecmascript.org/doku.php?id=strawman:private_names#private_declarations_exist_in_a_separate_name_space_parallel_to_the_variable_binding_environment The last really was too much for some folks. It makes the meaning of an identifier after . or before : in an object literal depend on a binding declaration, possibly far above. Thank you. I did not know of these. The problem in the third one (and the solution) are really crazy... I would do the early error if there would be a clash (akin to double let). The way to resolve the two-lexical-binding-chains issue for private declarations is not to overload . (member expression; also : in object literals), by requiring @ instead: private foo; @foo = bar; // this-relative private foo return @foo === other.@foo; return {@foo: bar}; This helps a lot, but there still _is_ (I only proposed a convenient shortcut, not some magic special names for private names) an identifier foo having that private name in its value. This was not decided, as far as I know. There are two choices: 1. private foo; defines a lexical binding used to denote the private name object, as well as after @ to use it to access a property in an object. 2. Rather, the *only* places foo would be allowed after private foo; above are those after an @. IOW it would be fine to use let foo = 42; and private foo; without conflict. Some further syntax, a la the old #.foo proposal (obsoleted in terms of # now), would be required to reflect foo from lexical-to-the-right-of-@ space into a first-class private name object reference. So it _would_ clash if foo was defined in code. But I believe that this can be solved by applying analogies from let, var, scopes, shadowing etc. all that machinery. I'm not sure what you mean. Choice (1) above allows shadowing. Choice (2) doesn't have any conflict. I *think* we may be pretty close to consensus on this, but I'm not sure. Not in ES6 at this point. Well, I am pretty hoping for this. It makes thing much more straightforward (when compared to private in actual class proposal with private store etc. - private names work and are generic). I may be overoptimistic about consensus. The choice (1) vs. (2) remains open, IIRC. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: shortcuts for defining block-local private names, plays nicely with @foo syntax
Brendan Eich wrote: Herby Vojčík mailto:he...@mailbox.sk January 21, 2012 1:56 PM Brendan Eich wrote: private foo; @foo = bar; // this-relative private foo return @foo === other.@foo; return {@foo: bar}; This helps a lot, but there still _is_ an identifier foo having that private name in its value. This was not decided, as far as I know. There are two choices: 1. private foo; defines a lexical binding used to denote the private name object, as well as after @ to use it to access a property in an object. 2. Rather, the *only* places foo would be allowed after private foo; above are those after an @. IOW it would be fine to use let foo = 42; and private foo; without conflict. Some further syntax, a la the old #.foo proposal (obsoleted in terms of # now), would be required to reflect foo from lexical-to-the-right-of-@ space into a first-class private name object reference. Oh. I favor 1. Inspired by latest notes and for(let...) I would see { private foo; ... } desugared to { let foo = _the_real_foo; ... } where _the_real_foo is defined somewhere at the module or program level such that it will not clash (hardwired private name or index to a table or whatever) and the rest is just reusing existing rules. 2. is too magical (for me). /be Herby ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: shortcuts for defining block-local private names, plays nicely with @foo syntax
Brendan Eich mailto:bren...@mozilla.org January 21, 2012 4:39 PM Er, const, I hope -- not let. Right? And _the_real_foo should be expanded: { private foo; ... } desugars to { const foo = Name.create(foo); ... } with Name.create imported appropriately. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Shouldn't timers be specified?
Correction: it is specified in HTML5 here http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#timers . Suffice to say that a DOM specification isn't sufficient for something so central to JavaScript, nor is it the specification currently followed by browsers anyway. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Shouldn't timers be specified?
Absolutely agree. I don't see a place for Node's 1ms resolution in browsers, which was the impetus for raising the issue. I see a place for Node (and other non-browser platforms) to implement their own host timers that provide higher resolution (In fact Node's process.nextTick(callback) is a good example of host functionality that's useful but wouldn't belong in a JS spec). But the point is that the lack of specification has already resulted in incompatible implementations of ostensibly the same basically required core language functionality. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Shouldn't timers be specified?
Sorry to spam this thread but I wanted to get the relevent points in up front: 'Actually, wait a minute -- I think I disagree with you here. WHATWG specifies the specific event queue of the browser. Node.js has its own event queue. Others may as well. The unofficial agreement of JS has always been, no matter where you embed it, it should never have pre-emption. So what we would be specifying is the rough concurrency framework required of any JS embedding. In other words, it would be a more abstract specification of event queues, of which WHATWG event queues are a valid implementation.' Spec the unofficial agreement, including the minimal(/maximal if it exists) time constraints, and go from there. This is needed. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Fixing instanceof (Array.isArray() etc.)?
with postMessage and other standard/secure ways to pass data around the cross frame problem is slowly disappearing unless it's meant to sandbox the Array, as example, of that frame. A classic example is indeed the freedom to extend the way we like a sandboxed Array which hopefully will never interferes with others defined elsewhere, either Array public static methods or those attached to the prototype. If I define Array.prototype.doMyStuff in my frame I *don't* want to affect external environment anyhow plus if the top frame performs an instanceof check against my Array, and the result is true, I may expect that frame to execute my doStuff method which may points to sandboxed, private, properties I don't want other frames to access or change in untrusted code. Makes sense. If this kind of issue went away, that would be great! Array.isArray is OK for Array like objects so that we know that common operation are allowed while instanceof should act exactly as it does now so no confusion cross frame will be possible. Note: Array.isArray() in general returns false for array-like objects: $ (function () { return Array.isArray(arguments) }()) false -- 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