Re: On class literals possibly not making it into ECMAScript.next
I think most of es.next will be transpiled for a long period of time. Given Dart and Coffescript, transpilers will become more and more important and more easily incorporated into the development cycle as evidenced by Dart's recent editor announcement. On Nov 6, 2011, at 3:29 AM, Joe Developer joe.d.develo...@gmail.com wrote: jQuery is a somewhat poor / extreme example - jQuery has taken a monolithic approach to code structuring - while more modern and full featured frameworks tend towards load-on-demand, and hence can offer 'capability-loading'. That said, I do think that it is worth keeping in mind that there will continue to be a considerable lag between ES.current and ES.baseline for browser apps - when you guys introduce constructs such as | in lieu of 'jury-riggable' approaches such as commandering Object.extend etc then it means that such code will be subject to de-facto environment lockin and running in 'less capable' environments will require maintaining separate codebases / transpile steps. The goal may be to make JS easier - but it is more likely to have the opposite effect, code containing | will straight up break outside of controlled environments. When I see things like | and .{ I get a bit queasy, but as long as you guys also cater for more backwards compatible constructs I guess we can all get along. On Sat, Nov 5, 2011 at 7:25 AM, Rick Waldron waldron.r...@gmail.com wrote: Still the same point, unified API under single namespace, for the same reasons. ES.next will still exist in the same hostile web of today. /Rick On Nov 4, 2011, at 8:19 PM, Axel Rauschmayer a...@rauschma.de wrote: I think we are arguing different points: All I meant is – how would you structure jQuery in ECMAScript.next (in the future, using the proposed modules)? On Nov 5, 2011, at 1:14 , Rick Waldron wrote: ...But that's not the point. The point is to have a _single_ namespaced, unified API; this helps keep the library small, reduces potential conflict with other libs, makes it easier to learn, easier to extend and easier to maintain. jQuery deals in reality, not the fantasy world of spec drafts and syntax bikeshedding, and that reality is the web _today_. To be clear, you're aware that jQuery supports a completely compatible API across all browsers that it supports, right? That means that nothing goes into jQuery that cannot be reproduced in... IE 6, 7, 8 9 Firefox 3.6, 6 7 Chrome 14, 15 Safari 5, 5.1 Opera 11.01, 11.5 It's not productive to suggest that jQuery has done some kind of poor man's module or that it could've done better if it had modules, or that it should, or even might be able to take advantage of some kind of bleeding edge ES.next Module system. jQuery promises that it will not break back compat from one release to the next, and when we do, we _hustle_ to get point release bug fixes out the door. When 24.6 million[1] sites are using a piece of code - because they can trust that it works and that it won't wreak havoc on their site from one version to the next. -- 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 ___ 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: Minimalist Classes
I noticed the absence of setter's, getter's. Would this be valid syntax? set health(value) { if (value 0) { throw new Error(Health must be non-negative.); } @health = value; } On Nov 3, 2011, at 12:17 AM, Brendan Eich bren...@mozilla.com wrote: What is super-intuitive about running 'class C' up against an arbitrary expression, which is then evaluated and *copied* (details fuzzy here) as the class prototype? Arguments about feelings and intuition are not that helpful. Saying why you need to construct a class that way, where no such object copying primitive exists in JS, would be more helpful. IOW, what's the use-case? /be On Nov 2, 2011, at 11:03 PM, Matthew J Tretter wrote: So to clarify, is the dynamic super issue the whole reason that Jeremy's dynamic construction of classes is considered not doable? Because it seems to me that super may not be worth that trade off. Besides, Python's super implementation requires the hardcoding of the class and that doesn't cause much of a stink. If something similar would give us this super-intuitive syntax and the ability to build classes from arbitrary object literals, it seems like not a big loss. ___ 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: Minimalist Classes
Does object@name break encapsulation? One could mutate object@name for any instance of the class passed in via a parameter for example. On Nov 2, 2011, at 8:01 AM, David Bruant bruan...@gmail.com wrote: Le 02/11/2011 14:26, Jeremy Ashkenas a écrit : (Full Disclosure: I'm still very opposed to const, private, and their object-lockdown friends, ) Could you elaborate on this point? All object-lockdown I can think (non-configurability, non-writability, non-enumerability, private names, const variables, const classes) of is optional. Why are you against them? Regarding const, it's an optional keyword basically telling the interpreter hey, the value isn't suppose to change at runtime, please ensure it!. It prevents bugs of mistakenly redefining something that shouldn't be redefined. Why are you opposed to this? Regarding private, I'm puzzled. Having private attributes in objects is necessary to implement encapsulation and get all the benefits of good object-oriented practices. A generation of JS programmers have used scope constructs and the var keyword to enable some privacy. I'm all in favor of providing a declarative support for what people have done for years anyway. What is wrong with private? Once again, all of this is optional, nothing forces you to use new features of the language. I will personnally never use multi-line strings, but I don't mind the feature being in the language. I was about to say if you're unsatisfied, create a language which doesn't provide features you don't like, like Coffeescript, but... humm... So, why being against the introduction of features in the language? David ___ 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: Minimalist Classes
On Nov 2, 2011, at 1:20 PM, Brendan Eich bren...@mozilla.com wrote: On Nov 2, 2011, at 1:17 PM, Kam Kasravi wrote: On Nov 2, 2011, at 11:29 AM, Brendan Eich bren...@mozilla.com wrote: On Nov 2, 2011, at 11:17 AM, David Bruant wrote: See my reply to Kam. We're not sugaring instance-private ivars. I am proposing something we agreed to in Nov. 2008: sugaring class-private ivars. Ok, that's what I was missing. What were the rationale? use cases? Doesn't the latest harmony class proposal define private within the constructor? I assume this proposal would supersede the Nov 2008 meeting Grammar pasted below: Are you asking a procedural question, or something? If so, bzzzt. :-| I'm hacking a gist forked from Jeremy's. But TC39 is sticking to consensus where we can. The wiki'ed class proposal does have class-private instance variables. It simply mislocates the private declaration inside the constructor. Again, this proposal is in trouble and the gist'ing is an attempt to rescue it, outside the confines of the somewhat-overconstrained TC39 setting. Understood, just wanted to clarify exactly what the TC39 consensus was in respect to the harmony class proposal. I do think your gist has advantages over the harmony class proposal both in terms of removing the public keyword and clarifying private-class var declaration and semantics. My only concern would be users/framework writers opting for the closure pattern in lieu of using private to prevent the Account use case I noted. That is, I would normally interpret private to mean no access unless you're the instance and within class scope. Here private means no access unless you're any instance and within class scope. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Loyal Opposition to Const, Private, Freeze, Non-Configurable, Non-Writable...
On Nov 2, 2011, at 1:27 PM, Mikeal Rogers mikeal.rog...@gmail.com wrote: On Nov 2, 2011, at November 2, 201110:57 AM, Brendan Eich wrote: On Nov 2, 2011, at 9:51 AM, Mikeal Rogers wrote: On Nov 2, 2011, at November 2, 20119:30 AM, Quildreen Motta wrote: freeze does not add anything new to an object. If you don't want to change the shape of an object ... don't change the shape of the object. Again, immutability isn't just about security, but optimisation as well. You could also look at shared-memory threads, because I think they make a hell of an argument for frozen objects or immutability. The last time we looked at freezing a few core objects in node.js we found that v8 was actually slower with them frozen and backed them out, which is probably a good thing. I'm very skeptical of the new language feature for optimization argument ever since the static typing debate in ES4 and the tracer work Mozilla did shortly after. Type inference is doing well for us now. I agree in general. However, there's a reason Dart did what it did. With JS, you have to guard, or provide an invalidation protocol, in case someone shadows an inherited property: var a = [], b = {m: function (i) { return i * i; }}, c = Object.create(b), d = Object.create(c); for (var i = 0; i BIG; i++) { a[i] = d.m(i); if (rarely(i)) { c.m = function (i) { return 42 * i; }; } } This is a contrived case, but in general, because JS objects are mutable, and when they're used as prototypes they stand in for class vtables, something has to pay a price. Either you worry about checking on every d.m(i) call that the cached target method in b is still the one to call, or you emit code that doesn't check but tear it up and throw it away when c.m is injected and shadows b.m. This is fine with me and worth the price, but it clearly is not for everyone. I don't think I've ever heard an active JavaScript developer, who has been programming in JavaScript longer than 6 months, ask for private class or instance variables. Maybe you have, you talk to more people than I do. I do hear this a lot from people who don't use JavaScript and likely won't even if we add it. The module pattern, arguably one of the most common JS patterns out there is predicated on making internal variables 'private' via a closure, and only returning a 'public' API. For any class/type defined, there are vars that are likely to be only used within the implementation or they are vital to the class/type contract. Both are compelling reasons to have private. I'm not just talking about implementors, either. Some users will want to know d.m isn't going to change. They may not want to know that it's b.m, mind you -- they simply won't want that c.m assignment to be legal, or else if they do support such a thing, they don't want it to affect d's vtable. Ok, so such people should use another language than JS. Or, perhaps, they could freeze c and b. I would argue that developers who rely on these kinds of assurances are actually slowing down their own, and others, productivity. Assuming they wrote the perfect method and it should never be changed is a grand claim for anyone who isn't Donald Knuth. Assuming that the consumer of their code is responsible for their own bugs if they introduce them with monkey patching class methods seems fair. I think this is what Jeremy is getting at, not having these features (or at least obscuring their use to be a different, more explicit pattern, using closures) actually leads to longer term productivity and sustainability in the community and I tend to agree I may have said this before, but the lack of these features may actually be part of what has allowed JavaScript to thrive and, for lack of a better term, to win. Jeremy brought up some compelling examples. Then they'd have parity, once V8 and other engines got around to optimizing accordingly. (It's bogus for you to infer too much from the state of optimization vs. new features.) I was just trying to debunk the claim that these features are necessarily faster and will vary with implementation. Most features can lend themselves to optimizations but, as you pointed out, at what cost. /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: Loyal Opposition to Const, Private, Freeze, Non-Configurable, Non-Writable...
Declaring vars in a function, private vars in a class or not using export in a module often have similar objectives and ultimately is the decision of the author. For serializable data structures that are reified in various places, private is overkill and would complicate JSON.{stringify,parse}. Perhaps an author wants to keep a definition 'open' and sees no reason for private. The language should enable but not require a variety of use cases which I think is the main point here. On Nov 2, 2011, at 2:56 PM, Jake Verbaten rayn...@gmail.com wrote: I don't think I've ever heard an active JavaScript developer, who has been programming in JavaScript longer than 6 months, ask for private class or instance variables. Your own code: https://github.com/mikeal/npmjs.org/commit/c0d9cc77e79504b9a7c23b4fac735dde97444054#L3R10 Line 35, you define the function stopBuffering (keeping only relevant parts): function File (options) { var stopBuffering = function () { // ... } } Why didn't you do this.stopBuffering = function(){}? Maybe you used the keyword var, but you effectively created a private method of your File class. With a class syntax, you would have used the private keyword to achieve the same thing. Maybe you don't call it this way, but you use (and de facto ask for) privacy. I think making such broad statements as every local variable is actually a 'private' variable is just plain silly. To me that looks like a utility method for code organisation points. private means its a private method/data that's used in other methods of an object. That particular function is not used in any method. And no, with class syntax it would not be private, it would still be a utility function inside the constructor. I personally second that we don't need private or instance variables. ___ 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: Harmony transpilers
I've implemented several harmony proposals in es.next by expanding the grammar in pegjs (https://github.com/dmajda/pegjs/blob/master/examples/javascript.pegjs). The AST and generator is defined using es.next classes and modules. I was thinking of converting the derived classes in the ast and generator modules to use the proto operator | rather than 'extends' since the LHS is desugared to a function. I'm using '@' for private names but this is a moving target and looks like it will be replaced by private names. It works similarly to coffeescript in that it generates plain javascript. It's been a side project I've worked on when I've had free time. It's in my private github repo and works with node using websockets (so you can load the parser into the browser). Could make it public if I have some time to spend on it this weekend. I like my approach because the grammar is easy to extend and I don't know of any other transpiler whose ast/generators are in the target language. On Oct 11, 2011, at 9:10 AM, Jake Verbaten rayn...@gmail.com wrote: One of the reasons traceur is not suitable is that it's a product of google and thus not neutral. I've actually asked traceur whether they intent to become a full es harmony compliant transpiler but there was no response. And another reason would be that it currently implements some strawmans that conflict with harmony proposals. For example it's class mechanism is not loyal to the _current_ es harmony proposal, another example would be traceur generators not using the `function*` notation. On Tue, Oct 11, 2011 at 4:42 PM, John J Barton johnjbar...@johnjbarton.com wrote: On Tue, Oct 11, 2011 at 6:41 AM, Juan Ignacio Dopazo dopazo.j...@gmail.com wrote: Hi! Is there anyone working on a Harmony transpiler besides Traceur? I'd like to understand why Traceur is not suitable. As far as I understand it was written to study new directions in JS. jjb It'd be really useful to have a transpiler that justs desugars (what's possible to desugar) without using a library like Closure, the way CoffeeScript is working nowadays. Thanks, Juan ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Minor extension to Set Literal Prototype operator as minimal classes
If the | operator's intent is to create new classes easily via composition, it seems like its grammar should be 'class' friendly eg the LHS | RHS could be a class and/or class expression as in the following: class Person { constructor(name) { private name; @name = name; } describe() { return Person called +@name; } } class Worker = Person | class { constructor(name, title) { private title; super(name); @title = title; } describe() { return super.describe()+ (+@title+); } }; However the grammar as described would exclude the above. Would the Set Literal Prototype grammar eventually be reconciled with the class grammar or do you feel it's a replacement? I ask because I suspect an application programmer would not understand why the RHS could take an ObjectLiteral (for example) but not an anonymous class - after all both contain 'class' elements. If the answer is 'no', it seems like '|' fragments the ways to define a class shape where LHS | { constructor: function(name,title) { Person.call(this,name); this.title = title; } } works but LHS | class { constructor(name,title) { private title; super(name); @title = title; } does not. From: Allen Wirfs-Brock al...@wirfs-brock.com To: Russell Leggett russell.legg...@gmail.com Cc: Axel Rauschmayer a...@rauschma.de; es-discuss es-discuss@mozilla.org Sent: Sunday, October 2, 2011 3:19 PM Subject: Re: Minor extension to Set Literal Prototype operator as minimal classes On Oct 2, 2011, at 1:32 PM, Russell Leggett wrote: ... I can see the recursive stache useful in some situations (although it is another syntax addition to object literals). It would allow for the ability to apply a deeply nested patch to an object, which is sort of interesting to think about. However, what I think this pattern, the original pattern, and Axel's pattern all lack is that it places too much emphasis on class members, and not enough on the prototype. Perhaps I'm being too nit-picky now, but I find that class/static members are a whole lot more rare than prototype/instance members. My proposal was shooting for a sweet spot where the 90% (a made up number of course) case of a constructor and some prototype methods could be handled in one object literal, effectively the same code as the body of a potential class literal. The problem with: const ClassName = SuperClass | { constructor(/*constructor parameters */) { //constructor body super.constructor(/*arguments to super constructor */); this.{ //per instance property definitions } } method1(){ return super.method1(); } method2(){} prop1:Properties unlikely, but allowed }.{ //class properties staticMethod(){} }; Is that the SuperClass | { ... }part evaluates to the prototype object, not the constructor function and hence what you would be naming is the prototype. This, in general, is how stache has to work for arbitrary object literals where all you really are trying to do is set the [[Prototype]]. There really isn't anything special in your pattern that distinguishes it from that simple object case. As has been discussed on this list before, if you are actually using prototypal inheritance to construct your object abstractions then it really is the prototype you want to name rather than the constructor function. EG: const Person = Mammal | { name: 'John Doe', constructor(sex,name) { super.constructor(sex); this.{name} } } console.log(typeof Person); //'object', not 'function' console.log(Person.name); //'John Doe' Person is the prototypal person. You would then really like to create new Person instances like: let joe = new Person('male','Joe Smith'); // means roughly joe = Object.create(Person).constructor('male','Joe Smith') console.log(joe.name); //'Joe Smith' console.log(Object.getPrototypeOf(joe).name); //'John Doe' However, new currently throws when applied to non-function objects. This is something I would like to fix for ES.next. Also, there is also an issue that in a definition like mine above the constructor function that is being created really should automatically get a 'prototype' property that back references the object with the 'constructor' property. Allen ___ 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: Minor extension to Set Literal Prototype operator as minimal classes
On Oct 3, 2011, at 3:11 AM, Axel Rauschmayer a...@rauschma.de wrote: Keep in mind that class literals are syntactic sugar and that Russells suggestion was about using his modified | operator as a replacement for class literals. What you are suggesting is a generic | operator, where both LHS and RHS can be arbitrary expressions. Actually no - see below... However, the point of | is that the RHS must be a literal (function declaration or object literal), because it actually should be considered to be a part of that literal. It creates the RHS with the appropriate prototype. Allowing any expression as the RHS would mean that the prototype of the RHS would have to be changed and that is much more tricky. The grammar rules for ProtoLiteral cover the various literal types including regex, so they're fairly broad now. I wasn't suggesting any expression, just integration of the class grammar since the intent of the '|' operator seems to be to make it easier to extend classes. Having the '|' operator exclude class constructs seems counterintuitive unless it is an alternative syntax to the classes proposal. On Oct 3, 2011, at 11:35 , Kam Kasravi wrote: If the | operator's intent is to create new classes easily via composition, it seems like its grammar should be 'class' friendly eg the LHS | RHS could be a class and/or class expression as in the following: class Person { constructor(name) { private name; @name = name; } describe() { return Person called +@name; } } class Worker = Person | class { constructor(name, title) { private title; super(name); @title = title; } describe() { return super.describe()+ (+@title+); } }; However the grammar as described would exclude the above. Would the Set Literal Prototype grammar eventually be reconciled with the class grammar or do you feel it's a replacement? I ask because I suspect an application programmer would not understand why the RHS could take an ObjectLiteral (for example) but not an anonymous class - after all both contain 'class' elements. If the answer is 'no', it seems like '|' fragments the ways to define a class shape where LHS | { constructor: function(name,title) { Person.call(this,name); this.title = title; } } works but LHS | class { constructor(name,title) { private title; super(name); @title = title; } does not. From: Allen Wirfs-Brock al...@wirfs-brock.com To: Russell Leggett russell.legg...@gmail.com Cc: Axel Rauschmayer a...@rauschma.de; es-discuss es-discuss@mozilla.org Sent: Sunday, October 2, 2011 3:19 PM Subject: Re: Minor extension to Set Literal Prototype operator as minimal classes On Oct 2, 2011, at 1:32 PM, Russell Leggett wrote: ... I can see the recursive stache useful in some situations (although it is another syntax addition to object literals). It would allow for the ability to apply a deeply nested patch to an object, which is sort of interesting to think about. However, what I think this pattern, the original pattern, and Axel's pattern all lack is that it places too much emphasis on class members, and not enough on the prototype. Perhaps I'm being too nit-picky now, but I find that class/static members are a whole lot more rare than prototype/instance members. My proposal was shooting for a sweet spot where the 90% (a made up number of course) case of a constructor and some prototype methods could be handled in one object literal, effectively the same code as the body of a potential class literal. The problem with: const ClassName = SuperClass | { constructor(/*constructor parameters */) { //constructor body super.constructor(/*arguments to super constructor */); this.{ //per instance property definitions } } method1(){ return super.method1(); } method2(){} prop1:Properties unlikely, but allowed }.{ //class properties staticMethod(){} }; Is that the SuperClass | { ... } part evaluates to the prototype object, not the constructor function and hence what you would be naming is the prototype. This, in general, is how stache has to work for arbitrary object literals where all you really are trying to do is set the [[Prototype]]. There really isn't anything special in your pattern that distinguishes it from that simple object case. As has been discussed on this list before, if you are actually using prototypal inheritance to construct your object abstractions then it really is the prototype you want to name rather than the constructor function. EG: const Person = Mammal | { name: 'John Doe', constructor(sex,name) { super.constructor(sex); this.{name
Re: Class literals: does public still make sense?
If the intent of classes is to provide a declarative syntax for its 'shape' then dropping the private syntax in lieu of private name objects seems to run counter to this philosophy. As I understand it, private name objects are a runtime construct dependent on the '@name' module and thus have no declarative definition. Are there yet to be defined ways to declaratively define/discover an instances private namespace? From: Axel Rauschmayer a...@rauschma.de To: Mark S. Miller erig...@google.com Cc: es-discuss es-discuss@mozilla.org Sent: Sunday, September 25, 2011 8:59 AM Subject: Re: Class literals: does public still make sense? Static analysis of the constructor should be able to do most of what public does, but after consulting the spec again, I see its advantages: - Const classes make public properties unconfigurable and read-only. - Shouldn’t public properties in non-const classes be unconfigurable, too? Are such properties expected to be configured? Read-only properties could be created via public const. On Sep 25, 2011, at 4:09 , Mark S. Miller wrote: Hi Axel, This was one of the options we considered. At one point it was the main class proposal. The problem is that since it looks exactly like an imperative assignment to a property of this, it should have the semantics of an imperative assignment to a property of this. In fact, the current class proposal does not disallow it, and gives it exactly these semantics. However, when used as the only or main means of initializing an instance, it defeats one of the main purpose of classes: The shape of the instances of a given class are no longer a static declarative feature of the class itself. Again, the contrast with modules is instructive. A CommonJS module exports only by imperative assignment to properties of an exports object. A proposed ES-next module exports by annotating top level declarations with export. As an abstraction mechanism, it would be bizarre to have good abstraction properties only for abstractions that cannot be multiply instantiated. On Sat, Sep 24, 2011 at 4:17 PM, Axel Rauschmayer a...@rauschma.de wrote: Without private members, do we still need the keyword public in class literals? For example, instead of constructor(geometry, materials) { super(geometry, materials); public identityMatrix = new THREE.Matrix4(); public bones = []; public boneMatrices = []; ... } I find the following just as intuitive, without the need for the keyword public: constructor(geometry, materials) { super(geometry, materials); this.identityMatrix = new THREE.Matrix4(); this.bones = []; this.boneMatrices = []; ... } Similarly intuitive is something that I’ve seen somewhere – passing through constructor arguments as members. class Point { constructor(this.x, this.y) { } } I don’t think public helps, I think it makes things *less* intuitive. -- Dr. Axel Rauschmayer a...@rauschma.de twitter.com/rauschma home: rauschma.de blog: 2ality.com ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss -- Cheers, --MarkM -- Dr. Axel Rauschmayer a...@rauschma.de twitter.com/rauschma home: rauschma.de blog: 2ality.com ___ 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: Class literals: does public still make sense?
Would the new private syntax then go from (old syntax) class Monster { // The contextual keyword constructor followed by an argument // list and a body defines the body of the class’s constructor // function. public and private declarations in the constructor // declare and initialize per-instance properties. Assignments // such as this.foo = bar; also set public properties. constructor(name, health) { public name = name; private health = health; } // An identifier followed by an argument list and body defines a // method. A “method” here is simply a function property on some // object. attack(target) { log('The monster attacks ' + target); } // The contextual keyword get followed by an identifier and // a curly body defines a getter in the same way that get // defines one in an object literal. get isAlive() { return private(this).health 0; } // Likewise, set can be used to define setters. set health(value) { if (value 0) { throw new Error('Health must be non-negative.') } private(this).health = value } // After a public modifier, // an identifier optionally followed by = and an expression // declares a prototype property and initializes it to the value // of that expression. public numAttacks = 0; // After a public modifier, // the keyword const followed by an identifier and an // initializer declares a constant prototype property. public const attackMessage = 'The monster hits you!'; } to: class Monster { // The contextual keyword constructor followed by an argument // list and a body defines the body of the class’s constructor // function. public and private declarations in the constructor // declare and initialize per-instance properties. Assignments // such as this.foo = bar; also set public properties. constructor(name, healthvalue) { public name = name; module name from @name; private health = name.create(); this[health] = healthvalue; } // An identifier followed by an argument list and body defines a // method. A “method” here is simply a function property on some // object. attack(target) { log('The monster attacks ' + target); } // The contextual keyword get followed by an identifier and // a curly body defines a getter in the same way that get // defines one in an object literal. get isAlive() { return this[health] 0; } // Likewise, set can be used to define setters. set health(value) { if (value 0) { throw new Error('Health must be non-negative.') } this[health] = value } // After a public modifier, // an identifier optionally followed by = and an expression // declares a prototype property and initializes it to the value // of that expression. public numAttacks = 0; // After a public modifier, // the keyword const followed by an identifier and an // initializer declares a constant prototype property. public const attackMessage = 'The monster hits you!'; } ? If so it seems odd, privately named variables like health, although declared in the constructor are implicitly available throughout the class. On Sep 25, 2011, at 2:08 PM, Brendan Eich bren...@mozilla.com wrote: On Sep 25, 2011, at 1:04 PM, Kam Kasravi wrote: If the intent of classes is to provide a declarative syntax for its 'shape' then dropping the private syntax in lieu of private name objects seems to run counter to this philosophy. We did not agree to drop the private declaration syntax at the July TC39 meeting. Perhaps my understanding of our agreement then does not match Marks? What we agreed to drop was the private(this) straw syntax in the classes proposal, in favor of this[x], this[y], for private-declared private name objects x and y. /be As I understand it, private name objects are a runtime construct dependent on the '@name' module and thus have no declarative definition. Are there yet to be defined ways to declaratively define/discover an instances private namespace? From: Axel Rauschmayer a...@rauschma.de To: Mark S. Miller erig...@google.com Cc: es-discuss es-discuss@mozilla.org Sent: Sunday, September 25, 2011 8:59 AM Subject: Re: Class literals: does public still make sense? Static analysis of the constructor should be able to do most of what public does, but after consulting the spec again, I see its advantages: - Const classes make public properties unconfigurable and read-only. - Shouldn’t public properties in non-const classes be unconfigurable, too? Are such properties expected to be configured? Read-only properties could be created via public const. On Sep 25, 2011, at 4:09 , Mark S. Miller wrote: Hi Axel, This was one of the options we considered. At one point it was the main class proposal. The problem is that since it looks exactly like an imperative assignment to a property of this, it should have the semantics
Re: Class literals: does public still make sense?
I see, so private declarations may go back to being defined at the class level - at least semantically - in order for the private name to be in scope across the class eg this[heath] referenced in Monster prototype methods: get isAlive(), Monster.set health(). From: Brendan Eich bren...@mozilla.com To: Kam Kasravi kamkasr...@yahoo.com Cc: Mark S. Miller erig...@google.com; Axel Rauschmayer a...@rauschma.de; es-discuss es-discuss@mozilla.org Sent: Sunday, September 25, 2011 8:10 PM Subject: Re: Class literals: does public still make sense? On Sep 25, 2011, at 3:12 PM, Kam Kasravi wrote: class Monster { // The contextual keyword constructor followed by an argument // list and a body defines the body of the class’s constructor // function. public and private declarations in the constructor // declare and initialize per-instance properties. Assignments // such as this.foo = bar; also set public properties. constructor(name, healthvalue) { public name = name; module name from @name; private health = name.create(); No, that's silly. If there is to be private declaration syntax, it should generate the private name, class-private (shared among instances). What you just spelled out wants 'const' not 'private', but hoisted to an outer closure. The way you wrote it, each constructor call would make a new and unique private name, so you'd get instance-private instance variables, not class-private. this[health] = healthvalue; This part is what we agreed to in July. /be___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: New ES6 Working Draft
Were 'const functions' ever accepted into the grammar? See WeakMap for an example. From: Allen Wirfs-Brock al...@wirfs-brock.com To: es-discuss@mozilla.org Sent: Friday, September 23, 2011 10:21 AM Subject: New ES6 Working Draft I have updated the wiki with my latest working draft of the ES.next (ESA6) spec. Word and PDF versions are available. They can be access from http://wiki.ecmascript.org/doku.php?id=harmony:specification_drafts Please report issues using https://bugs.ecmascript.org/enter_bug.cgi?product=Draft%20for%206th%20Edition against the September 23, 2011 Draft Changes in this draft are generally marked with Rev 3 The change summary is: * Resolved as fixed bugs 137, 140,167, 177, 183,184,185,186,187,188,189,190,191,193,196,196 * Merged multiple built-in “class” branding internal properties into a single [[NativeBrand]] internal property * In 10.2, change environment records so that both mutable and immutable bindings may be in an initialized state and must be initialized before use via InitializeBinding * In 10.5 added separate algorithm for Block declaration instantiation. Block level declaration instantiations now specified. Function and global level still need to be updated to support let and const * Added a Declaration production to the grammar and changed StatementList to include both Statement and Declaration * Added let and const declarations. var declarations still hoist to function level and must not conflict with a let or const. * Hoisting and temporal dead zone for all block scoped declarations * Added semantics for destructuring binding pattern. * Added appropriate lexical scoping for declarations in bodies of switch and try statements. Note that for statements still need work for declarations in for head. * Added initializes for individual property level bindings in destructure binding ___ 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: New ES6 Working Draft
Ok, thanks Mark. On Sep 23, 2011, at 4:07 PM, Mark S. Miller erig...@google.com wrote: They were not. I will fix the WeakMap page when I have time. On Fri, Sep 23, 2011 at 4:01 PM, Kam Kasravi kamkasr...@yahoo.com wrote: Were 'const functions' ever accepted into the grammar? See WeakMap for an example. From: Allen Wirfs-Brock al...@wirfs-brock.com To: es-discuss@mozilla.org Sent: Friday, September 23, 2011 10:21 AM Subject: New ES6 Working Draft I have updated the wiki with my latest working draft of the ES.next (ESA6) spec. Word and PDF versions are available. They can be access from http://wiki.ecmascript.org/doku.php?id=harmony:specification_drafts Please report issues using https://bugs.ecmascript.org/enter_bug.cgi?product=Draft%20for%206th%20Edition against the September 23, 2011 Draft Changes in this draft are generally marked with Rev 3 The change summary is: Resolved as fixed bugs 137, 140,167, 177, 183,184,185,186,187,188,189,190,191,193,196,196 Merged multiple built-in “class” branding internal properties into a single [[NativeBrand]] internal property In 10.2, change environment records so that both mutable and immutable bindings may be in an initialized state and must be initialized before use via InitializeBinding In 10.5 added separate algorithm for Block declaration instantiation. Block level declaration instantiations now specified. Function and global level still need to be updated to support let and const Added a Declaration production to the grammar and changed StatementList to include both Statement and Declaration Added let and const declarations. var declarations still hoist to function level and must not conflict with a let or const. Hoisting and temporal dead zone for all block scoped declarations Added semantics for destructuring binding pattern. Added appropriate lexical scoping for declarations in bodies of switch and try statements. Note that for statements still need work for declarations in for head. Added initializes for individual property level bindings in destructure binding ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: {Weak|}{Map|Set}
The reference to private is actually in the Map, Set classes shown below. The BNF is also below: CallExpression : ... private ( AssignmentExpression ) ConstructorElement : ... PrivateVariableDefinition PrivateVariableDefinition : private ExportableDefinition class Map { private keys, vals; constructor() { private(this).keys = []; private(this).vals = []; } get(key) { const keys = private(this).keys; const i = indexOfIdentical(keys, key); return i 0 ? undefined : private(this).values[i]; } has(key) { const keys = private(this).keys; return indexOfIdentical(keys, key) = 0; } set(key, val) { const keys = private(this).keys; const vals = private(this).vals; let i = indexOfIdentical(keys, key); if (i 0) { i = keys.length; } keys[i] = key; vals[i] = val; } delete(key) { const keys = private(this).keys; const vals = private(this).vals; const i = indexOfIdentical(keys, key); if (i 0) { return false; } keys.splice(i, 1); vals.splice(i, 1); return true; } // todo: iteration } class Set { private map; constructor() { private(this).map = Map(); } has(key) { return private(this).map.has(key); } add(key) { private(this).map.set(key, true); } delete(key) { return private(this).delete(key); } // todo: iteration } From: Kam Kasravi kamkasr...@yahoo.com To: Mark S. Miller erig...@google.com Cc: es-discuss es-discuss@mozilla.org Sent: Wednesday, September 14, 2011 7:53 PM Subject: Re: {Weak|}{Map|Set} I noticed that these class definitions declare private names within the class body but not the constructor. My latest read of the class proposal was that private could only be declared within the constructor. Have I interpreted the BNF incorrectly? On Sep 14, 2011, at 6:20 PM, Mark S. Miller erig...@google.com wrote: On Wed, Sep 14, 2011 at 6:04 PM, Juan Ignacio Dopazo dopazo.j...@gmail.com wrote: On Wednesday, September 14, 2011, David Bruant david.bru...@labri.fr wrote: Also, I would like to talk a little bit about terminology. WeakMaps have their name inspired by the idea of weak references which have particular garbage-collection properties. From the developer perspective, this seems to be some sort of implementation detail they should not be aware of. As far as I know, current functions/constructors have their name inspired by the contract they fulfill rather than implementation considerations. The difference between current WeakMaps and Maps is their contract. In the latter, keys can be enumerated, in the former not. I think that this is the difference that should inspire different names rather than the implementation optimisation that is induced by this contract difference. In the last few days I had to write a piece of code that would strongly benefit from WeakMaps. I needed to store information about DOM nodes and retrieve it later, and these nodes aren't in my control so they can be detached at any time by someone else. If the references I kept were weak, I'd be sure that I wouldn't be causing a memory leak. And that's important in this case because the nodes are very likely Flash objects which can easily mean 20-50mb in memory. So knowing that a reference is weak is important information. I agree. Normally I strongly take the same position David does: emphasize semantics over implementation. But why? It is good when we can label a tool according to its purpose, rather than how it accomplishes that purpose. Associating the tool with its purpose helps us remember the right tool for the right job. Few would reach for the WeakMap tool thinking I need a non-enumerable table. Granted, there are cases when the non-enumerability is the desired feature, but those cases are rare. The common purpose of a WeakMap is rooted in our understanding, at a high level, of certain implementation costs, and our desire to avoid certain avoidable implementation costs. Generally, that is what a WeakMap is *for*. -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: {Weak|}{Map|Set}
I noticed that these class definitions declare private names within the class body but not the constructor. My latest read of the class proposal was that private could only be declared within the constructor. Have I interpreted the BNF incorrectly? On Sep 14, 2011, at 6:20 PM, Mark S. Miller erig...@google.com wrote: On Wed, Sep 14, 2011 at 6:04 PM, Juan Ignacio Dopazo dopazo.j...@gmail.com wrote: On Wednesday, September 14, 2011, David Bruant david.bru...@labri.fr wrote: Also, I would like to talk a little bit about terminology. WeakMaps have their name inspired by the idea of weak references which have particular garbage-collection properties. From the developer perspective, this seems to be some sort of implementation detail they should not be aware of. As far as I know, current functions/constructors have their name inspired by the contract they fulfill rather than implementation considerations. The difference between current WeakMaps and Maps is their contract. In the latter, keys can be enumerated, in the former not. I think that this is the difference that should inspire different names rather than the implementation optimisation that is induced by this contract difference. In the last few days I had to write a piece of code that would strongly benefit from WeakMaps. I needed to store information about DOM nodes and retrieve it later, and these nodes aren't in my control so they can be detached at any time by someone else. If the references I kept were weak, I'd be sure that I wouldn't be causing a memory leak. And that's important in this case because the nodes are very likely Flash objects which can easily mean 20-50mb in memory. So knowing that a reference is weak is important information. I agree. Normally I strongly take the same position David does: emphasize semantics over implementation. But why? It is good when we can label a tool according to its purpose, rather than how it accomplishes that purpose. Associating the tool with its purpose helps us remember the right tool for the right job. Few would reach for the WeakMap tool thinking I need a non-enumerable table. Granted, there are cases when the non-enumerability is the desired feature, but those cases are rare. The common purpose of a WeakMap is rooted in our understanding, at a high level, of certain implementation costs, and our desire to avoid certain avoidable implementation costs. Generally, that is what a WeakMap is *for*. -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: module exports
Yes, thanks, my mistake on the unexported startCar function declaration. My question is more about semantics, if the author of engine did not want to export start, the grammar allows anyone importing the engine module to override the original author's intent. On Jul 10, 2011, at 8:11 PM, David Herman dher...@mozilla.com wrote: According to the module grammar, the following is valid: 691module car { function startCar() {} module engine { function start() {} } export {start:startCar} from engine; } It seems like there would be issues with exporting module elements after the module has been defined. I don't see any conflicts with the code you wrote, but it does contain a linking error, because the car module doesn't have access to the unexported start function. Maybe you intended: module car { export function startCar() { } module engine { export function start() { } } export { start: startCar } from engine; } In this case, you have a conflict, because the car module is attempting to create two different exports with the same name. This is an early error. Also, what is the behavior of aliasing over existing Identifiers? Would the compiler fail or would behavior be the 'last' Identifier wins? Early error. Dave ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
module exports
Hi Dave: According to the module grammar, the following is valid: 691module car { function startCar() {} module engine { function start() {} } export {start:startCar} from engine; } It seems like there would be issues with exporting module elements after the module has been defined. Also, what is the behavior of aliasing over existing Identifiers? Would the compiler fail or would behavior be the 'last' Identifier wins?___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Module grammar
Should this ImportDeclaration(load) ::= import ImportBinding(load) (, ImportBinding(load))* ; ImportPath(load) ::= ImportSpecifierSet from ModuleExpression(load) ImportSpecifierSet ::= * | IdentifierName | { (ImportSpecifier (, ImportSpecifier)*)? ,? } ImportSpecifier ::= IdentifierName (: Identifier)? Be this? ImportDeclaration(load) ::= import ImportBinding(load) (, ImportBinding(load))* ; ImportBinding(load) ::= ImportSpecifierSet from ModuleExpression(load) ImportSpecifierSet ::= * | IdentifierName | { (ImportSpecifier (, ImportSpecifier)*)? ,? } ImportSpecifier ::= IdentifierName (: Identifier)? ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Classes: suggestions for improvement
On Jun 12, 2011, at 10:49 PM, Brendan Eich bren...@mozilla.com wrote: On Jun 12, 2011, at 8:46 PM, Axel Rauschmayer wrote: I’ve only got one use case for this, but “class methods” would also work better if they could be attached to the prototype (and subject to inheritance) instead of the constructor. We had a thread about this, because Ruby and CoffeeScript (which translates to JS and copies properties to do constructor inheritance) both support class method inheritance. Putting class methods on the prototype mixes up is-a relations, making the class constructor delegate to the class prototype. That breaks constructor is-a function in general. Better to have two parallel proto-chains, one from subclass prototype to superclass prototype, the other from subclass constructor to superclass constructor. Is the constructor calling implicit if not specified? For example both c++ and java will call super() implicitly if there is no explicit call for the subtype constructor. /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: Harmony:classes static and private
Thanks Allen, more than I was hoping for ... On Jun 7, 2011, at 10:11 PM, Allen Wirfs-Brock al...@wirfs-brock.com wrote: There are lots of sources about this The classic but somewhat technical paper that coined the phrase that I misquoted is William Cook's: http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.102.8635rep=rep1type=pdf some overviews http://c2.com/cgi/wiki?SubTypingAndSubClassing another good overview, from more of a java perspectivehttp://www.mit.edu/~6.170/lectures/lect09-subtyping-handouts.pdf Basically, subtyping typically is taken to imply strict substitutability. An instance of a subtype can be used anywhere an instance of its supertype is expected. This isn't just about what public methods are available (a subtype have can only add to the supertypes interface). It is also about what can be passed to and returned form each method, recursively applied. It is trivial to break such substitutability with JavaScript objects, even those created by the proposed class declarations. It is possible to create JavaScript objects that behave as subtypes but it takes work. It may not always be worth the effort. Statically typed languages and their users are often very concerned about correct subtyping because the memory safety of such languages often depends upon the fact that subtype substitutability invariants are guaranteed. Dynamic language folks are often less concerned because any such broken invariants will at worst cause the program to perform the wrong computation but dynamic runtime checks will still guarantee memory safety. Your actual milage may vary. Allen (I am not a type theorists) On Jun 7, 2011, at 8:17 PM, Kam Kasravi wrote: Yes I puzzled over that a bit :) I realize that types within a typed language need to provide certain guarantees in terms of schema, equivalence, etc. For the those of us more 'untyped' than others, could you expound very briefly on the type vs class distinction? Is it due to javascript's ability to morph a class definition both in terms of its properties and its prototype chain? I also ask due to Dave's suggestion in relation to modules that ES.next is much more amenable to static analysis (paraphrasing) which I would think an IDE would exploit to provide some level of type-checking. In Allen's mirrors article, it seems like types would be important to reflection. Although wouldn't you know, I searched Allen's article (http://www.wirfs-brock.com/allen/posts/228) and he never once mentions 'type' :) On Jun 7, 2011, at 6:47 PM, Allen Wirfs-Brock al...@wirfs-brock.com wrote: Oops, obviously I meant: JavaScript subclassing is definitely not equivalent to subtyping. Time for dinner-at keyboard too long. On Jun 7, 2011, at 6:34 PM, Mark S. Miller wrote: On Tue, Jun 7, 2011 at 6:11 PM, Allen Wirfs-Brock al...@wirfs-brock.com wrote: In a language as dynamic as JavaScript subtyping is definitely not equivalent to subtyping. Wow, JavaScript is even more dynamic than I thought ;). -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: class sugar: static inheritance
Just as the private(this) is used to expose the private instance record, could static([[Constructor]]) be introduced to provide access to the union of static properties across the set of constructor objects? (I know that their is some concern about the lengthy syntax of private()) Regarding the use of private(AssignmentExpression), does it provide access to all private ExportableDefinition's regardless of what inherited class they were declared in? That is given class Monster { constructor(health) { private health = health; } } class GilaMonster prototype Monster { constructor(owner) { super(10); private owner = owner; } eat(critter) { If(critter === private(this).owner) { private(this).health = 0; } else { private(this).health++; } } } Should the GilaMonster's private record include health? On Jun 6, 2011, at 11:08 AM, Allen Wirfs-Brock al...@wirfs-brock.com wrote: On Jun 6, 2011, at 10:32 AM, Brendan Eich wrote: On Jun 6, 2011, at 10:19 AM, Bob Nystrom wrote: On Sun, Jun 5, 2011 at 9:35 PM, Peter Michaux petermich...@gmail.com wrote: Based on my understanding of what the desugared code would be, the last line above would be an error because Dragon.allMonsters is undefined. That's correct. Do you have any examples of code where inheriting the constructor objects would be helpful? Used all the time in Ruby, and in some Smalltalks. Supported by CoffeeScript. See Actually, all modern Smalltalks where modern means anything post 1980 https://gist.github.com/1007150 https://gist.github.com/1006999 (warning: Ruby reading skills required). /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: class sugar: static inheritance
On Jun 8, 2011, at 3:05 AM, Brendan Eich bren...@mozilla.com wrote: On Jun 8, 2011, at 2:45 AM, Kam Kasravi wrote: Just as the private(this) is used to expose the private instance record, Please read private(this), e.g., is unbearably verbose; leaks an implementation detail. from http://wiki.ecmascript.org/doku.php?id=harmony:classes#open_issues. The syntax is a placeholder. It will not last. could static([[Constructor]]) be introduced to provide access to the union of static properties across the set of constructor objects? (I know that their is some concern about the lengthy syntax of private()) It's not concern, it is an open issue to resolve by using better syntax. What does union of static properties across the set of constructor objects mean? We're not reifying sets of properties as objects, if that's what you mean (static private yikes). This was related to Peter's concern included below for brevity Based on my understanding of what the desugared code would be, the last line above would be an error because Dragon.allMonsters is undefined. I was wondering if this could be solved in some way without explicitly referencing the particular Constructor. This isn't a static private issue per se, rather a suggestion for an operator that would allow one to reference Monster.allMonsters as Dragon.allMonsters. eg static(Dragon).allMonsters. Although it would probably be more consistent to resolve Dragon.allMonsters in the same way properties on the prototype chain are resolved. So we can probably ignore this suggestion. I can see how private(foo) brings this to mind. This is the problem I clumsily labeled leaks an implementation detail. Regarding the use of private(AssignmentExpression), does it provide access to all private ExportableDefinition's regardless of what inherited class they were declared in? That is given class Monster { constructor(health) { private health = health; } } class GilaMonster prototype Monster { constructor(owner) { super(10); private owner = owner; } eat(critter) { If(critter === private(this).owner) { private(this).health = 0; } else { private(this).health++; } } } Should the GilaMonster's private record include health? The private record especially views as an object is a kind of placeholder too. It doesn't help to think of it as a record. It probably does not help to think of it as an object, either, especially if you cannot get at it via anything like the still-straw private(this) or private(other) syntax. Yes, I agree, I was attempting to keep as close as possible to http terminology used in the proposal. On another topic, it does seem like protected is inevitable, doesn't it? Which may be a slippery slope :( BTW is it premature to ask questions on harmony proposals in their current state? /be On Jun 6, 2011, at 11:08 AM, Allen Wirfs-Brock al...@wirfs-brock.com wrote: On Jun 6, 2011, at 10:32 AM, Brendan Eich wrote: On Jun 6, 2011, at 10:19 AM, Bob Nystrom wrote: On Sun, Jun 5, 2011 at 9:35 PM, Peter Michaux petermich...@gmail.com wrote: Based on my understanding of what the desugared code would be, the last line above would be an error because Dragon.allMonsters is undefined. That's correct. Do you have any examples of code where inheriting the constructor objects would be helpful? Used all the time in Ruby, and in some Smalltalks. Supported by CoffeeScript. See Actually, all modern Smalltalks where modern means anything post 1980 https://gist.github.com/1007150 https://gist.github.com/1006999 (warning: Ruby reading skills required). /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: class sugar: static inheritance
Sorry iPad autocorrection strikes again... The comment towards the bottom should read: I was attempting to keep as close as possible to the terminology used in the proposal. On Jun 8, 2011, at 3:41 AM, Kam Kasravi kamkasr...@yahoo.com wrote: On Jun 8, 2011, at 3:05 AM, Brendan Eich bren...@mozilla.com wrote: On Jun 8, 2011, at 2:45 AM, Kam Kasravi wrote: Just as the private(this) is used to expose the private instance record, Please read private(this), e.g., is unbearably verbose; leaks an implementation detail. from http://wiki.ecmascript.org/doku.php?id=harmony:classes#open_issues. The syntax is a placeholder. It will not last. could static([[Constructor]]) be introduced to provide access to the union of static properties across the set of constructor objects? (I know that their is some concern about the lengthy syntax of private()) It's not concern, it is an open issue to resolve by using better syntax. What does union of static properties across the set of constructor objects mean? We're not reifying sets of properties as objects, if that's what you mean (static private yikes). This was related to Peter's concern included below for brevity Based on my understanding of what the desugared code would be, the last line above would be an error because Dragon.allMonsters is undefined. I was wondering if this could be solved in some way without explicitly referencing the particular Constructor. This isn't a static private issue per se, rather a suggestion for an operator that would allow one to reference Monster.allMonsters as Dragon.allMonsters. eg static(Dragon).allMonsters. Although it would probably be more consistent to resolve Dragon.allMonsters in the same way properties on the prototype chain are resolved. So we can probably ignore this suggestion. I can see how private(foo) brings this to mind. This is the problem I clumsily labeled leaks an implementation detail. Regarding the use of private(AssignmentExpression), does it provide access to all private ExportableDefinition's regardless of what inherited class they were declared in? That is given class Monster { constructor(health) { private health = health; } } class GilaMonster prototype Monster { constructor(owner) { super(10); private owner = owner; } eat(critter) { If(critter === private(this).owner) { private(this).health = 0; } else { private(this).health++; } } } Should the GilaMonster's private record include health? The private record especially views as an object is a kind of placeholder too. It doesn't help to think of it as a record. It probably does not help to think of it as an object, either, especially if you cannot get at it via anything like the still-straw private(this) or private(other) syntax. Yes, I agree, I was attempting to keep as close as possible to http terminology used in the proposal. On another topic, it does seem like protected is inevitable, doesn't it? Which may be a slippery slope :( BTW is it premature to ask questions on harmony proposals in their current state? /be On Jun 6, 2011, at 11:08 AM, Allen Wirfs-Brock al...@wirfs-brock.com wrote: On Jun 6, 2011, at 10:32 AM, Brendan Eich wrote: On Jun 6, 2011, at 10:19 AM, Bob Nystrom wrote: On Sun, Jun 5, 2011 at 9:35 PM, Peter Michaux petermich...@gmail.com wrote: Based on my understanding of what the desugared code would be, the last line above would be an error because Dragon.allMonsters is undefined. That's correct. Do you have any examples of code where inheriting the constructor objects would be helpful? Used all the time in Ruby, and in some Smalltalks. Supported by CoffeeScript. See Actually, all modern Smalltalks where modern means anything post 1980 https://gist.github.com/1007150 https://gist.github.com/1006999 (warning: Ruby reading skills required). /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: class sugar: static inheritance
Mark Miller wrote Actually, it isn't another topic. It's why Kam's GilaMonster cannot see Monster's health. private means private to the class, not private to the class and subclasses. protected would mean the second, and no, I don't think it's inevitable. Aren't there also motivations related to covert channels especially given javascript's call and apply where any object should not have the ability to discern what private fields exist within an instance? This may be preventable using the meta attributes on property descriptors, but it seems like private should not 'leak' even to subclasses - per Brendan's earlier statements. I imagine Mark can or has written volumes on this, but probing a subclass of 'CreditCard' for the existence of private instance variables or static class declarations would seem to enable an attack vector and violate the class proposal objective of Strong encapsulation in order to support defensiveness and security. In other words it's seems like uses cases related to private instance as well as private class (ie static private) are reasonable and at least as important as protected. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Harmony:classes static and private
Hmmm... I'm referencing http://wiki.ecmascript.org/doku.php?id=harmony:classes. Is this one incorrect? On Jun 8, 2011, at 11:13 AM, Bob Nystrom rnyst...@google.com wrote: Either I'm out-of-date or the wiki page is. My understanding is that at the TC39 meetings we decided to move instance and private record declarations out of the class body and into the constructor. If that's the case, this should be less confusing. You can no longer use public or private at the class body level. So that example becomes: class Monster { // static places the property on the constructor. static allMonsters = []; // No modifier declares on the prototype. numAttacks = 0; constructor() { // private places it on the private record of the new instance. private health; } } That's better, but public and private are still less than ideal keywords here since Javascript's use of them is distinctly different from other languages. Alas, they were the best we could come up with. As far as your original question, Mark is right. You can have private static state by just having a variable in the closure that surrounds the class declaration but that isn't otherwise visible. Modules are one way to do that. This is another: var Monster; { let allMonsters = []; Monster = class { // can access allMonsters here... } } (Hopefully I have that right.) - bob On Wed, Jun 8, 2011 at 1:11 AM, Kam Kasravi kamkasr...@yahoo.com wrote: Thanks Allen, more than I was hoping for ... On Jun 7, 2011, at 10:11 PM, Allen Wirfs-Brock al...@wirfs-brock.com wrote: There are lots of sources about this The classic but somewhat technical paper that coined the phrase that I misquoted is William Cook's: http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.102.8635rep=rep1type=pdf some overviews http://c2.com/cgi/wiki?SubTypingAndSubClassing another good overview, from more of a java perspectivehttp://www.mit.edu/~6.170/lectures/lect09-subtyping-handouts.pdf Basically, subtyping typically is taken to imply strict substitutability. An instance of a subtype can be used anywhere an instance of its supertype is expected. This isn't just about what public methods are available (a subtype have can only add to the supertypes interface). It is also about what can be passed to and returned form each method, recursively applied. It is trivial to break such substitutability with JavaScript objects, even those created by the proposed class declarations. It is possible to create JavaScript objects that behave as subtypes but it takes work. It may not always be worth the effort. Statically typed languages and their users are often very concerned about correct subtyping because the memory safety of such languages often depends upon the fact that subtype substitutability invariants are guaranteed. Dynamic language folks are often less concerned because any such broken invariants will at worst cause the program to perform the wrong computation but dynamic runtime checks will still guarantee memory safety. Your actual milage may vary. Allen (I am not a type theorists) On Jun 7, 2011, at 8:17 PM, Kam Kasravi wrote: Yes I puzzled over that a bit :) I realize that types within a typed language need to provide certain guarantees in terms of schema, equivalence, etc. For the those of us more 'untyped' than others, could you expound very briefly on the type vs class distinction? Is it due to javascript's ability to morph a class definition both in terms of its properties and its prototype chain? I also ask due to Dave's suggestion in relation to modules that ES.next is much more amenable to static analysis (paraphrasing) which I would think an IDE would exploit to provide some level of type-checking. In Allen's mirrors article, it seems like types would be important to reflection. Although wouldn't you know, I searched Allen's article (http://www.wirfs-brock.com/allen/posts/228) and he never once mentions 'type' :) On Jun 7, 2011, at 6:47 PM, Allen Wirfs-Brock al...@wirfs-brock.com wrote: Oops, obviously I meant: JavaScript subclassing is definitely not equivalent to subtyping. Time for dinner-at keyboard too long. On Jun 7, 2011, at 6:34 PM, Mark S. Miller wrote: On Tue, Jun 7, 2011 at 6:11 PM, Allen Wirfs-Brock al...@wirfs-brock.com wrote: In a language as dynamic as JavaScript subtyping is definitely not equivalent to subtyping. Wow, JavaScript is even more dynamic than I thought ;). -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Harmony:classes static and private
Thanks Mark, Brendan Within this context subtype access and it's interactions with private would also be of interest to me. For example interactions with static private const. On Jun 7, 2011, at 4:51 PM, Mark S. Miller erig...@google.com wrote: I agree with all of this. It does seem bizarre to resort to private names for a use case addressed well by lexically captured variables. But yes, we could do either. On Tue, Jun 7, 2011 at 4:07 PM, Brendan Eich bren...@mozilla.com wrote: On Jun 7, 2011, at 3:31 PM, Mark S. Miller wrote: We have talked about adding some way to state class-private per-class variable declarations without having to place them textually outside the class. However, a problem with static private is that it suggests that such things are properties. They're not. They're just lexically captured variables. How could you tell? I mean, what reflection APIs would not disclose static privates as properties? Since http://wiki.ecmascript.org/doku.php?id=harmony:private_name_objects are in Harmony, it's not a given that static privates must be lexically captured as in a power-constructor pattern. It should not be observable apart from reflection. From http://wiki.ecmascript.org/doku.php?id=harmony:private_name_objects#open_issues I think we have some freedom to restrict reflection APIs from seeing any private names. That leaves proxies, but with class static private (or should that be private static? ;-)) members, a Proxy can't get in the middle. Can it? Between the open issues on private name objects and the private(this) placeholder and related open issues on classes, I believe we have some room to maneuver. My point here is not to argue that we must have static private class members. Only that we could consider them as distinct from lexically captured private upvars a la the power constructor pattern. /be -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Harmony classes
From the harmony classes example copied below for reference. The set health(value) {...} assigns a new value to this.health. But health is a private property, so the assignment is setting a public property. Shouldn't the assignment be private(this).health = value? class Monster { // The contextual keyword constructor followed by an argument // list and a body defines the body of the class’s constructor // function. public and private declarations in the constructor // declare and initialize per-instance properties. Assignments // such as this.foo = bar; set public properties. constructor(name, health) { public name = name; private health = health; } // An identifier followed by an argument list and body defines a // method. A “method” here is simply a function property on some // object. attack(target) { log('The monster attacks ' + target); } // The contextual keyword get followed by an identifier and // a curly body defines a getter in the same way that get // defines one in an object literal. get isAlive() { return private(this).health 0; } // Likewise, set can be used to define setters. set health(value) { if (value 0) { throw new Error('Health must be non-negative.') } this.health = value } // An identifier optionally followed by = and an expression // declares a prototype property and initializes it to the value // of that expression. public as a member modifier is allowed. numAttacks = 0; // The keyword const followed by an identifier and an // initializer declares a constant prototype property. const attackMessage = 'The monster hits you!'; }___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: class sugar
Although this ship has sailed, its unfortunate the keyword privileged was never considered as part of the closure pattern and valid syntax within the classes strawman, where public operated on the prototype chain and privileged operated on the closure. Now its less clear what type of pattern is being employed since public methods within the constructor are not on the prototype and cannot be extended. From: Brendan Eich bren...@mozilla.com To: Peter Michaux petermich...@gmail.com Cc: Mark S. Miller erig...@google.com; es-discuss es-discuss@mozilla.org Sent: Saturday, June 4, 2011 3:23 PM Subject: Re: class sugar On Jun 4, 2011, at 3:00 PM, Peter Michaux wrote: On Sat, Jun 4, 2011 at 9:52 AM, Juan Ignacio Dopazo dopazo.j...@gmail.com wrote: Both styles are equally useful. Prototype based code has its own advantages such as being able to easily modify the behavior of multiple objects on the fly (very useful when working with 3rd party code for instance). Yes but this is a limitation of our tools. If Firebug let you into a closure and edit the code inside the closure, for example, you could have this ability with the closure based system. This is hard, though. It's related to the optimization challenges in joining function objects to their one expression form. See http://www.mail-archive.com/es-discuss@mozilla.org/msg03904.html http://www.mail-archive.com/es-discuss@mozilla.org/msg03906.html All solvable, but hard enough that even the latest JS engines (last I checked) show slowdowns when you scale up objects as closures vs. the prototypal equivalent. I know, it's a vicious cycle. We can't get engine implementors to optimize harder without somehow making closure costs hurt, but since closure costs hurt developers first and engine implementors second or third, while prototypes hurt less, many developers choose prototypes. JS has prototypes as well as closures, and prototypes allow explicit sharing of methods. This ship sailed long ago. Good to see class syntax supporting both styles, in any event. /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: statements that could be expressions?
The latest narcissus has a few ES.next strawmen incorporated. Narcissus is very cool and easy to understand (most of it anyway), though its not auto-generated from any type of BNF grammar. Pegjs does autogenerate from a slightly annotated BNF (see javascript.pegjs under examples on github) though it does not transpile to any target backend like es5. There may be others out there that would make your life easier eg traceur or ometa. Just FYI. From: Breton Slivka z...@zenpsycho.com To: Brendan Eich bren...@mozilla.com Cc: es-discuss es-discuss@mozilla.org Sent: Saturday, June 4, 2011 7:12 PM Subject: Re: statements that could be expressions? If I could demonstrate my idea working in Narcissus (or your parser of choice), would that be helpful or useful to anyone? I was thinking about the ambiguity of {x,y} with relation to the key/value shortcut, and it seems that there's a lot of ambiguities around the { symbol that are causing some problems. My idea basically boils down to embracing the ambiguities as special cases of the same underlying semantic structure. To put this another way, this is my thought exercise: pretend that we're scientifically observing the state of javascript today, and we decided to operate under the assumption that *all* structures that begin with { and end with } compile and evaluate into the same type of semantic structure (instead of multiple different kinds, function bodies, objects, blocks with labels, and what have you) what kind of structure is it that we are observing? It would seem like that as the language stands we get access to a subset of this structure's capabilities. In terms of moving forward, what kind of properties can we extrapolate from what we know about this structure type already? Looking backwards, what sort of properties does this structure have currently that would produce the behaviour we see today? There needs to be a lot more practical work done on this idea to make it particularly compelling, but as I said, I'm willing to tinker with getting it working in an existing javascript parser/evaluator if anyone on this list thinks it is worth the time to investigate. On Sat, Jun 4, 2011 at 9:04 AM, Brendan Eich bren...@mozilla.com wrote: On Jun 3, 2011, at 3:11 PM, Waldemar Horwat wrote: On 06/02/11 20:12, Brendan Eich wrote: - Conflict between blocks and statements: a = {x: while (x) { ... break x;}} is either an object initializer or a block containing a labeled while statement. http://wiki.ecmascript.org/doku.php?id=strawman:arrow_function_syntax based on feedback from Jorge here on the list mentions a block that cannot start with a label. Two-token lookahead restriction, why not? Don't you also want to allow (either now or in the future) for the shorthand {x, y} to mean {x:x, y:y}? There are also getters, setters, and various other stuff that can be put into object initializers now or in the future, so there are more possibilities than just an identifier followed by a colon. True, and {x, y} is noted somewhere (or was in a past version) as a problem. http://wiki.ecmascript.org/doku.php?id=strawman:object_initialiser_shorthand did not get promoted yet, and I forgot to keep this pot boiling. The accessors are not ambiguous, but the proposed !, ~, and # property prefixes for writable, enumerable, and configurable false-setting do make trouble. Perhaps Breton's more radical idea of unifying objects and block (lambdas) deserves a look, instead of trying to separate syntaxes that start with { at this late date. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: how to create strawman proposals?
On Jun 3, 2011, at 8:47 AM, Allen Wirfs-Brock al...@wirfs-brock.com wrote: I just wanted to add, that it's always wise to flesh out an idea by writing it up as a cohesive proposal. Don't let lack of non-member access to the TC39 wiki stop you from doing this. Write it up anyway. Then post it to your personal blog, website, github, or anywhere else that you have access to. Then start a discussion thread here and point at your proposal. That's really all it takes. Great idea, it's also easy to tweet your concept and add @BrendanEich, @wycats or some others. Given how active Brendan and Allen are on twitter (how do you guys find the time?) has TC39 considered a twitter channel perhaps along strawman boundaries? For example the strawman page could add a twitter reference next to each strawman (if the author wants to). Given the amount of informal discussion happening now it looks like it's happening anyway... Allen ___ 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: ES parsing tools (Re: Short Functions)
On May 31, 2011, at 4:20 PM, Waldemar Horwat walde...@google.com wrote: On 05/29/11 19:35, Kam Kasravi wrote: Does Waldemar still maintain the tool? the source dates seemed fairly old... It still works. I didn't bother updating the ES3 parser for ES5 because I had already explored the same syntax as part of ES4 and it worked. I'm going to update it for ES.next. The code does more than just validate the lexical and syntactic grammars. It can encode semantics and evaluate ECMAScript expressions directly from the semantics. It also validates things like that there are no contexts in the grammar where a / would be both a division symbol and the start of a regular expression. Thanks, sounds like a great tool. Do you build an ast along the lines of the parser API? https://developer.mozilla.org/en/SpiderMonkey/Parser_API Waldemar ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: May 24-26 rough meeting notes
On May 31, 2011, at 2:55 PM, Brendan Eich bren...@mozilla.com wrote: On May 31, 2011, at 2:30 PM, Waldemar Horwat wrote: I would not want to use anything like a PEG to standardize a grammar. Here's why: PEG being unambiguous by construction simply means that it resolves all ambiguities by picking the earliest rule. This turns all rules following the first one into negative rules: X matches Z only if it DOESN'T match a Y or a Q or a B or You could pick the same strategy to disambiguate an LR(1) grammar, and it would be equally bad. PEGs use of ordered choice provides an opportunity to minimize backtracking, but it still backtracks given a nonterminal where the first ordered choice is incorrect. A PEG must return one parse tree or an error after potentially exhausting all choices (unlike GLR). I believe there are differing motivations to pick a parser depending on your goals, if you're experimenting with the grammar or want a parser to transform an extended grammar then PEGs make alot of sense because they closely matche the BNF grammar and it's easy to introduce new grammar rules. It's likely PEGs could provide diagnostics related to LR(1) ambiguity, at least with pegjs it looks like this could be built into the algorithm. I understand the motivation to avoid any parser which tolerates ambiguous LR(1) grammars, but PEGs can be great tools given the LR(1) requirement is enforced. Negative rules are the bane of grammars and behind the majority of the problems with the C++ grammar, including the examples I listed earlier. They make a grammar non-understandable because the order of the rules is subtly significant and makes it hard to reason about when an X matches a Z; a language extension might expand the definition of Y to make an X no longer match a Q, and you wouldn't know it just by looking at a grammar with negative rules. In a positive-rule-only grammar you'd discover the problem right away because the grammar wouldn't compile. Thanks -- you've made this point before and I've agreed with it. It helps to restate and amplify it, I think, because my impression is that not many people get it. PEG users may be happy with their JS parsers at any given point in the language's standard version-space, of course. It still could be that we use LL(1) or another positive-rule-only grammar, of course, but we can hash that out separately. Negative rules also interact badly with both semicolon insertion and division-vs-regexp lexer disambiguation. One might naively think that semicolon insertion would be an ideal match for negative rules: You first try to parse tokens-on-line1 tokens-on-line2 Heh; this doesn't pass the first rule of ASI fight-club: there's no insertion is there is no error. /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: May 24-26 rough meeting notes
On May 31, 2011, at 9:34 PM, Brendan Eich bren...@mozilla.com wrote: On May 31, 2011, at 9:08 PM, Kam Kasravi wrote: On May 31, 2011, at 2:55 PM, Brendan Eich bren...@mozilla.com wrote: On May 31, 2011, at 2:30 PM, Waldemar Horwat wrote: I would not want to use anything like a PEG to standardize a grammar. Here's why: PEG being unambiguous by construction simply means that it resolves all ambiguities by picking the earliest rule. This turns all rules following the first one into negative rules: X matches Z only if it DOESN'T match a Y or a Q or a B or You could pick the same strategy to disambiguate an LR(1) grammar, and it would be equally bad. [just noting you are replying to Waldemar's words here, not mine. /be] PEGs use of ordered choice provides an opportunity to minimize backtracking, but it still backtracks given a nonterminal where the first ordered choice is incorrect. A PEG must return one parse tree or an error after potentially exhausting all choices (unlike GLR). Yes. The problem with PEGs is not ambiguity (multiple parse trees for one sentence) but the negative-rule future hostility problem that Waldemar cited. That is hard to see at any given instant. It comes up when evolving a language. I believe there are differing motivations to pick a parser depending on your goals, if you're experimenting with the grammar or want a parser to transform an extended grammar then PEGs make alot of sense because they closely matche the BNF grammar and it's easy to introduce new grammar rules. It's likely PEGs could provide diagnostics related to LR(1) ambiguity, at least with pegjs it looks like this could be built into the algorithm. I understand the motivation to avoid any parser which tolerates ambiguous LR(1) grammars, but PEGs can be great tools given the LR(1) requirement is enforced. This matches Tom's testimony. At this point I'm working under assumption ES.next sticks with the LR(1) grammar. First target: destructuring, using an extended Reference type. There are alternatives (thanks to dherman for discussion today about this) but I think this is the minimal patch to ES5. Arrow function syntax can be handled similarly, provided Expression covers ArrowFormalParameters. But that is a strawman, so it'll go after destructuring. There was no suggestion on my part to deviate from LR(1), rather provide some info on PEG parsers annd their ability to parse ECMA-262 5th Edition and some proposed strawmen extensions. Its valuable to know the strengths of different types of parsers and the types of parsers currently in action. Is it a given that the grammar extensions in the various strawmen are all LR(1)? /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: ES parsing tools (Re: Short Functions)
I've been experimenting with pegjs - which generates a parser based on the ecma-262 5th edition grammar. I've been building a backend that walks the ast to regenerate the code (less white related formatting). The nice thing about pegjs is most of the ast nodes agree with the parser api (https://developer.mozilla.org/en/SpiderMonkey/Parser_API) My approach is to add various strawmen and have them translated to plain javascript - transpiler approach. I've been very happy with the ast it generates thus far. (http://pegjs.majda.cz/) From: Brendan Eich bren...@mozilla.com To: Claus Reinke claus.rei...@talk21.com Cc: es-discuss es-discuss@mozilla.org Sent: Sunday, May 29, 2011 12:55 PM Subject: Re: ES parsing tools (Re: Short Functions) On May 29, 2011, at 12:21 PM, Brendan Eich wrote: Mark and Tom already use Ometa at a code.google.com project, as noted. What more do you want? This does *not* address the issue of a usable spec grammar that can be validated (my point (a)). In spite of over a thousand words and many paragraphs in reply :-/. To say a bit more, in a more positive tone: I agree that deterministic choice is attractive considered in a vacuum, to avoid ambiguities and better match how hand-crafted recusrive descent parsers are written. So PEG or stronger is plausible when experimenting, no argument there. Mark and Tom's choice to use Ometa for their language lab seems fine. Recasting the ECMA-262 specification's unambiguous (after ASI, and assuming ES5 added no ambiguities to ES3) LR(1) grammar using a PEG could be tried and evaluated. I would be interested in seeing a no-other-changes translation of the spec grammar into a PEG that is validated somehow. Here the issue is not validation against ambiguity, since the PEG is unambiguous because of ordered choice. The validation we'd need would be that both grammars produce sentences only and exactly in the same language. /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: ES parsing tools (Re: Short Functions)
Does Waldemar still maintain the tool? the source dates seemed fairly old... On May 29, 2011, at 12:21 PM, Brendan Eich bren...@mozilla.com wrote: On May 29, 2011, at 2:11 AM, Claus Reinke wrote: tl;dr: - JS-based PEG + ANTLR as a route for ES grammar experiments Mark and Tom already use Ometa at a code.google.com project, as noted. What more do you want? This does *not* address the issue of a usable spec grammar that can be validated (my point (a)). In spite of over a thousand words and many paragraphs in reply :-/. - would like to know about route viability and alternative routes Tom testified to slowness. Mark and Tom being on TC39 does *not* address the implementor acceptability (my point (b)) of Ometa, which is nearly nil. The relation to the current topic is that ANTLR's LL(*) parsing [1] aims to generalize and optimize PEGs and related formalisms typical for top-down parsers (while GLR and bison are typical for bottom-up parsers, which are not relevant for ES implementations, according to your information). The ECMA-262 spec uses LR(1), and ES3's grammar was validated by Waldemar using his custom common lisp program, source available in the old Mozilla CVS repo: http://mxr.mozilla.org/mozilla/source/js2/semantics/ Changing to something new is certainly possible, but we need at least that much validation (what Yacc calls shift/reduce and reduce/reduce conflict detection). Top-down formalisms may not be suitable if they do not check for ambiguities and rule them out. To quote from Waldemar on this list in October 2008, This is why ambiguous grammars are bad and unsuitable for our spec. In an unambiguous grammar, if you find a series of production expansions that matches a source program, then you know that those are the expansions that will be taken. In an ambiguous grammar, you also need to prove the negative: no *other* expansion can match that source program and shadow your expansions. Proving the negative causes trouble because a language extension could turn the mismatch into a match and because sometimes[...], you expected some other part of the grammar to shadow your expansions but it didn't. At this point, I'd like to plead for fewer words and aspirational statements, and more concrete details about validation against ambiguity in the system(s) you are proposing. The postings which triggered my inquiry were authored by coders not implementing the major ES engines, but by ES implementers nevertheless. If you mean Mark and Tom, please say so. They did not implement a performant JS engine, so that's not helpful for point (b). Last time I'll say this, please don't rehash. Many people are playing with JS parsers, testing extensions, building transpilers. That's all great, but it does not address the spec issue, specifically both points (a) and (b). /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 revival, now with semantics
My expectation was that that this would not be bound in the same manner as this.myage = function() { return this.age }.bind(this); using block lambdas. Thanks for the clarifications below. In the block lambda strawman examples, the surprise is the use of return (and other goto constructs like break). At least in similar discussions related to closures in java, Neal Grafter suggests that return and other control constructs not be allowed (http://gafter.blogspot.com/2006/08/tennents-correspondence-principle-and.html) due to TCP. I assume this is also why var is being excluded in the strawman. Given the impact to the grammar to exclude var, would this constraint be compile time checked? Would grammar constraints like no var be semantically checked by implementors or folded into the grammar formally? The latter would suggest a production rule other than StatementList*, where VariableStatement would be excluded... On May 23, 2011, at 6:57 AM, Brendan Eich bren...@mozilla.com wrote: On May 22, 2011, at 10:15 PM, Kam Kasravi wrote: Is this valid? function Person(a) { this.age = a; } Person.prototype.myage = {|| this.age}; Block-lambda, per Tennent's Correspondence Principle as cited, uses the same this as if you moved the code inside the {|| ... } outside. This is so expr is equivalent to {|| expr }(). JS hackers do not see function () { ... } so should not expect this to change meaning. (For this reason among others, block-lambdas have no [[Construct]] internal method. Same as for built-in functions in ES1-5.) So this is not going to do what you want below: function info(myage) { console.log('my age is '+myage()); } info(new Person(10).myage); info(new Person(12).myage); Enclosing the block-lambda within the constructor works: function Person(a) { this.age = a; this.myage = {|| this.age}; } Note that in this case, unlike the case with a function expression instead of the block-lambda, the implementation can optimize aggressively: no other this can be bound dynamically in any subsequent call via new Person(10).myage() or myage() in info. This is a stronger guarantee than if Person used this.myage = function () { return this.age; }.bind(this); in the absence of aggressive static analysis (without which, who knows what bind means at compile time)? The full closure pattern works too, of course: function Person(a) { return {get age() { return a; }, myage: {|| a}}; } but you have to commit to accessors. One last note: freezing and joining (see # usage in http://wiki.ecmascript.org/doku.php?id=strawman:arrow_function_syntax referencing http://wiki.ecmascript.org/doku.php?id=strawman:const_functions) do not enable much more optimization in this constructor pattern, however you do it. Whether closing over this or the parameter a, the joined block-lambda (or function) identity cannot join across the Person closure boundary. (I did not make block-lambdas implicitly frozen and joined since some on TC39 and in the community object to that kind of change without opt-in syntax, and because it doesn't help much, given the change to make this a lexical upvar.) So block-lambdas are not going to solve the bound method cost problem in JS. For that, you need a class proposal that automatically binds methods to the receiver while at the same time disallowing any kind of dynamic inheritance. ES4 after ActionScript 3 had this; Java etc. do too of course. Does JS really need it, vs. the prototypal function-valued properties as methods pattern? In any event, nothing block-lambdas or any other this-capturing form can fix by themselves. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Is class syntax really necessary ?
If one has a class proposal with the prerequisite examples and grammar specification, how does one propose this with a possible goal of an alternate strawman? On May 23, 2011, at 11:25 AM, Bob Nystrom rnyst...@google.com wrote: On Mon, May 23, 2011 at 10:41 AM, Brendan Eich bren...@mozilla.com wrote: On May 23, 2011, at 10:03 AM, Alex Russell wrote: (A) the boilerplate needed to set up a sub-prototype object with correct constructor property, and (B) the pain of doing correct super calls by hand. I hope we can add the hazards of incorrectly adding mutable state to a prototype and not an instance to this list. I.e., many people get this wrong: function C(){ // should include: // this._list = []; } C.prototype = { _list: [], addToList: function(item) { this._list.push(item);// logic error! // side-effects here } }; There's two bugs there: 1. Not creating this._list in the ctor. 2. Creating one on .prototype. If bug #1 is fixed, there's no sensible reason to ever define _list on the prototype since it would always be shadowed. Where and how does the current proposal address (C)? One thing I'd like the proposal to support, which it doesn't currently, is initializers on instance property declarations. Then you could do: class C { public _list = []; } With that, you'll correctly get a new _list on each instance of C when it's created. - bob ___ 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: Short Functions
I've been experimenting with PEG/packrat parsers and how well they do on the ecmascript grammar. Since these do not use lexers and are LL(n) they may be a better fit. There are a few implementations out there written in JS - ometa and pegjs come to mind. They also are a good fit for transpilers though I realize this is not a TC39 goal. From: Waldemar Horwat walde...@google.com To: Brendan Eich bren...@mozilla.com Cc: es-discuss es-discuss@mozilla.org Sent: Monday, May 23, 2011 2:09 PM Subject: Re: Short Functions On 05/21/11 23:53, Brendan Eich wrote: That's accurate. But I discounted arrow functions because to be usable, to have the syntax you show above, requires GLR parsing (if bottom up; top-down may be easier, haven't proven it yet). GLR parsing would be wild in ECMAScript due to the fact that the lexer is dependent on the parser's current state. A GLR parser is working on a quantum superposition of multiple states in parallel, so if it encounters a / then some of the superposed states may direct the lexer to interpret it as a division symbol while others direct it to start scanning a regular expression. So now you need a quantum entanglement of lexers corresponding to the superposed parser states the GLR parser is considering. Semicolon insertion would also be be forced into quantum entanglement with the superposed parser states. Do we really want to go there? Waldemar ___ 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: Short Functions
On May 23, 2011, at 4:08 PM, Brendan Eich bren...@mozilla.com wrote: On May 23, 2011, at 2:55 PM, Kam Kasravi wrote: I've been experimenting with PEG/packrat parsers and how well they do on the ecmascript grammar. Since these do not use lexers and are LL(n) they may be a better fit. There are a few implementations out there written in JS - ometa and pegjs come to mind. Mark and Tom used Ometa for http://code.google.com/p/es-lab/ -- slo-o-o-o-w. Yeah it has no memoization. Pretty cool nevertheless as far as what he was able to do. Though I really like what Dave is doing on narcissus. They also are a good fit for transpilers though I realize this is not a TC39 goal. We need to consider browser implementations, which must lex and parse quickly, and which all (AFAIK) use hand-written lexers and parsers. /be From: Waldemar Horwat walde...@google.com To: Brendan Eich bren...@mozilla.com Cc: es-discuss es-discuss@mozilla.org Sent: Monday, May 23, 2011 2:09 PM Subject: Re: Short Functions On 05/21/11 23:53, Brendan Eich wrote: That's accurate. But I discounted arrow functions because to be usable, to have the syntax you show above, requires GLR parsing (if bottom up; top-down may be easier, haven't proven it yet). GLR parsing would be wild in ECMAScript due to the fact that the lexer is dependent on the parser's current state. A GLR parser is working on a quantum superposition of multiple states in parallel, so if it encounters a / then some of the superposed states may direct the lexer to interpret it as a division symbol while others direct it to start scanning a regular expression. So now you need a quantum entanglement of lexers corresponding to the superposed parser states the GLR parser is considering. Semicolon insertion would also be be forced into quantum entanglement with the superposed parser states. Do we really want to go there? Waldemar ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: block lambda revival, now with semantics
Is this valid? function Person(a) { this.age = a; } Person.prototype.myage = {|| this.age}; function info(myage) { console.log('my age is '+myage()); } info(new Person(10).myage); info(new Person(12).myage); From: Brendan Eich bren...@mozilla.com To: es-discuss es-discuss@mozilla.org Sent: Sunday, May 22, 2011 9:17 PM Subject: block lambda revival, now with semantics http://wiki.ecmascript.org/doku.php?id=strawman:block_lambda_revival Only a couple of TODOs: 11.1.7.1 [[Call]] When the [[Call]] internal method for a block-lambda object B is called with a list of arguments, the following steps are taken: 1. Let funcCtx be the result of establishing a new execution context for function code using the value of B‘s [[FormalParameters]] internal property, the passed arguments List args, and the this value given by the ThisBinding component of the execution context in B‘s [[Context]] internal property. 2. Let result be the result of evaluating the StatementList or EmptyStatement that is the value of B‘s [[Code]] internal property. 3. Exit the execution context funcCtx, restoring the previous execution context. 4. If result.type is normal and result.value is empty then return (normal, undefined, empty). 5. Else if result.type is break, continue, or return and B‘s [[Context]] internal property has already exited, throw a TypeError exception. 6. Else if result.type is break or continue and result.target has already exited, throw a TypeError exception. 7. Else return the Completion value result. TODO: forbid var in block-lambdas (yeah!) 11.2.3 Function Calls ... TODO: Process Completion return type The production CallExpression: CallExpression[no LineTerminatorhere] BlockArguments is evaluated evaluated in exactly the same manner, except that BlockArguments is evaluated instead of Arguments in step 3. In other words, a block-lambda's [[Call]] internal method must return a Completion in order to attempt to break, continue, or return in the enclosing switch/loop/function. One way to do this: uncatchable internal Completion exceptions for (break, empty, target), (continue, empty, target), and (return, value, empty) thrown by the relevant statements. The uncatchable part is ugly and this looks like an unnecessary change at the statement-grammar level, since Completion type works there already to solve the same problem. The issue is that within an expression, results are values, not Compietions. There's a bit of magic in the spec by which an exception thrown from sub-expression evaluation is caught by the statement level and packaged up into a (throw, value, empty) completion. Block-lambdas are the first way by which an expression can complete with break, continue, or return. We could make all expression evaluation in the spec return a union of Reference and Completion types. Explicitness seems best. I'll let this one marinate. The first TODO proposes to ban var from occurring within block-lambdas. This seems better than contorting the spec to hoist var bindings across block-lambda boundaries. Who is with me? ;-) /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: arrow syntax unnecessary and the idea that function is too long
Some references to parsers that do not share ambiguity problems due to limited lookahead such as GLR and PEG parsers. http://www.cs.nyu.edu/rgrimm/papers/pldi06.pdf http://www.cs.rit.edu/~ats/projects/jsm/paper.xml http://www.cs.ucla.edu/~awarth/papers/dls07.pdf From: Brendan Eich bren...@mozilla.com To: Claus Reinke claus.rei...@talk21.com Cc: es-discuss es-discuss@mozilla.org Sent: Friday, May 20, 2011 11:06 AM Subject: Re: arrow syntax unnecessary and the idea that function is too long On May 20, 2011, at 7:07 AM, Claus Reinke wrote: we should focus on the harder nut to crack (the leading parenthesized parameter list). Isn't that an example of issues that would not exist if arrow functions had a prefix marker? It is a deeper issue. ECMA-262 currently covers left-hand side of assignment with LeftHandSideExpression, but that produces 42, not a valid LHS. Semantic checks and mandatory errors in spec prose make up for the lack of a precise grammar. ES5, Clause 16, has Attempts to call PutValue on any value for which an early determination can be made that the value is not a Reference (for example, executing the assignment statement 3=4). Destructuring assignment -- not the binding forms, e.g. let {x, y} = obj; but just assignment expressions, {x, y} = obj -- takes advantage of this cover grammar approach, but it will require semantic checks. And as Waldemar points out, this constrains RHS structuring via object and array initialisers to have the same syntax (unless we add more semantic post-grammar restrictions there too!) as the LHS destructuring patterns. This may be a bad constraint. Type guards don't seem like they'll be only LHS or RHS, indeed the :: choice for guard prefix was based on easy composing of guards after property names in object initialisers. But some future extension might want LHS and RHS to diverge. Arrow functions really do want a different ArrorFormalParameters sub-grammar from ( Expression ) where Expression is of course a comma-expression. So I'm investigating GLR parsing. It can handle all of these cases without ambiguity. It does not require implementatoins to have forking parsers, but it is an attractive spec tool. More on this in a bit. /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: arrow syntax unnecessary and the idea that function is too long
Thanks Claus for the synopsis and pointing out the 404. ometa is the last paper: http://www.tinlizzie.org/~awarth/papers/dls07.pdf, which is a javascript packrat parser. Tom and Mark are very familiar with this work I believe. There are some great examples of javascript monads or monad-like frameworks - for example jquery ... It's unfortunate the harmony grammar cannot take advantage of these more recent advances in parsing, however I understand Brendan's point about accommodating the major implementors. Any transpiler could certainly go this route. From: Claus Reinke claus.rei...@talk21.com To: Kam Kasravi kamkasr...@yahoo.com; Brendan Eich bren...@mozilla.com Cc: es-discuss es-discuss@mozilla.org Sent: Friday, May 20, 2011 2:11 PM Subject: Re: arrow syntax unnecessary and the idea that function is too long For a presumed-done area, there has been a lot of activity in parser research recently, partially fueled by IDEs and DSLs (model-driven development with good generated tool support). For grammar spec purposes, it might be interesting to look at self-applications of these techniques (IDEs for parser development, with support for grammar analysis and debugging). I keep meaning to look at ANTLRWorks: The ANTLR GUI Development Environment http://www.antlr.org/works/index.html Anyway, the titles for two of those three urls, for those who don't have time to look right now: http://www.cs.nyu.edu/rgrimm/papers/pldi06.pdf Better Extensibility through Modular Syntax Robert Grimm http://www.cs.rit.edu/~ats/projects/jsm/paper.xml Monadic Parsing using JavaScript Axel T. Schreiner Independent of parsing, I recommend that readers of this thread scroll down to the interpreter (search for 'eval'). It gives an example of how an essential programming pattern (monads) is technically supported in Javascript, but mostly useless due to syntactic overhead: instead of bringing out the essential aspects, they get burried in syntax (and if one tries to shunt the 'return's out of the way, ASI says hello). Javascript coders, when faced with this issue, tend to split into two groups: one that abandons the variable binding functionality of monads and makes due with libraries, and one that writes preprocessors (the author here, also streamline.js and Jscex as just two recent examples from the nodejs list). Just as a further example for those still unconvinced by the case for better function syntax: it isn't sufficient, but it is necessary!-) http://www.cs.ucla.edu/~awarth/papers/dls07.pdf 404 for me? Claus___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Modules first or second class (Re: I noted some open issues on Classes with Trait Composition)
This is sort of an interesting point. In a related question I've wondered about how narcissus could use modules in lieu of its current way of eval'ing definitions.const in jslex and jsparse in order to get the operators, tokens and keywords in local scope for both the lexer and the parser.If narcissus were to take advantage of harmony could jsparse, jslex do an 'import jsdefs.consts' as an alternative? From: Claus Reinke claus.rei...@talk21.com To: David Herman dher...@mozilla.com Cc: es-discuss@mozilla.org Sent: Friday, May 20, 2011 2:51 PM Subject: Modules first or second class (Re: I noted some open issues on Classes with Trait Composition) I think modules are a construct that evaluates to an object is the wrong way to think about them. Syntactic modules are a second-class construct that is not an expression. You can reflect on modules at runtime, and that reflection is provided as an object, but that's because almost all compound data structures in JS are objects. But I would advise against describing modules as a kind of object. Just a note on this: for me, that means Harmony modules are a step back from what I can implement in JS/now. Not having first-class modules has been a major drawback in Haskell (which has a strictly 1980s-style module system), leading to all kinds of work-arounds. One of these workarounds, which I expect to see and use a lot in Harmony, is to have first-class modules-as-records (or objects) inside second-class built-in-modules. Is this an intended outcome of the Harmony module design? For instance, I've got a parser-combinator library and a (near) ES5 grammar built on it, and to test, I pass one module to the other, and both modules to the tester: test(source, options, pc, grammar(pc)) Strictly speaking, the pc module also depends on the grammar module, for grammar-specified whitespace, but cyclic structures are a bit awkward in Javascript. Claus ___ 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: Function syntax
I also tend to agree with this sentiment, despite having loved operator overloading in C++. My reasoning is that javascript has no current operator overloading to speak of and adding recent proposed operator syntax variations would seem to be better delegated to a transpiler of your choice. IMHO a better approach would be to minimize operator overloading in the current grammar and standardize an extensible grammar model/framework so that coffeescript, traceur and cousins are more easily produced and transpiled to a simple (if not verbose) target. Having a common grammar framework based on PEG's or something with similar characteristics (closed under composition, scannerless, ordered choice) and standardized among browser vendors would allow far more developers to innovate at the grammar level with the most popular or innovative grammar dialects being crafted by many rather than a few. From: David Griffiths dxgriffi...@gmail.com To: johnjbar...@johnjbarton.com Cc: es-discuss@mozilla.org Sent: Thursday, May 19, 2011 8:46 AM Subject: Function syntax I agree with John, here, and think his sentiment is probably the most appropriate of all I've read. For all the talk about what's usable and readable, I haven't seen much mention of empirical testing done with ordinary people... (My sincere apologies if there's some usability test lab for middlingly intelligent JavaScripters that I'm not aware of). It's worth remembering that nobody, no matter how well-intentioned, can ever really imagine what it's like to be more stupid or more ignorant than they currently are. John J. Barton wrote: Both application developers and library/framework developers benefit from clear, widely understandable code. Adding bizarre special characters and programming constructs that require world-class programming language expertise to understand helps neither group. jjb ___ 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: ECMAScript Object equivalence classes proposal
On Apr 5, 2011, at 1:38 PM, David Bruant david.bru...@labri.fr wrote: On Apr 2, 2011, at 5:11 PM, Brendan Eich wrote: On Apr 2, 2011, at 4:19 PM, David Bruant wrote: I have the feeling that none of these can help out with multiple inheritance. This is the problem I want to address. Why? I mean, given the WebIDL and DOM changes. Is multiple inheritance a use case that TC39 intends to address in a generic manner? No. Inheritance-based instanceof testing for the purpose of dynamic classification of objects is most appropriate in statically typed subclasing===subtyping languages. Multiple inheritance (at least for interfaces) is almost essential in such languages. That isn't is the case for dynamically typed subclassing!==subtyping languages. There is lots of experience with such languages that shows that dynamic classification via class or superclass inclusion testing is a poor practice. This is because it is possible (and often even necessary) to create behaviorally substitutable classes that don't participate in an inheritance relationship. By using such a test you are forcing downstream developers to fit into your implementation hierarchy and there may be strong reasons to do otherwise. I am highly interested by all what is in this paragraph. Would you have articles talking about that you could refer me to? Yes I am as well. Allen, were you thinking of adding a required attribute to the property MOP (this may be similar to traits)? The type signature would then be some encoding of all required properties. instanceof testing is very familiar to programmers coming from a Java-like language background. But like a number of other statically-typed language practices, instanceof testing is not a good idiom to use in JavaScript. If an EventTarget must have specific behavioral characteristic, then define those characteristics such that any object that needs to be an EventTarget can implement them, regardless of what is on its [[Prototype]] chain. If it is important to be able to dynamically test if an object can serve as an EventTarget then define a property that provides that characterization and make it part of the specified behavior of an EventTarget. Just don't require that EventTarget.prototype is somewhere on the [[Prototype]] chain. So in a way, are you saying that the DOMCore/WebIDL decision is a bad one? If so, how would you solve the Element+EventTarget problem? One interesting aspect I see in having all the things you inherit from in the [[Prototype]] chain is that you may be able to communicate with all other instances in a way. It may be a completely stupid idea, I don't know. Practically speaking, large parts of JavaScript community are just starting to use the language to build rich class libraries. Many of them don't have experience with dynamically typed OO languages so they naturally follow the practices they are familiar with. We really need to guide them towards using the best practices that have been proven effective for dynamic OO languages rather than facilitating continued use of static OO idioms that are a poor fit to JavaScript. I don't think I am familiar enough with dynamically typed OO languages to fully grasp how they work and best practices, but if other people are, maybe they should weigh in for another decision for the Element+EventTarget issue. It would be a great occasion to guide the JavaScript community toward using good practices, wouldn't it? I also came from a C/Java background and learnt JS by myself. I'd be happy to learn best practices of dynamic OO languages. As for the first paragraph, if you have articles to share on the topic, I would be happy to read them. David Allen ___ 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: Inner functions and outer 'this' (Re: That hash symbol)
Thank you Allen for the references and analysis. It's interesting that Gilad argues resolution should be lexical followed by inheritance to avoid 'unanticipated name capture' that may exist within the inheritance chain. Probably even less of an option given backward compatibility requirements. On Mar 31, 2011, at 11:12 AM, Allen Wirfs-Brock al...@wirfs-brock.com wrote: On Mar 31, 2011, at 10:32 AM, Kam Kasravi wrote How reasonable would it be to treat 'this' in a similar way that the prototype chain is referenced when resolving identifiers? I realize there would be ambiguity for like named identifiers but that problem exists now... In Allen's first example this.handleClick(this,e) would not be resolved with it's implicit binding to elem, so 'this' would be bound lexically and the code would just work. The second 'this' would of course default to the implicit bindin Other languages have tried to integrate inheritance based binding with lexical binding. See f http://dyla2007.unibe.ch/?download=dyla07-Gilad.pdf and http://bracha.org/newspeak-modules.pdf for one example and additional references. There are some complications to this approach and it seems to me that it is unlikely to be something that could be retrofitted in JavaScript. Allen ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Inner functions and outer 'this' (Re: That hash symbol)
On Mar 28, 2011, at 10:35 AM, Allen Wirfs-Brock al...@wirfs-brock.com wrote: On Mar 27, 2011, at 11:13 AM, David Herman wrote: To be fair, your suggestion is more moderate than de Bruijn, although it's not clear whether you're proposing the ability to refer to shadowed bindings of *all* variables or just |this|. If it's the former, I'm *strongly* opposed. If it's the latter, well, I guess I'm still pretty opposed, just maybe less strongly. :) Dave, I think that applying this solution to the this-scoping issue may be a really good idea Claus, thanks from bringing a new (old) idea into the discussion. I agree with Dave about all the fragility issues he mentioned for the general case. Also, I just don't see the general problem (if it is even a problem) as one that is important enough to try to fix in the language since it is probably rare and it can be avoided by careful naming. However, the specific case of 'this' is a different matter.'this' is implicitly rebound in every function scope and the JavaScript programmer has no direct control over the naming and shadowing. The result is that they have to know and use the self renaming pattern. This issue shows up enough in defining objects via object literal methods and in methods that call higher order functions that it is something that may well be worth addressing in the language. Particularly as we discuss adding additional declarative forms to Harmony that included nested method definitions. The outer 'this' problem is limited enough that we can avoid things like dynamic scoping complications in the solution. Also it is limited enough that I don't believe that the solution imposes refactoring complications. Here is a sketch of a proposal: ^this is added as a new lexical token of the language. When spoken it is pronounced as outer this . In the expression grammar ^this is a primary expression. It is a syntax error for ^this to appear outside of a function body. It may not occur at the top level of a program. When evaluated, the value of ^this is the this binding of the function that immediately lexically encloses the function body that contains the ^this. It is a early syntax error if there is no such function. For example: //at the top level var self = ^this; //syntax error, at the top level function foo() { ^this.bar(); //syntax error, no enclosing function } The two primary use cases for ^this are exemplified by the following two examples: MyObj.prototype.addClickHandingForElement(elem) { elem.addEventListener('click', function (e) {^this.handleClick(this,e)}); } This does provide an elegant solution but perhaps for a somewhat uncommon problem. Today I think most would do the following (if not using self): MyObj.prototype.addClickHandingForElement(elem) { elem.addEventListener('click', this.handleClick.bind(this)) } Where the event.target would be used in the context of handleclick. I've noticed that coffescript uses this= to autobind but not disambiguate. One possible alternative would be to have a keyword modifier similar to your suggested method called callback which autobinds this. From a declarative viewpoint it would be clear what methods within the type were intended to be used in this way. Although it would not handle the inner outer this use case. Your second example below I would of done as: MyObj.prototype.wrap = (function (wrapper) { // create a wrapper object that limits access to the properties of one of my objects return { name: this.id, //fix name of wrapper at creation (uses this of wrap call get foo () {return wrapper.foo}, //outer this is this of wrap call set bar(val) {wrapper.bar = val} //outer this is this of wrap call })(this); even if ^this were available since I would find it clearer. At least in my experience I do not run into many scenarios where both this and ^this are accessed in the same context, but I do use/find many scenarios where callbacks should be bound especially when custom events are used liberally or within node. In those cases where I need both I tend to curry the inner this and provide it as a parameter to the outer callback. Somewhat contrived for the first example since elem is available in the event but it would look like elem.addEventListener('click', this.handleClick.bind(this).curry(elem)) assuming curry was available on the Function prototype. MyObj.prototype.wrap = function () { // create a wrapper object that limits access to the properties of one of my objects return { name: this.id, //fix name of wrapper at creation (uses this of wrap call get foo () {return ^this.foo}, //outer this is this of wrap call set bar(val) {^this.bar = val} //outer this is this of wrap call } Note that only one level outer this access is supported, ^^this would be a syntax error. In the rare cases where
Re: Lexically Scoped Object Extensions (was About private names)
On Mar 21, 2011, at 9:40 PM, Brendan Eich bren...@mozilla.com wrote: On Mar 21, 2011, at 6:17 PM, Allen Wirfs-Brock wrote: On Mar 21, 2011, at 5:55 PM, Waldemar Horwat wrote: You'd still run into all of the issues caused by private filter behaving like a C++ #define. #define exagerrates. For example: var foo = {filter: 34}; then pass foo to an outside client. Trying to interpret your comment. Are you saying that the above appearing within the scope of the private filter would unintentionally use private foo instead of public foo? That's true, but the whole point of the block (and the extension declaration) was to constrain the visibility of private filter, so it could be used as an extension property name in a limited scope. Defining a property using that name within that scope seem like a pretty clueless error. Sure, it will happen, but I don't see how this use of lexically scoping is any more or less error prone an any other use. You could be right. But there is a difference, it is not as extreme as #define, but it's real. It is what Andrew described so clearly: that any foo after any dot in the scope of private foo is bound to the private name. With let, const, or function in block, the lexical scoping affects the meaning of unqualified identifiers as primary expressions. It doesn't affect the meaning of identifiers (IdentifierName in the grammar) on the right of '.' in MemberExpressions. Does this matter? In Java it matters much less because of types. In JS, it matters more but an IDE could still help (as in Java, but without types -- just lexical use-to-def connection-making by the IDE). There would be several private names per type though each one preventing any occurrence of that name within any identifier in any member expression at that scope. This would complicate things like minifiers. Not to mention trying to mix say svg, canvas and Dom within some framework since they all use common member names such as element, node, children, attributes, etc. I'm not saying this characteristic of private names is bad or good. It is distinct from lexical binding in Harmony without private names, though. /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: [whatwg] Cryptographically strong random numbers
hey along these lines, does anyone track strawman implementations in various vendor browser nightlies? Something like http://kangax.github.com/es5-compat-table/ but for the various harmony proposals. kam From: Brendan Eich bren...@mozilla.com To: Mark S. Miller erig...@google.com Cc: es-discuss es-discuss@mozilla.org Sent: Wed, February 16, 2011 12:00:37 PM Subject: Re: [whatwg] Cryptographically strong random numbers On Feb 16, 2011, at 11:31 AM, Mark S. Miller wrote: This issue seems to be the only significant remaining controversy here, so more words settling it more decisively would be welcome. Thanks. Not to drag this out, but the randomness quality issue (or non-issue, now) is not the only remaining one. Allen raised the question of whether typed arrays should be used at all when Array might do. This was in reply to your suggestion that the sooner not later simple and usable API depend on the forthcoming binary_data strawman. I'm not sure what the browser vendors who don't yet support typed arrays think. Purely out of expediency and I'm all right, Jack Firefox boosting, typed arrays are fine and have some advantages over plain old Array, as Adam has laid out. But ideally, we should hash this out with Microsoft people weighing in here on es-discuss (I'm told they're not allowed to participate on whatwg lists). I miss the Opera presence on TC39 but I know a few still read and post. Would be great to hear from them soon too. /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: Simple Modules: lazy dependency evaluation
I assume you mean m.load(la1). So what is the behavior if you do new m.load(la1).Foo() if you know Foo is an exported object? Is there a module API that allows one to introspect a modules content? On Jan 26, 2011, at 1:46 PM, Sam Tobin-Hochstadt sa...@ccs.neu.edu wrote: On Wed, Jan 26, 2011 at 2:04 PM, James Burke jrbu...@gmail.com wrote: CommonJS Modules 1.1 allows this kind of construct in module code: var a; if (someCondition) { a = require(a1); } else { a = require(a2); } and the module a1 is not actually evaluated until execution reaches the a = require(a1) call. 1) Could something like this work in Simple Modules? If so, what would be the syntax for it? You can use module loaders to do exactly this (I believe, based on my understanding of CommonJS). It would look like: var ml = ... the desired module loader ... var a; if (someCondition) { a = ml.load(a1); } else { a = ml.load(a2); } This produces a module instance object, bound to |a|. It doesn't, however, allow you to import from |a|, since nothing is statically known about what the exports of |a| are. 2) What are the design decisions behind only allowing module and use at the top level of a module? Modules are a statically scoped construct, and the implementation and the programmer can both statically tell where variables come from. This prevents modules from being dynamically created, except in the context of module loaders, as seen above. -- sam th sa...@ccs.neu.edu ___ 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: Simple Modules: lazy dependency evaluation
I understand why callbacks are required for module loaders given they fetch asynchronously, though it's too bad this isn't more tightly integrated with an eventing model where events could be published when modules are loaded. I imagine TC39 has no interest in broaching an event system per se, but IMHO there would be rapid adoption and tighter integration if module loading could have associated events like DOMReady etc. A different layer and a different committee no doubt. Sent from my iPad On Jan 26, 2011, at 2:50 PM, David Herman dher...@mozilla.com wrote: On Jan 26, 2011, at 4:04 PM, Brendan Eich wrote: On Jan 26, 2011, at 1:54 PM, Kam Kasravi wrote: So what is the behavior if you do new m.load(la1).Foo() if you know Foo is an exported object? Sam addressed that directly (nothing is statically known), cited in full below. Oh, I understand this question better. To clarify a bit further: the module loading API returns the first-class module instance objects, rather than statically known modules. The code would actually look like this: ml.load(a1, function(m) { // in here, m is just an ordinary variable // bound to a first-class object that reflects // the contents of the module loaded from a1 ... }); Is there a module API that allows one to introspect a modules content? Are you reading the wiki? There are explanations and examples of first-class module instance objects on the wiki, but to be fair some of the details are a bit out of date (in particular the scoping semantics has changed a bit). Updating the wiki is towards the top of my to-do list. Dave ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Private names use cases
Coming from the commonjs perspective I did something similar to create private data per instance using a closure. I feed an object literal into a 'type' generator so that: Type.create('Foo', { imports: { log: require('log') }, specification: { 'private': { bar: null, baz: null }, 'constructor': function(props) { try { var properties = props || {}; bar = properties.bar; } catch(e) { log.Logger.error(this,e); } return this; }, 'public': { print: function() { log.Logger.debug(this,'bar='+this.getBar()); } } } }, require, exports); generates // Foo var Foo = (function() { // imports var log = require('log'); // public Foo.prototype['print'] = function print() { log.Logger.debug(this, 'bar=' + this.getBar()); }; function Foo() { // private function privateData() { this.bar = null; this.baz = null; }; var p_vars = new privateData(); var bar = p_vars.bar; this.getBar = function getBar() { return bar; }; this.setBar = function setBar(b) { bar = b; return this; }; var baz = p_vars.baz; this.getBaz = function getBaz() { return baz; }; this.setBaz = function setBaz(b) { baz = b; return this; }; // constructor var args = Array.prototype.slice.call(arguments); arguments.callee.ctor = function(props) { try { var properties = props || {}; bar = properties.bar; } catch(e) { log.Logger.error(this, e); } return this; }; return arguments.callee.ctor.apply(this, args) || this; }; return function() { var args = Array.prototype.slice.call(arguments); arguments.callee['constructor'] = Foo; return new Foo(args args.length args[0]); }; })(); exports.Foo = Foo; the object literal looks a little like the object initializer strawman (http://wiki.ecmascript.org/doku.php?id=strawman:object_initialiser_extensions). The idea is the user is shielded from private data lookup when creating an object instance. eg Foo({bar:'hello'}).print(); // internally calls new Foo({bar:'world'}).print(); From: Garrett Smith dhtmlkitc...@gmail.com To: Allen Wirfs-Brock al...@wirfs-brock.com Cc: es-discuss@mozilla.org Sent: Mon, December 20, 2010 11:28:15 PM Subject: Re: Private names use cases On 12/20/10, Allen Wirfs-Brock al...@wirfs-brock.com wrote: I've seen mentions in the recent thread that the goal of the Private Names proposal was to support private fields for objects. While that may be a goal of some participants in the discussion, it is not what I would state as the goal. I have two specific use cases in mind for private names: 1) Allow JavaScript programmers, who choose to do so, to manage the direct accessibly of object properties. This may mean limiting access to methods of a particular instance, or to methods of the same class, or to various friends or cohorts, etc. If private is based on lexical scope then it's already possible but it can be a bad smell. For example: var Blah = function() { var privateBlah = { complicatedDirtyWork : function() { alert(blah.) } }; var Blah = { goBang : function() { privateBlah.complicatedDirtyWork(); } }; return Blah; }(); Blah.goBang() Great for a one-off, but when you wanna have many of the ADT (many instances of Blah), then there's an equal number of privateBlah and the strategy must make some sort of lookup, e.g. var delegateBlah = getPrivateBlah( this ); delegateBlah.doTrick(); That's a bit more work and when there are only a couple of fields, it seems like too much trouble. If it were authored in a way that obviates that cruft but could still be facilitated by using scope tricks, as above? -- Garrett ___ 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: instanceof trap and default handler for Proxies
How 'bout extending proxies to provide an introspection API? From: Tom Van Cutsem tomvc...@gmail.com To: es-discuss es-discuss@mozilla.org Sent: Thu, October 28, 2010 6:02:11 AM Subject: instanceof trap and default handler for Proxies Hi, I created a strawman page to host possible extensions to harmony:proxies: http://wiki.ecmascript.org/doku.php?id=strawman:proxy_extensions It currently hosts two extensions: - enabling proxies to trap instanceof - standardizing the default no-op forwarding handler At least the first will be on the agenda for the November TC39 meeting. Please comment and discuss. Cheers, Tom___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: instanceof trap and default handler for Proxies
I assume the answer is no, but can one proxy simple modules? From: Tom Van Cutsem tomvc...@gmail.com To: es-discuss es-discuss@mozilla.org Sent: Thu, October 28, 2010 6:02:11 AM Subject: instanceof trap and default handler for Proxies Hi, I created a strawman page to host possible extensions to harmony:proxies: http://wiki.ecmascript.org/doku.php?id=strawman:proxy_extensions It currently hosts two extensions: - enabling proxies to trap instanceof - standardizing the default no-op forwarding handler At least the first will be on the agenda for the November TC39 meeting. Please comment and discuss. Cheers, Tom___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Const functions with joining is ready for discussion
I tend to prefer 'const function' since it seems more consistent with other types of modifiers such as 'public' and 'private' covered in the classes as sugar strawman Sent from my iPad On Sep 6, 2010, at 7:47 AM, Mark S. Miller erig...@google.com wrote: On Mon, Sep 6, 2010 at 8:14 AM, Chris Marrin cmar...@apple.com wrote: On Sep 5, 2010, at 7:19 AM, Mark S. Miller wrote: At the last EcmaScript meeting, I proposed the const function notation seen at http://wiki.ecmascript.org/doku.php?id=strawman:const_functions. Someone -- my apologies, I forget who -- suggested that const functions would make the old never-implemented ES3 joining optimization safe. (If you don't know what that is, don't worry about it. The new explanation is self contained.) I have now enhanced that strawman page with a promotion rule for const functions that provides this optimization benefit is a predictable manner. Opinions? Forgive my outsider comment. I was not at the meeting where this was proposed, so this may have been discussed. But it seems like using 'const' in place of 'function' may be syntactically valid but it's confusing to read. It seems like 'const function', while more wordy, would be more clear, as in: const function foo(a) {return a(foo);} Omitting the 'function' keyword is going to make many instances of this look like a function call rather than a function declaration. Does that cause parsing problems or something? This was raised at the meeting without resolution. As I said then, if necessary to get consensus, I am willing to agree to const function. That said, I don't like its verbosity. Of all things that need to by syntactically lightweight, function expressions are the most pressing. That's why we keep trying to find a shorter syntax. (I still like # FWIW) If we accept const function, frankly, for the sake of readability, I would probably continue to write list.filter(function(e) { return e % 2 === 0; }) rather than list.filter(const function(e) { return e % 2 === 0; }) unless I knew that the loss of efficiency, security, or simplicity actually matters in this individual case. After all, as Sussman Abelson say (paraphrasing from memory): Programs should be written primarily for people to read and only secondarily for machines to execute. I do see how list.filter(const(e) { return e % 2 === 0; }) can seem confusing at first. But even for a reader who doesn't know that const is a keyword, the code above still wouldn't be a valid function call because of the immediately following body. I've been using this shorter syntax on slides and have never seen anyone confuse it with a function call. -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Modules: Name capture
Hi Dave By explicit linking are we talking about mechanism's to unambiguously reference modules that may otherwise be ambiguous? For example in java if 'Node' could refer to a Node class in several different packages, the language allows one to fully qualify the Node class eg foo.Node. Just want to make sure I'm clear on the distinction between explicit and implicit linking. Thx kam On Jun 2, 2010, at 12:14 PM, David Herman dher...@mozilla.com wrote: I don't have the time or inclination to provide a full bibliography. I consider your argument withdrawn, then. Excuse me? My argument is not withdrawn (are we in court?). If you are unaware of decades of prior art on modules, that's not my failing but yours. My argument was and remains that others have gone down that road, and it's still very much an open research topic how to create module systems that provide the generality of explicit linking with the convenience of implicit linking. See e.g. Derek Dreyer's work, starting with his thesis and continuing to this day. Possibly, depending on whether you want to present modules to themselves as well. As I believe we discussed in our most recent f2f, it is possible to provide modular code with access to its own reified module instance via some distinguished symbol (e.g., this at the top level). And of course, modular code always has direct individual access to its own exports. Hence depending. As recast, therefore, the example introduces Odd to even.js and Even to odd.js. It's pretty minimal. And yet it's still too expensive. No one will take the step from non-module code to module code. They just won't. Besides, a not-quite-so-bad example of the Odd and Even modules is pretty weak tea. The point is, you can special-case this if you want, but if you have a module graph of N modules, and each needs to be explicitly linked with N - 1 other modules, then you impose a quadratic code-size requirement on programmers. Unless, as I said, you beef up your linking-specification language. Dave ___ 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: Modules: Name capture
Hi Ihab This problem has many similarities to the XML / WSDL world. The use of namespaces and versioning has been leveraged there to disambiguate names which otherwise could be occluded by changing interfaces. That being said, I like your suggestion of 'renaming at the boundary' where one could possibly disambiguate like names. Independent of versioning, which is how many large software systems guarantee integrity, we need something like namespaces or your 'boundary renaming' to avoid name collisions. Section 4.2.1 in XSchema describes import, include and redefine as mechanisms to allow composition of multiple schemas and is worth reading. thanks kam From: ihab.a...@gmail.com ihab.a...@gmail.com To: es-discuss Steen es-discuss@mozilla.org Sent: Wed, May 26, 2010 3:39:10 PM Subject: Modules: Name capture Hi folks, As promised, this is the first major issue I wish to raise regarding the Simple Modules strawman. This point was first brought to our collective attention by my colleague, Jasvir Nagra. I'm describing this from scratch here, even though this came up previously on the list, to help anyone who has not been following the previous thread in detail get a handle on the issues. I've divided it into sections to avoid tl;dr for people who are already up to speed. == Motivating factors we agree upon == The Web is large, and full of code. For any given corpus, there may be millions of copies on various people's servers; hundreds of forks on github; and dozens of officially supported versions on the Website of the maintainers. This presents a distributed version matching and *naming* problem quite unlike any other we have encountered so far in software development. Software is now created as casually as Web pages. All of us who are interested in the module problem seem to agree (and please correct me if I am mistaken in this or any other collective claim) that even URL string equality is not a good metric of whether the resource found at that URL is the same: on the one hand, the stuff retrieved via a URL can change from one moment to the next; and on the other hand, distinct URLs may validly refer to bitwise identical code. All of us also seem to agree that we cannot brush this problem under the rug completely: we cannot *completely* relegate it to off-spec configuration management or build process. When one is composing software from various independent sources, this software must sometimes make demands for loading things that the parent loader did not even know about. Yet the parent loader must sometimes provide modules to what is being loaded for convenience and unification. So, if I write an application that loads modules M1 and M2: * I may want to provide a common module jQuery to M1 and M2; but also * In order to do its work, M1 may want to fetch some module Z of which I have never heard. To put it another way, modules on the Web must be able to wire themselves, and compute, over the Web as it is, rather than over the small set of software that happens to be installed in (say) the /usr/lib directory of the local system. In Python, I can simply import smtplib. On the Web, the question is, which one? == Current Simple Modules solution == The Simple Modules strawman shows a rather clever solution to this problem. It distributes the mappings -- from agreed-upon names to gnarly URLs -- across the codebase in a fine-grained fashion. At the most basic level, I can map the name jQuery to my chosen copy of the jQuery library, and use it as below. Nested modules can choose their own versions of (say) YUI, and use them as well. module jQuery = load http://.../jquery-1.3.2.js;; module Foo { module YUI = load http://.../yui-3.1.1.js;; module Bar { import jQuery.ajax; import YUI.Accordion; ajax(...); Accordion(...); } } This also works if I know that some library simply uses the name jQuery, and I map that to my own chosen copy. In the following example: // somelib.js import jQuery.ajax; ajax(...); // My code module jQuery = load http://.../jquery-1.3.2.js;; module Somelib = load http://.../somelib.js;; the code in somelib.js will pick up the jQuery that I have defined prior to the load. The clever part of this is, again, the decentralized name assignments. == Pitfalls in the Simple Modules solution == The problem is that, in the space of module names, the current Simple Modules strawman introduces a hazard of inadvertent name capture (though it does clearly separate other names such as var, const and function declarations). An example is: // zero.js: module jQuery = load 'jquery.js'; module Drawing = load 'footgun.js'; module One = load 'one.js'; // one.js: import jQuery.ajax; module Two = load 'two.js'; // two.js: import jQuery.ajax; At the time that one.js was written, two.js did not contain a reference to Drawing. Now, unbeknownst to the author of one.js, two.js changed
Re: modules proposal
Thanks Brendan, David. A few comments below. From: Brendan Eich bren...@mozilla.com To: David Herman dher...@mozilla.com Cc: Kam Kasravi kamkasr...@yahoo.com; P T Withington p...@pobox.com; es-discuss Steen es-discuss@mozilla.org Sent: Sun, May 16, 2010 8:00:35 PM Subject: Re: modules proposal On May 16, 2010, at 7:18 PM, David Herman wrote: RegExp literal expressions evaluate to mutable object values, per ES5 and reality (ES3 got this wrong, making an object per literal lexeme -- not per evaluated expression). Yes, but there's no reason to assume a RegExp token would be a RegExp literal expression. The reader of the source might assume exactly that. One regexp looks like another, and might be expected to quack like any other. Modules are static. Do we really want to drag in some of the runtime (RegExps) just to filter imports? This seems not only like over-design, but also the wrong design. Import/export declarations are distinguished contexts; there's no need to introduce runtime evaluation. A sensible design for import/export declaration with a RegExp would simply be run a regular expression at compile time, with no ES object creation involved. That's possible, and desirable in practice: regexps have effects in real-world implementations (the unspecified but still used RegExp.$_, RegExp.$1, etc. properties). If written with /y or /g they mutate there own lastIndex property and use it for subsequent matches (how many times is /.*\.js$/g evaluated in that import directive?). [kam] My use case is the regex would be evaluated server-side with no client-side eval at runtime or compile time. This pertains more to the dynamic loader but what I was after was an ability to partially import a module in those cases where the entire module was not needed. But in reality, its likely the entire module would be fetched and evaluated. I do think that module authors would package modules and nested modules in ways where the server could optimize what was returned to minimize additional trips if regex's were allowed. I'm not advocating the feature, but if we did include it, ISTM the benefit of using regexps is precisely their limited power. You'd have to limit that power from what it is today in terms of effects (including those pesky de-facto standard effects). Another unwanted power is that these NFAs misnamed regular expressions can blow up with O(exp(n)) complexity due to backtracking. This is enough of a problem that we're about to try throwing an exception when JS regexp exec complexity measured in terms of active backtrack states compared to target string length seems to be worse than O(n^3) (see https://bugzilla.mozilla.org/show_bug.cgi?id=452451 and bugs it cites). Making some tamed, quasi-regexp-just-for-import seemed not what Kam proposed, but anyway undesirable on its face. I mean, the taming attempt is desirable ignoring the big picture, but the whole idea seems misbegotten. My two cents. [kam] An example might be something like SVG.*Filter* where the importer was interested in retrieving only filter related features within a SVG module. Brendan's point is valid, if the regex is 'quasi' or treated differently than true regex expressions then the use case(s) need to be convincing. /be___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: modules proposal
Along these lines of imports, a regex would allow partial imports. On May 15, 2010, at 4:53 AM, P T Withington p...@pobox.com wrote: On 2010-05-13, at 19:41, David Herman wrote: I've updated the strawman proposals for static modules and dynamic module loaders and would love to get feedback from the es-discuss community. * Static modules: http://wiki.ecmascript.org/doku.php?id=strawman:simple_modules http://wiki.ecmascript.org/doku.php?id=strawman:simple_modules_examples Looks great! I wonder if you considered having an export list, rather than tagging the individual exports? I think that makes it easier to see/document the public API of a module. You could at the same time allow renaming on export. module Cowboy { export {draw: d, shoot: s}; function d () { ... }; function s () { d(); }; } FWIW, the rename on import looked backwards to me at first glance, but I think I can learn. Do we really need to say `.*` for all? We couldn't just say `import Math`? ___ 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: Traits library
Hi Brendan Picking up where Tom left off below... I've wondered how you and the ECMAScript body prefer to have particular concepts presented. Given that the lag time between new syntax and conformance across vendors could be months, years or never, it seems that there is always a need to provide a 'shim' or implementation that emulates proposed syntax. I think many concepts including Tom and Mark's steer away from new syntax due to the problems noted. In general should there be due diligence on both? I realize this may vary per strawperson but thought you may have a general philosophy to share. thx kam From: Tom Van Cutsem to...@google.com To: Brendan Eich bren...@mozilla.com Cc: Mark S. Miller erig...@google.com; es-discuss Steen es-discuss@mozilla.org Sent: Thu, February 18, 2010 11:09:18 AM Subject: Re: Traits library Put together the user and implementor taxes, and you have sufficient cause for new syntax. Add to this tax revolt the plain desire for better syntax-as-user-interface. If you want const f(){}, why //wouldn't// you want declarative trait syntax? Hi Brendan, Thanks for enlightening us with the implementation-level issues involved in getting user-land traits optimized. That definitely puts things in perspective. I wholeheartedly agree that dedicated syntax would be of great help to users, and to implementors as a not-to-be-underestimated bonus. I am not at all opposed to dedicated syntax/semantics for traits in ES-harmony. Think of traits.js more as an exercise in exploring the design space of what is possible today. For example, the fact that ES5's property descriptor maps turned out to be directly usable as traits was a surprising new insight to me. I think the most useful outcome of this experiment is that it gives us a better idea of what the fundamental limits of a library approach are. For example: that syntax for traits is (mostly) not a boilerplate issue but a semantic issue (early error feedback) + an implementation issue (method sharing). And who knows, if there is an uptake of this library in ES5, it would help familiarize programmers with traits without them having to wait for dedicated syntax. But I am aware that this is very optimistic: many have previously designed good class, mixin and even trait libraries for ES3, and to the best of my knowledge, none of these seem to have widely caught on. Cheers, Tom___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Traits library
thanks Dave, Brendan. the net-net then is to emphasize syntax but when possible outline a migration path. This may have been obvious to many but at least I've been very conservative about suggesting new syntax. Worth far more than 2 pennies :) kam From: David Herman dher...@mozilla.com To: Kam Kasravi kamkasr...@yahoo.com Cc: Tom Van Cutsem to...@google.com; Brendan Eich bren...@mozilla.com; Mark S. Miller erig...@google.com; es-discuss Steen es-discuss@mozilla.org Sent: Fri, February 19, 2010 8:58:52 AM Subject: Re: Traits library First, this traits proposal looks very nice -- thanks, Tom and Mark, for your work on this. I want to add another point about the benefit of new syntax by calling out a piece of the code.google.com proposal under Performance, where it says: In order for the partial evaluation scheme to work, programmers should use the library with some restrictions. This is one of the places where you have the opportunity to call out more precisely in the language where users can expect better performance. By creating a declarative syntax, you invite implementors to make the common cases efficient, and provide a clearer set of rules for programmers to know when they are or aren't straying into you can do that, but it'll cost you territory. Another side of the same coin is that you /dis/invite users from accidentally straying into the expensive territory. The convenient syntax provides an incentive for people to use the version you want to be the common case. On Feb 19, 2010, at 7:29 AM, Kam Kasravi wrote: Picking up where Tom left off below... I've wondered how you and the ECMAScript body prefer to have particular concepts presented. Given that the lag time between new syntax and conformance across vendors could be months, years or never, it seems that there is always a need to provide a 'shim' or implementation that emulates proposed syntax. I think many concepts including Tom and Mark's steer away from new syntax due to the problems noted. In general should there be due diligence on both? I realize this may vary per strawperson but thought you may have a general philosophy to share. I know your question was to Brendan, but if I may add my $.02: we should be mindful but not terrified of changing the language. That's what we're here to do, after all! Now, the specific concern over new syntax has been that it prevents a program from even running, which means you can't dynamically test for a feature before using it. Putting aside the fact that you could use `eval' (or dynamic module loading, given a module system) for such a purpose, I'm still not sure how often people actually want to build two different implementations of a program based on whether or not a particular feature exists. We shouldn't hold back the language just because it'll take take for new features to be spread enough for commonplace use. That's all the more reason to move forward sooner than later. That said, I think something like the traits library could have a nice migration path, where a library compatible with ES5 could be even more attractive down the road with new syntax. Dave___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Traits library
Do the various server-side implementations count for example ejsscript which incorporated many features of es4? Or is the list specific to translation engines that take some ecmascript derivative and produce harmony or es5? Given what I've seen in translators to javascript from language 'X', the list could be pages. From: Brendan Eich bren...@mozilla.com To: es-discuss Steen es-discuss@mozilla.org Sent: Fri, February 19, 2010 9:40:22 AM Subject: Re: Traits library On Feb 19, 2010, at 9:28 AM, Brendan Eich wrote: Content authors will have to decide among the several solutions. The JS community should and no doubt will make translation tools available (even in-browser translators, where feasible). To make a more useful followup to my own message, I should note that the JS community already has made various translators available, notably * OpenLaszlo * 280N's Objective-J * Aza's pyscript (http://www.azarask.in/blog/post/making-javascript-syntax-not-suck/) * Neil Mix's Narrative JS * Alex Fritze's Stratified JS Some of these adhere to likely Harmony syntax more than others ;-). I'm sure I'm forgetting others. Anyone have a comprehensive list with links? /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: Traits library
Hi Tom The 'pattern' I'm describing has some similarities to multi-methods. An example is a drawing program. Depending on 'context' which includes the user agent, the type of drawing primitive and the type of drawing filter or effects you need to dynamically build an object which chooses vml, flash, svg or canvas. The drawing object is told to draw a circle with a linear gradient. As the designer you do not want to download implementations of vml, flash, svg and canvas. You also do not want to build a container object which has gratuitous if statements to do delegation or contains knowledge of all implementations. This would not scale given you would like the design to be extensible. For example next week you may want to add silverlight. You also would like to only download resources based things like user agent and version (vml for ie, svn and/or canvas for webkit, firefox, opera depending on the type of primitive and effect). Patterns like template-methods do not apply because each implementation may take different parameters in its methods and given a user agent/version you may want to do a drawCircle using a canvas on firefox but use svg on iphone and use flash on webkit. It doesn't sound like traits would enable this 'pattern' given different methods need to be mixed in with appropriate context from the implementation and all methods are final. Also it doesn't look like you could draw a circle and pass things like border, background in a closure rather than explicitly through parameters, although you allude to a way via the property descriptor. Passing attributes like background, border in the property descriptor would seem to be an abuse of the meta-data framework by passing data not meta-data. thx kam From: Tom Van Cutsem to...@google.com To: Kam Kasravi kamkasr...@yahoo.com Cc: es-discuss es-discuss@mozilla.org Sent: Tue, February 16, 2010 7:18:48 PM Subject: Re: Traits library Hi Kam, If I understand the implementation of traits, it provides a ES5 compatible way of composing 'final' properties to an existing object's prototype. Options provide the meta-data required to define the property descriptor such as required, etc. Do traits provide an ability to bind a 'context' to the property in the form of a closure so that the property may be provided with additional information? Effectively a way to curry or export additional information required by the trait when it is called in the context of the object it was added to. I'm not entirely sure I understand the question. Do you have a particular use case in mind or can you give an example to clarify things? As far as I can understand, if what you want is additional meta-data stored in property descriptors, this can be done by adding additional attributes to the descriptors. In effect, that's what the library already does for 'required' and 'conflicting' properties. Cheers, Tom thx kam From: Tom Van Cutsem to...@google.com To: es-discuss es-discuss@mozilla.org Sent: Tue, February 16, 2010 2:55:50 PM Subject: Traits library Hi, Mark Miller and I have been working on a small traits library for Javascript. It is documented here: http://code.google.com/p/es-lab/wiki/Traits Traits are reusable building blocks for classes, very similar to mixins, but with less gotchas. For example, traits support explicit conflict resolution upon name clashes and the order in which traits are composed is not significant. In a nutshell: - The library is designed for ES5, but backwards-compatible with existing ES3 implementations. - Our library represents traits as ES5 property maps (objects mapping property names to property descriptors). The library exports: - a convenient trait constructor to generate property maps from object literals. - a number of trait combinators to compose property maps. - a function that can instantiate such property maps into objects (analogous to the ES5 Object.create function, but with awareness about trait-specific property semantics). The interesting thing about our choice of transparently representing traits as ES5 property maps is that our library can be used as a general-purpose library for manipulating property descriptors in addition to its use as a library to compose and instantiate traits. A small expository example that uses the library: http://code.google.com/p/es-lab/source/browse/trunk/src/traits/examples.js Mark and I were both surprised at how well Javascript accommodates a trait library with very little boilerplate. However, there is one catch to implementing traits as a library. Traits, like classes, are normally simply declared in the program text, but need not necessarily have a runtime representation. Trait composition is normally performed entirely at compile-time (in trait lingo this is called flattening the traits). At runtime, no trace of trait composition is left
Re: Traits library
Hi Tom thanks for your excellent clarifications below. I agree traits is a way to compose different blocks from different 'classes' which would avoid the limitations of single-inheritance. One use case when using traits in this way is whether traits (either using Trait.create or Object.create) could be used to replace prototypical inheritance rather than classical inheritance. That is, can traits be used to compose different blocks from different instances rather than different classes. kam From: Tom Van Cutsem to...@google.com To: Kam Kasravi kamkasr...@yahoo.com Cc: es-discuss es-discuss@mozilla.org Sent: Wed, February 17, 2010 2:49:43 PM Subject: Re: Traits library Hi Kam, Thanks for the clarification. As far as I can tell, what you are describing is an example that would require trait composition to be postponed until runtime (as it depends on runtime context). The way I see it, the traits library would not prevent that: since traits are not static entities but just property maps that are manipulated at runtime, I see no fundamental obstacle to writing a generic dispatching function that, given some context, returns the appropriate traits or trait composition making up a drawing editor. However, I would like to point out that if this is your desired use case, then traits may not be the right building block. As you point out yourself, the example you're describing seems like a perfect match for multi-methods. I do not think that 'dynamic trait composition' is a good alternative for multi-methods. At least, that's not the use case for which traits have been designed. Traits are an alternative to composition by inheritance. As is the case in typical single/mixin/multiple-inheritance schemes, the relationship between the inheriting entities is usually known (and declared) statically and is immutable. I see traits more like a static building block that can be used to organize code (while enabling a higher reuse potential than that provided by classes+single-inheritance). Some details: It doesn't sound like traits would enable this 'pattern' given different methods need to be mixed in with appropriate context from the implementation and all methods are final. Methods are 'final' upon trait composition only when a property map is instantiated using Trait.create. If Object.create is used, the instantiated object is a plain Javascript object with all of the malleability this implies. Passing attributes like background, border in the property descriptor would seem to be an abuse of the meta-data framework by passing data not meta-data. I completely agree. When I proposed the use of attributes to store data in property descriptors in my earlier message, I thought you meant to store meta-data. Cheers, Tom thx kam From: Tom Van Cutsem to...@google.com To: Kam Kasravi kamkasr...@yahoo.com Cc: es-discuss es-discuss@mozilla.org Sent: Tue, February 16, 2010 7:18:48 PM Subject: Re: Traits library Hi Kam, If I understand the implementation of traits, it provides a ES5 compatible way of composing 'final' properties to an existing object's prototype. Options provide the meta-data required to define the property descriptor such as required, etc. Do traits provide an ability to bind a 'context' to the property in the form of a closure so that the property may be provided with additional information? Effectively a way to curry or export additional information required by the trait when it is called in the context of the object it was added to. I'm not entirely sure I understand the question. Do you have a particular use case in mind or can you give an example to clarify things? As far as I can understand, if what you want is additional meta-data stored in property descriptors, this can be done by adding additional attributes to the descriptors. In effect, that's what the library already does for 'required' and 'conflicting' properties. Cheers, Tom thx kam From: Tom Van Cutsem to...@google.com To: es-discuss es-discuss@mozilla.org Sent: Tue, February 16, 2010 2:55:50 PM Subject: Traits library Hi, Mark Miller and I have been working on a small traits library for Javascript. It is documented here: http://code.google.com/p/es-lab/wiki/Traits Traits are reusable building blocks for classes, very similar to mixins, but with less gotchas. For example, traits support explicit conflict resolution upon name clashes and the order in which traits are composed is not significant. In a nutshell: - The library is designed for ES5, but backwards-compatible with existing ES3 implementations. - Our library represents traits as ES5 property maps (objects mapping property names to property descriptors). The library exports: - a convenient trait constructor to generate property maps from object literals. - a number of trait combinators to compose
Re: Traits library
Thanks Tom. The traits concept resonates with something very similar I had prototyped which you briefly describe under 'Traits and Type Tests'. Specifically where you describe var o = Trait.create(proto, trait, { implements: [ brand1, brand2, ... ] }); The object literal I had used was { 'private': { ... }, 'constructor': function() { ... }, 'privileged': { ... }, 'public': { ... }, 'actions': { ... }, 'init': function() { ... } } By providing groupings in the form of a meta-model, type classification was greatly improved in the resulting object along with reflection capabilities and other advantages when a javascript meta-model is enabled. For example 'private' would mean closures, 'actions' would mean the methods would be automating bound to Function.bind. One thing I did which may be worth considering is to make the 'Trait' object extensible by allowing it to also be extended via composition. Although this is somewhat metacircular, it provides the ability to add new meta-data other than 'required' and have that meta-data handled within the extended Trait object. For example, if you wanted to indicate whether a property should be documented you could do something like { a: Trait.document } where you would expand Trait to handle this new meta-data by doing something like Trait.compose(Trait, {'document': function() { ... }}). Match a new meta-data property with a Trait method of the same name would be one possible way of making Trait extensible in similar ways as java annotations. Given your expertise in this area, would you view this meta-circular approach as a way to extend Trait into areas beyond composition where more semantic behavior could be injected given a new meta-data keyword? You may feel this distorts the simple semantics but I would be interested in hearing your views. thx kam From: Tom Van Cutsem to...@google.com To: Kam Kasravi kamkasr...@yahoo.com Cc: es-discuss es-discuss@mozilla.org Sent: Wed, February 17, 2010 6:19:12 PM Subject: Re: Traits library As a follow-up to my earlier reply to Kam, I included a diagram at http://code.google.com/p/es-lab/wiki/Traits#API that helps to clarify what kinds of objects and operations are involved in using the library. On Wed, Feb 17, 2010 at 4:54 PM, Tom Van Cutsem to...@google.com wrote: Hi Kam, One use case when using traits in this way is whether traits (either using Trait.create or Object.create) could be used to replace prototypical inheritance rather than classical inheritance. That is, can traits be used to compose different blocks from different instances rather than different classes. Yes, the traits library enables this, because it allows instances to be 'lifted' into traits. Just like the library provides two ways to generate an object from a property map (either use Object.create or Trait.create), the library provides two ways to generate a property map from an object: - either use the Trait constructor: Trait(object) - property-map - or use Object.getOwnProperties(object) - property-map I didn't mention this on the wiki page, but the traits.js library actually goes ahead and adds the missing 'getOwnProperties' utility method to Object if it doesn't already exist, precisely because it's so useful in combination with representing traits as property maps. getOwnProperties is a simple utility method based on ES5's getOwnPropertyNames + getOwnPropertyDescriptor built-in methods. Just like Trait.create is the trait-aware version of Object.create, the Trait constructor is the trait-aware version of Object.getOwnProperties. The Trait constructor will, for example, recognize properties bound to Trait.required, whereas Object.getOwnProperties will not. That said, I envisaged the Trait constructor to be used in the absolute majority of cases in conjunction with an in-line object literal, as in Trait({...}). Generally, I don't think it makes a lot of sense to turn an actual instance back into a trait (it's like turning an object into a class). But the library doesn't stop you from using Trait or Object.getOwnProperties on arbitrary instances if this is really what you want to do. Cheers, Tom kam From: Tom Van Cutsem to...@google.com To: Kam Kasravi kamkasr...@yahoo.com Cc: es-discuss es-discuss@mozilla.org Sent: Wed, February 17, 2010 2:49:43 PM Subject: Re: Traits library Hi Kam, Thanks for the clarification. As far as I can tell, what you are describing is an example that would require trait composition to be postponed until runtime (as it depends on runtime context). The way I see it, the traits library would not prevent that: since traits are not static entities but just property maps that are manipulated at runtime, I see no fundamental obstacle to writing a generic dispatching function that, given some context, returns the appropriate traits or trait composition making up a drawing editor
Re: Traits library
Hi Tom: If I understand the implementation of traits, it provides a ES5 compatible way of composing 'final' properties to an existing object's prototype. Options provide the meta-data required to define the property descriptor such as required, etc. Do traits provide an ability to bind a 'context' to the property in the form of a closure so that the property may be provided with additional information? Effectively a way to curry or export additional information required by the trait when it is called in the context of the object it was added to. thx kam From: Tom Van Cutsem to...@google.com To: es-discuss es-discuss@mozilla.org Sent: Tue, February 16, 2010 2:55:50 PM Subject: Traits library Hi, Mark Miller and I have been working on a small traits library for Javascript. It is documented here: http://code.google.com/p/es-lab/wiki/Traits Traits are reusable building blocks for classes, very similar to mixins, but with less gotchas. For example, traits support explicit conflict resolution upon name clashes and the order in which traits are composed is not significant. In a nutshell: - The library is designed for ES5, but backwards-compatible with existing ES3 implementations. - Our library represents traits as ES5 property maps (objects mapping property names to property descriptors). The library exports: - a convenient trait constructor to generate property maps from object literals. - a number of trait combinators to compose property maps. - a function that can instantiate such property maps into objects (analogous to the ES5 Object.create function, but with awareness about trait-specific property semantics). The interesting thing about our choice of transparently representing traits as ES5 property maps is that our library can be used as a general-purpose library for manipulating property descriptors in addition to its use as a library to compose and instantiate traits. A small expository example that uses the library: http://code.google.com/p/es-lab/source/browse/trunk/src/traits/examples.js Mark and I were both surprised at how well Javascript accommodates a trait library with very little boilerplate. However, there is one catch to implementing traits as a library. Traits, like classes, are normally simply declared in the program text, but need not necessarily have a runtime representation. Trait composition is normally performed entirely at compile-time (in trait lingo this is called flattening the traits). At runtime, no trace of trait composition is left. Because we use a library approach, traits are not declarative entities and must have a runtime representation. Thus, there is a runtime overhead associated with trait creation and composition. Moreover, because the implementation is oblivious to traits, multiple objects instantiated from the same trait declaration don't share structure. However, we did design the library such that, if traits are specified using object literals and property renaming depends only on string literals (which is the common case), a partial evaluator could in principle perform all trait composition statically, and replace calls to Trait.create with a specialized implementation that does support structural sharing between instances (just like an implementation that notices multiple calls to Object.create with the same property descriptor map can in principle arrange for the created objects to share structure). Any feedback on our design is welcomed. In particular, it'd be interesting to hear how hard/easy it would be for an implementation to recognize the operations performed by our library in order to perform them statically. Cheers, Tom___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: simple modules
I thought I would also mention that contexts (as in execution context), sandbox, security and other terms are also heavily used in html5. Defining a module framework without at least being familiar with current and upcoming browser environments may result in an implementation that is at odds with html5 entities which use similar terminology. For example, a SecureESContext would probably prevent cross-document messaging, channel messaging and other mechanisms that exist or are being defined in html5. Strictly speaking cross-document messaging violates TCB since existence of adjacent iframes and their source domains can be determined. Yes I'm not sure current module strawmen define a general mechanism where module-to-module communication can occur. Perhaps to complement the discussion, there is a variety of literature which describes modules in different ways. Given one goal of harmony is to make programming in the large easier, I would think a module framework's first goal is to make it easier to organize code. Some papers on modules with a few choice quotes. Functions, Frames and Interactions. Claus Reinke. 'A module is a ... collection ... of elements. It provides a separate namespace with explicit control of import/export.' Modular Object-Oriented Programming with Units and Mixins. Findler, Flatt 'A module delineates boundaries for separate development...' Metalevel Building Blocks for Modular Systems. Jagannathan 'allow ... module elaboration with minimal program rewriting...' The Influence of Software Module Systems on Modular Verification. Li, Fisler, Krishnamurthi. 'feature-oriented modules ... simplify key software engineering problems such as configurability, maintainability, and evolution.' kam From: Kris Kowal kris.ko...@cixar.com To: David Herman dher...@mozilla.com Cc: es-discuss Steen es-discuss@mozilla.org Sent: Tue, February 2, 2010 6:23:55 PM Subject: Re: simple modules On Tue, Feb 2, 2010 at 5:27 PM, David Herman dher...@mozilla.com wrote: On Feb 2, 2010, at 5:03 PM, Kris Kowal wrote: Presuming that in the proverbial glossary a Context is what ES presently calls an execution context that has some intrinsic Primordials, and a Sandbox is a mapping from unique module identifiers to modules (albeit instances or makers depending on what proposal you're talking about), does this proposal suggest that there is exactly one Context for every Sandbox and that any module block statement evaluated in a context populates the corresponding sandbox with a mapping from the given module identifier to the first class exports object of that module? Not quite sure how to unpack the question. Let me try a quick sketch, at least for the simple modules system: - a module ID resolver is a mapping from module ID's to module instances - a module context is a set of module instances Please call this something else. It is confusing for context to mean execution context and module context depending on the context. I've called this a system of modules or sandbox of modules in the past. Different module contexts may have different module ID resolvers, so for example it would be possible for host environments to provide a SecureESContext that didn't allow identifiers to resolve to the filesystem module or the dom module. This verbiage implies black-listing. It would be good to be clear that the object formerly known as a module context should be explicitly populated with a white-list of module instances for SES. There would be an API for dynamically evaluating code in a given context; roughly a `loadModule' that takes a Context argument (or is a method of Context). Tell me more about this loadModule and how it works. I am concerned that modules would be autonomous; I firmly believe that a chunk of code should never select its own name, or more to the point, it should never be necessary to edit code to give a module, or a tree of modules, an alternate name. That kind of coupling has wasted many days of my time, integrating disparate projects with tight linkage. Kris Kowal P.S., for some liesure reading, here is the Narwhal CommonJS module context implementation: http://github.com/280north/narwhal/blob/master/lib/sandbox.js http://github.com/280north/narwhal/blob/master/lib/loader.js ___ 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: simple modules: module managment vs. configuration management
Allen: I agree with the assessment of entangling configuration management and module management. Both module specifications have this issue, although Ihab's package proposal attempts to separate the two. In the community, the commonjs syntax is 'require(./compiler/Lexer);' which implicitly says to go get the script at relative location ./compiler/Lexer.js, where a '.js' is appended to the literal string. This is an implicit rule which inherently ties configuration management with module management. BTW, string literal's (which are in both module specifications) doesn't work well with combo handlers used by Yahoo and others where a 'module' (defined to be a collection of script files) is fetched using the URL 'http://yui.yahooapis.com/combo?version/resource1.jsversion/resource2.jsversion/resource3.js' The implicit rule would be to add '.js' to the above que An approach taken by commonjs when specifying a string literal eg: require('import/Lexer') is to have a 'paths' property on the require function like require.paths=[url1,url2,url3]; which resembles java's class path mechanism where first found is first loaded. Of course this assumes that the relative path is constant among the different path entries. An approach I had taken was to separate loading resources completely. I use client-side websockets which communicate using a derived MessageEvent that specifies resources by name, mimetype, if-modified-since or etag. This is a 'pull' mechanism where the client asks for resources which are then used to create modules. These derived MessageTypes would need to be specified at the WebIDL (W3C) level and used by a module loader. Delegating resource acquisition to an implementation of the loader does decouple module management from configuration management, there should be MessageEvent's or JSON structures that module management can use when evaluating resources fetched by the configuration management system. This would be a great example of specifying the ecmascript mapping from WebIDL. kam From: Allen Wirfs-Brock allen.wirfs-br...@microsoft.com To: es-discuss@mozilla.org es-discuss@mozilla.org Sent: Sat, January 30, 2010 11:43:39 AM Subject: simple modules: module managment vs. configuration management There is quite a bit of literature on “2nd class” module systems, but most of it is from a period before first class modules became the primary modularity research interest. I’ll see if I can dig up some references to papers that may be helpful. One of the points that I recall is the importance of not entangling “module management” with “configuration management”. In this context, “module management” means structuring the source code of a program into independent explicitly coupled pieces. This is done to manage complexity, allow parallel or independent development, simplify maintenance, etc. “Configuration management” means controlling and structuring the assembly instructions that describe how an actual runable program is instantiated as a composition of specific module instances. Configuration management is about selecting which specific module versions from various possible alternatives and sources get bound together for execution. As a more concrete example, a “program” might be logically composed of 4 modules with import/export based dependencies: module Main { …}; module Subsys { …}; module DB { …}; module yui3 {…}; To actually run this program you have to identify specific versions of containers that contain the modules definitions (eg, which specific files to load, which versions to load from a repository, which server to load from, etc.). How configurations are specified is usually quite specific to the actual mechanism used construct/instantiate executable programs. It might be a makefile, or a manifest, or some other declarative or imperative description. On the web, it might simply be the set of script tags in a HTML document: script type='text/javascript” src='/myapp/main/version2.js' script type='text/javascript” src='/myapp/subsys/version1.js' script type=”text/javascript” src='/library/DB-2010.js' script type=”text/javascript” src='http://developer.yahoo.com/modules/yui3.js' Module management becomes entangled with configuration management when configuration management information is embedded within the actual module definitions. When this occurs, configuration changes require the modification of the actual source code of modules. For example, if a module import statement uses a hard-code file path or server name then moving the location of an imported module requires modification of every module that performs such an import. The simple module proposal has a couple places where this sort of entanglement is possible. For example, from the samples: import 'http://json.org/modules/json2.js' as JSON; import 'http://developer.yahoo.com/modules/yui3.js#dom' as dom; import “compiler/Lexer”;
Re: Native modules
I had approached this concept in a slightly different way where resources required were specified using a derived MessageEvent type. There is precedence in building from the event system since its the only place I'm aware of where distributed semantics are being formally broached -eg postMessage, MessageChannels, etc. So motivations could be: 1) Already a rich hierarchy of DOM events 2) MessageEvent, postMessage, onMessage has good support across browsers 3) Security is factored into postMessage with remote or cross-document messaging. 4) MessagePorts are queued, providing well-defined dependency ordering I had also used WebSockets (supported in Chrome and Webkit). Also supported in Jetty and a few other servers.WebSockets can be emulated in other browsers via flash. Although this is delving too deep into implementation details, describing resources required within a derived MessageEvent like ResourcesRequest and ResourcesResponse with the ability to send related info per request like if-modified-since would allow a server to respond with a ResourcesResponse that included aggregated content (images,css,js) specified in the ResourcesRequest. Done over a websocket, it would satisfy Ihab's suggestion to do this over a devoted bidirectional channel which is the WebSockets protocol. Performance characteristics especially if you use the gmail technique of delaying eval of javascript sources until needed were very convincing.Is this forum appropriate for discussion of eventing, WebIDL, etc? I'm not sure, though I imagine this committee has spent uncountable hours discussing events related to the DOM etc. kam From: ihab.a...@gmail.com ihab.a...@gmail.com To: Kevin Curtis kevinc1...@googlemail.com Cc: es-discuss@mozilla.org Sent: Tue, January 19, 2010 11:46:56 AM Subject: Re: Native modules On Tue, Jan 19, 2010 at 11:26 AM, Kevin Curtis kevinc1...@googlemail.com wrote: Could a ECMAScript module proposal cover 'native modules' - which are built into the platform (ECMAScript engine and browser) - and can be imported if required and are not a binding on the global object. Could be useful for vendor specific innovation. From where I sit, it seems you are asking, not for native modules, but native services. A module, according to the proposals currently on the table, is simply a piece of code with no powers to affect the outside world. All powers it gets are through values passed to it by its creator (whether explicitly, in modules_emaker_style, or implicitly within a sandbox, in the require case of modules_primordials). Are you really asking for a service registry? Ihab -- Ihab A.B. Awad, Palo Alto, CA ___ 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: Native modules
I do think we could use some suggestions from the committee on how resources could be fetched ahead of import. Given the myriad of ways that exist now to get resources - mostly based on script injection or xhr, I think its going to be difficult to define a common service registry to fetch resources and eval them. kam From: ihab.a...@gmail.com ihab.a...@gmail.com To: Mark S. Miller erig...@google.com Cc: es-discuss@mozilla.org Sent: Wed, January 20, 2010 1:09:00 PM Subject: Re: Native modules On Wed, Jan 20, 2010 at 8:25 AM, Mark S. Miller erig...@google.com wrote: In these terms, for my previous example ... EphemeronTable and Proxy would be native modules. By the same token, perhaps something like http://code.google.com/p/nativeclient/ modules could be loaded via the module system too. Ihab -- Ihab A.B. Awad, Palo Alto, CA ___ 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: Isolated worlds (was Re: Module isolation) (Adam Barth)
This reminds me of ometa's implementation of worlds which provides isolation. http://www.vpri.org/pdf/rn2008001_worlds.pdf From: es-discuss-requ...@mozilla.org es-discuss-requ...@mozilla.org To: es-discuss@mozilla.org Sent: Tue, January 12, 2010 12:00:01 PM Subject: es-discuss Digest, Vol 35, Issue 9 Note: Forwarded message is attached. Send es-discuss mailing list submissions to es-discuss@mozilla.org To subscribe or unsubscribe via the World Wide Web, visit https://mail.mozilla.org/listinfo/es-discuss or, via email, send a message with subject or body 'help' to es-discuss-requ...@mozilla.org You can reach the person managing the list at es-discuss-ow...@mozilla.org When replying, please edit your Subject line so it is more specific than Re: Contents of es-discuss digest... Today's Topics: 1. Re: Isolated worlds (was Re: Module isolation) (Adam Barth) ___ 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: Module system strawpersons
Understood, yes I'm familiar with Neil Mix's NarrativeJS. Sorry for the misinterpretation of your comments as well as the import strawman. Lazily fetching imports in this way could force preemption in many places. Were there any es4 strawman's that suggested a similar deviation from the run-to-completion model? Kam From: Brendan Eich bren...@mozilla.com To: Kam Kasravi kamkasr...@yahoo.com Cc: ihab.a...@gmail.com ihab.a...@gmail.com; Oliver Hunt oli...@apple.com; kkasravi kkasr...@me.com; es-discuss es-discuss@mozilla.org Sent: Mon, January 18, 2010 8:40:15 PM Subject: Re: Module system strawpersons On Jan 18, 2010, at 6:14 PM, Kam Kasravi wrote: I guess Brendan is saying that if a continuation was natively built ar the '.' then the risk is that not acquiring the resource would result in a zombie. But if the runtime could build a continuation at the '.' then it could come back to it when the resource was acquired. Brendan is that layman's description or did I get it wrong? That's not wrong, but it does not consider the preemption point. Scripts in browsers today (event handler or timeout functions, same deal) run to completion. They do not race or nest event loops (bugs notwithstanding). So you can be sure a global variable you've just set to 42 will still be 42 after a call to a function. We could break this model at the . whose left-hand side was (import M) but should we? Neil Mix's NarrativeJS used - instead, to signify the difference. I do not propose we break the run-to-completion model implicitly, or add explicit syntax for doing so. At least not without a lot more discussion. /be Kam On Jan 18, 2010, at 5:52 PM, ihab.a...@gmail.com wrote: On Mon, Jan 18, 2010 at 5:43 PM, Oliver Hunt oli...@apple.com wrote: It's also horrific in the context of a browser as it's effectively an arbitrary length call blocked on IO. That's a good description of what I was proposing. Yes it would block the event loop. Perhaps it could be useful if (say) the module were available in a local disk cache but not loaded into memory: the cost of I/O to a disk cache may be reasonable, but not the cost of a completely new fetch from the network. Ihab --Ihab A.B. Awad, Palo Alto, CA ___ 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: Module system strawpersons
Yes, that looks right, I also remember a reference to the 'dot' notation where namespace access would be arbitrated implicitly by objects representing the '.' It may have been in one of Lars Hansen papers on gradual typing. In any case there was some good discussion on meta-level objects and controlling capabilities or access. Was there any discussion in the past about parameterized modules or units where recursively nested modules/units were brought up? If two modules refer to each other and all imports are resolved eagerly then I think this would be a problem where use cases would abound. thx Kam From: Brendan Eich bren...@mozilla.com To: Kam Kasravi kamkasr...@yahoo.com Cc: mikesam...@gmail.com; kkasravi kkasr...@me.com; es-discuss es-discuss@mozilla.org Sent: Mon, January 18, 2010 12:23:46 AM Subject: Re: Module system strawpersons On Jan 15, 2010, at 1:32 PM, Kam Kasravi wrote: Brendan, do you recall es4 where the concept of a unit was introduced? There was also some discussion where management and security where implicitly mapped to the '.' between identifier parts. I cannot find that reference. Was it this? http://wiki.ecmascript.org/doku.php?id=proposals:program_units /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Module system strawpersons
Andy yes I was referring to the circular dependency issue. Catch-alls would be useful for this, though it would be nice if they were automated, eg returning a proxy until the module was used. Doing it manually by developer would be too difficult. I realize modules are intended to just satisfy a function body and can be initialized as objects or called as functions, but since they have strong container semantics I wonder if they should have more than just an 'id' especially if they provide a gateway to what else is in the directory as in commonjs. Kam From: Andy Chu a...@chubot.org To: Kam Kasravi kamkasr...@yahoo.com Cc: Brendan Eich bren...@mozilla.com; kkasravi kkasr...@me.com; es-discuss es-discuss@mozilla.org Sent: Mon, January 18, 2010 12:40:35 PM Subject: Re: Module system strawpersons On Mon, Jan 18, 2010 at 10:29 AM, Kam Kasravi kamkasr...@yahoo.com wrote: Yes, that looks right, I also remember a reference to the 'dot' notation where namespace access would be arbitrated implicitly by objects representing the '.' It may have been in one of Lars Hansen papers on gradual typing. In any case there was some good discussion on meta-level objects and controlling capabilities or access. Was there any discussion in the past about parameterized modules or units where recursively nested modules/units were brought up? If two modules refer to each other and all imports are resolved eagerly then I think this would be a problem where use cases would abound. What are you referring to here? I think you are hinting at the problem of circular dependencies using import semantics like Python and CommonJS. Right now if you have mutually recursive modules, you get partially initialized modules, because the program counter just follows every require(). The CommonJS spec specifically allows the partially initialized modules I think. Personally I try to break up circular dependencies, but this behavior is not very friendly, so I think it would be better if Harmony supported circular dependencies in a more correct way. So this is an advantage of the makers style semantics (separating module definition and configuration). The Newspeak paper talks explicitly about this: http://scholar.google.com/scholar?hl=ensource=hpq=objects%20as%20modules%20in%20newspeakum=1ie=UTF-8sa=Ntab=ws If you are initializing modules in topological order, and there is a circular dependency between A and B, he says to just make a dummy proxy object for B to pass into A, initialize A, and then initialize B. That also reminds me that a good use case for catchalls is making module-like objects. I haven't seen any discussions of the 2 together but it's definitely worth thinking about how they interact. Andy ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Module system strawpersons
Ok, cool! So the import framework could go about fetching A then B or B then A for any 3rd object that was going to use them. I know that YUI 3 does this type of loadiong explicitly, in this case would the import framework would take care of it or would there still need to be something the developer would do to get A and B early? I wasn't sure going thru the 'pim' function in Ihab's strawman where it was finding the dependencies or was getting help from the js runtime or something. thx Kam From: Mike Samuel mikesam...@gmail.com To: Kam Kasravi kamkasr...@yahoo.com Cc: Andy Chu a...@chubot.org; kkasravi kkasr...@me.com; Brendan Eich bren...@mozilla.com; es-discuss es-discuss@mozilla.org Sent: Mon, January 18, 2010 2:44:48 PM Subject: Re: Module system strawpersons 2010/1/18 Kam Kasravi kamkasr...@yahoo.com: Hi Mike The former but not in the way you've described. Rather module A: this.getB= function() { return new (import 'B')(); } module B: this.getA = function() { return new (import 'A')(); } If modules eagerly resolve imports then the above circular dependency would be a problem. If modules lazily resolve imports then the above circular dependency would be ok. If catch-alls were used then proxy's would be used and the circular dependency would be ok. Current js has many examples of circular dependencies which are resolved by lazy evaluation. Ok. Ihab's proposal allows eager fetching, and mandates lazy instantiation, so the above example is not a problem with Ihab's proposal. Kam From: Mike Samuel mikesam...@gmail.com To: Kam Kasravi kamkasr...@yahoo.com Cc: Andy Chu a...@chubot.org; kkasravi kkasr...@me.com; Brendan Eich bren...@mozilla.com; es-discuss es-discuss@mozilla.org Sent: Mon, January 18, 2010 1:50:15 PM Subject: Re: Module system strawpersons I don't quite understand what is meant by circular dependencies in this context. Are you talking about the graph of imports, or the graph of module instances? If the former, how is it a problem? If the latter, how could it occur without explicit user intent : a module explicitly passing itself to a dependency? E.g. in the former // fib.js var self = (import fib.js); if (n 2) { return n; } return self({ n: n - 2 }) + self({ n : n - 1 }); a module imports itself, and recursively invokes separate instances which is stupid but does not result in a module being observed in a partially initialized state. In the latter: // foo.js var otherModuleMaker = (import bar.js)({ baz: this }); module foo is explicitly allowing otherModuleMaker to observe it in an uninitialized state. 2010/1/18 Kam Kasravi kamkasr...@yahoo.com: Andy yes I was referring to the circular dependency issue. Catch-alls would be useful for this, though it would be nice if they were automated, eg returning a proxy until the module was used. Doing it manually by developer would be too difficult. I realize modules are intended to just satisfy a function body and can be initialized as objects or called as functions, but since they have strong container semantics I wonder if they should have more than just an 'id' especially if they provide a gateway to what else is in the directory as in commonjs. Kam From: Andy Chu a...@chubot.org To: Kam Kasravi kamkasr...@yahoo.com Cc: Brendan Eich bren...@mozilla.com; kkasravi kkasr...@me.com; es-discuss es-discuss@mozilla.org Sent: Mon, January 18, 2010 12:40:35 PM Subject: Re: Module system strawpersons On Mon, Jan 18, 2010 at 10:29 AM, Kam Kasravi kamkasr...@yahoo.com wrote: Yes, that looks right, I also remember a reference to the 'dot' notation where namespace access would be arbitrated implicitly by objects representing the '.' It may have been in one of Lars Hansen papers on gradual typing. In any case there was some good discussion on meta-level objects and controlling capabilities or access. Was there any discussion in the past about parameterized modules or units where recursively nested modules/units were brought up? If two modules refer to each other and all imports are resolved eagerly then I think this would be a problem where use cases would abound. What are you referring to here? I think you are hinting at the problem of circular dependencies using import semantics like Python and CommonJS. Right now if you have mutually recursive modules, you get partially initialized modules, because the program counter just follows every require(). The CommonJS spec specifically allows the partially initialized modules I think. Personally I try to break up circular dependencies, but this behavior is not very friendly, so I think it would be better if Harmony supported circular dependencies in a more correct way. So this is an advantage of the makers style semantics (separating module definition and configuration
Re: Module system strawpersons
I guess Brendan is saying that if a continuation was natively built ar the '.' then the risk is that not acquiring the resource would result in a zombie. But if the runtime could build a continuation at the '.' then it could come back to it when the resource was acquired. Brendan is that layman's description or did I get it wrong? Kam On Jan 18, 2010, at 5:52 PM, ihab.a...@gmail.com wrote: On Mon, Jan 18, 2010 at 5:43 PM, Oliver Hunt oli...@apple.com wrote: It's also horrific in the context of a browser as it's effectively an arbitrary length call blocked on IO. That's a good description of what I was proposing. Yes it would block the event loop. Perhaps it could be useful if (say) the module were available in a local disk cache but not loaded into memory: the cost of I/O to a disk cache may be reasonable, but not the cost of a completely new fetch from the network. Ihab -- Ihab A.B. Awad, Palo Alto, CA ___ 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: Module system strawpersons
Within that body of literature there is one called Higher Order Functors which describes in this context modules being initialized with modules all of them parameritized. It looks like this is possible and powerful. Kam On Jan 16, 2010, at 11:47 AM, Andy Chu a...@chubot.org wrote: On Thu, Jan 14, 2010 at 1:58 PM, ihab.a...@gmail.com wrote: Hi Mike, On Thu, Jan 14, 2010 at 1:29 PM, Mike Samuel mikesam...@gmail.com wrote: Are these proposals mutually exclusive or complementary. If (1) and (2) are exclusive, is there a place to collect use cases for a module-off? For my part, I think (1) and (2) are counterproposals, but there may exist a bunch of cross-pollination. For example, I will probably end up stealing Kris's import with syntax sometime. Are they really? The primitive proposal says: This proposal specifies support for both “loading” dependencies as module factory functions (Makers) ... I can see how the Makers will work, but I think to convince ourselves, it would be good to provide example #4 of implementing Makers on top of Context() (proposal 2 on top of proposal 1). I like the approach of providing a primitive Context() and then being able to implement Makers-style modules in those semantics (i.e. with pure JS code). For makers, what you're essentially proposing is parameterized modules, no? The modules are parameterized by their dependencies. That is something I strongly support, but is unusual compared say Python or Ruby's module systems. In those systems, dependencies are essentially hard-coded. I think making this clear in the proposals is useful. Most of these papers are about this distinction (especially the Newspeak papers, and the Scala one): http://lambda-the-ultimate.org/node/3735 The way I think of it is that there are bound and unbound modules -- you bind the dependencies (requires) of the Module by calling its module function with concrete dependencies. I've been working on some code which does allows this extra degree of flexibility for CommonJS modules: http://code.google.com/p/gelatin-js/ (needs docs, coming shortly) Basically you say require('file') in the source code. And then at build time, bind 2 different implementations to that requirement, depending on where you want to deploy. You can think of this as module metaprogramming at build time, whereas the makers proposal is module metaprogramming at runtime, in JavaScript. In one of the Newspeak papers he talks about not conflating module definition and module configuration (e.g. which Python/Ruby/Perl do). I agree with this -- there is one mechanism to define modules, and then you can configure the modules at build time or runtime. JavaScript especially needs this feature because there are so many different execution environments, and no standard library (yet). So I really like the general ideas of these 2 proposals, but some of the details are unclear. I think relating things to CommonJS modules is good because they are already implemented quite widely. thanks, Andy ___ 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: Module system strawpersons
comments below... From: Mike Samuel mikesam...@gmail.com To: Kam Kasravi kamkasr...@yahoo.com Cc: kkasravi kkasr...@me.com; es-discuss es-discuss@mozilla.org Sent: Fri, January 15, 2010 1:45:52 PM Subject: Re: Module system strawpersons 2010/1/15 Kam Kasravi kamkasr...@yahoo.com: Ihab, Mike - Thanks for the comments. Yes, my examples confused definition with declaration, thanks for the corrections. I think I still have some unanswered questions which I'll try and clarify as: 1. I'm still not clear what the module identifier represents. Something like 'a/b/c' could be a URI or associated with a URI. Commonjs implicitly adds a '.js' which suggests this maps to a REST construct. I think it would be helpful to clarify the above literal, the module.id, any relation to javascript namespace and a mapping to server resources since there is such an overlap with package management. 2. If the eagerness of the interpreter is determined by its implementation we could have lots of indeterminism across interpreters. There should Which sources of indeterminism do you foresee? Is this indeterminism as apparent to a network observer or as apparent to code running in the same interpreter? [Kam] the network observer. A given interpreter may end up making lots of fetches or a few depending when it decided to resolve the import's. probably be another construct that defines when resources are fetched. I'm not sure if the interpreter shouldn't be influenced by the developer. Could you rephrase this last sentence, please? [Kam] as an example. lets say a module contains 3 adapters: one that uses jQuery, one that uses Ext and one that uses YUI. A eager interpreter may fetch all three when evaluating the module. Yet if the choice of what framework to use (jQuery, Ext or YUI) was determined by the developer/user early on, then the interpreter would fetch 2 frameworks without needing to. If the developer had a way to indicating to the interpreter that 2 of the frameworks weren't needed then the behavior of the interpreter would be predictable. Brendan, do you recall es4 where the concept of a unit was introduced? There was also some discussion where management and security where implicitly mapped to the '.' between identifier parts. I cannot find that reference. Kam From: Mike Samuel mikesam...@gmail.com To: kkasravi kkasr...@me.com Cc: es-discuss es-discuss@mozilla.org Sent: Fri, January 15, 2010 11:20:48 AM Subject: Re: Module system strawpersons 2010/1/15 kkasravi kkasr...@me.com: Hi Mike, Ihab: One factor that would influence eager or lazy fetching is where the import keyword may appear within the ecmascript grammar. The proposal suggests it could appear anywhere an identifier could appear. For example: I believe it cannot appear where a LeftHandSideExpression is expected because a function cannot be assigned to. So no replacing foo.bar = baz with (import ...) = baz 1) function find(name) { var name = foo.bar.Baz.find(name); // identifier 'foo.bar.Baz' ... } Replacing foo.bar with import would yield 2) function find(name) { var name = (import 'foo/bar').Baz.find(name); Provisioning is separate from importing. The above is looking up Baz on a function instance which normally would be the same as var name = Function.prototype.Baz.find(name) I think normal usage would look like var name = (import ...)(module, instance, parameters).Baz.find(name) ... } Replacing foo.bar.Baz with import would yield 3) function find(name) { var name = (import 'foo/bar/Baz').find(name); ... } I provided 2) and 3) because its not clear where a module definition begins. The presumption by naming convention is that foo.bar.Baz can be found within a relative resource named ./foo/bar.js on some server. This metadata needs to be somehow made available to the javascript runtime. So in some ways module's need package info. Let's assume the correct one is 2). Looking at 2), current javascript behavior is always lazy fetching because the above function find fetching can be eager, but evaluation happens whenever the ImportExpr is reached, possibly not at all. may not be called immediately or not at all. The javascript runtime would not complain about identifiers that are not immediately accessed or not accessed at all. Doing eager fetching means that we would need to fetch all imports prior to eval. Impacts are: 1. We fetch more than necessary and immediately. User perception is the new js runtime is much slower. Eager fetching can be done, or can be delayed, or multiple module definitions could be fetched in the same transaction. The degree of eagerness is up to the interpreter. 2. We forces all import expressions to be statically defined. Summary: If import can appear in place