Re: use strict; prepended blindly to scripts in the wild
On Tue, Sep 7, 2010 at 9:35 PM, Brendan Eich bren...@mozilla.com wrote: On Sep 7, 2010, at 10:28 AM, Boris Zbarsky wrote: On 9/7/10 1:21 PM, Brendan Eich wrote: See, e.g., https://bugzilla.mozilla.org/show_bug.cgi?id=593963 -- but this is not the first instance. Previously: https://bugzilla.mozilla.org/show_bug.cgi?id=579119. The latter wasn't blind. It was just a site concatenating a bunch of third-party scripts together, and one of the third-party scripts (correctly) using strict So that one is totally Amazon's flub, imo. Thanks -- this clarifies things, and makes me worry about more of the same. Blind concatenation is a feature as much as a bug in the history of JS. Combined with script inline content moving out to src= URL-named convent, it is how we end up with Unicode BOMs and !-- pseudo-comments in the middle of files. Currently, a site may normally concatenate 3rd-party libs with use strict at the global level. The technique is the same as with forgotten semicolon -- just to put an empty statement at the beginning of the end file. Thus the site's combined file won't be globally strict, however since a lib is tested before a production release (at least I hope so ;), then the lib's code should pass the strictness, and therefore, a use strict may be even removed from the lib's file. However, if not to remove, then an empty statement is enough. ;/*1st lib*/use strict;eval = 10;/*2st lib*/use strict;arguments=20;/*our code*/ Dmitry. /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: Classes as Sugar is now ready for discussion
There's no mistake that dedicated syntax for traits would help users and implementors alike. However, while I (or others) could definitely come up with a 'traits-as-sugar', or even a 'traits-as-a-new-value' proposal, that still wouldn't solve the version evolution problem associated with trait composition (or any other traditional inheritance mechanism). As long as this remains a deal-breaker, I don't think it's worth looking into alternative traits proposals. As Dave said, traits.js is out there for people to experiment with. Any feedback on usability issues of the design in its current form are highly appreciated. 2010/9/9 David Herman dher...@mozilla.com Agreed; perhaps my question was not clear. If there was a Traits-like proposal that did include new syntax, would you be against it because you can implement something similar as a library without needing new semantics, or would you be more inclined to reserve judgement until you could actually review a proposal and see what the proposed benefits were? The latter (speaking for myself, of course). 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: Classes as Sugar is now ready for discussion
On 2010-09-09, at 06:13, Tom Van Cutsem wrote: There's no mistake that dedicated syntax for traits would help users and implementors alike. However, while I (or others) could definitely come up with a 'traits-as-sugar', or even a 'traits-as-a-new-value' proposal, that still wouldn't solve the version evolution problem associated with trait composition (or any other traditional inheritance mechanism). As long as this remains a deal-breaker, I don't think it's worth looking into alternative traits proposals. As Dave said, traits.js is out there for people to experiment with. Any feedback on usability issues of the design in its current form are highly appreciated. I have on my to-do list to try re-casting the OpenLaszlo class framework as traits. Of the proposals for better class support in harmony, traits seems the most feasible to me for my work (we already translate to Ecmascript 3 and Actionscript 3). Clearly, I've got to actually implement it to test that theory. I certainly don't know any solution to the version evolution problem. AFAIK, it's why no one uses DLL's any more (or if they do, each app ships with its own private copy of every DLL it depends on). It's great that we can experiment with Traits without standardizing. It would be a shame to end up standardizing on an inferior proposal because of that feature of Traits. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: use strict; prepended blindly to scripts in the wild
On Sep 9, 2010, at 1:09 AM, Dmitry Soshnikov wrote: Thus the site's combined file won't be globally strict, however since a lib is tested before a production release (at least I hope so ;), then the lib's code should pass the strictness, and therefore, a use strict may be even removed from the lib's file. However, if not to remove, then an empty statement is enough. That does not disable strict mode. The problem at real sites including an intel.com property is that subsequent parts of the concatenation have had strict mode errors. ;/*1st lib*/use strict;eval = 10;/*2st lib*/use strict;arguments=20;/*our code*/ An example showing the problem would need a use nonstrict; directive after the first part of the concatenation, but there is no such directive. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: use strict; prepended blindly to scripts in the wild
On Thu, Sep 9, 2010 at 10:32 AM, Brendan Eich bren...@mozilla.com wrote: On Sep 9, 2010, at 1:09 AM, Dmitry Soshnikov wrote: Thus the site's combined file won't be globally strict, however since a lib is tested before a production release (at least I hope so ;), then the lib's code should pass the strictness, and therefore, a use strict may be even removed from the lib's file. However, if not to remove, then an empty statement is enough. That does not disable strict mode. The problem at real sites including an intel.com property is that subsequent parts of the concatenation have had strict mode errors. ;/*1st lib*/use strict;eval = 10;/*2st lib*/use strict;arguments=20;/*our code*/ An example showing the problem would need a use nonstrict; directive after the first part of the concatenation, but there is no such directive. I recall reading that the use strict; directive was block-scoped. Is this true? If so, there's no need for function wrappers -- putting each script in its own block is easy and should have no ill effects on concatenation, right? ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: use strict; prepended blindly to scripts in the wild
On Sep 9, 2010, at 8:46 AM, Dean Landolt wrote: On Thu, Sep 9, 2010 at 10:32 AM, Brendan Eich bren...@mozilla.com wrote: On Sep 9, 2010, at 1:09 AM, Dmitry Soshnikov wrote: Thus the site's combined file won't be globally strict, however since a lib is tested before a production release (at least I hope so ;), then the lib's code should pass the strictness, and therefore, a use strict may be even removed from the lib's file. However, if not to remove, then an empty statement is enough. That does not disable strict mode. The problem at real sites including an intel.com property is that subsequent parts of the concatenation have had strict mode errors. ;/*1st lib*/use strict;eval = 10;/*2st lib*/use strict;arguments=20;/*our code*/ An example showing the problem would need a use nonstrict; directive after the first part of the concatenation, but there is no such directive. I recall reading that the use strict; directive was block-scoped. Is this true? If so, there's no need for function wrappers -- putting each script in its own block is easy and should have no ill effects on concatenation, right? No, the use strict; directive is meaningful only at top of program and function bodies. See ES5 14.1: 14.1 Directive Prologues and the Use Strict Directive A Directive Prologue is the longest sequence of ExpressionStatement productions occurring as the initial SourceElement productions of a Program or FunctionBody and where each ExpressionStatement in the sequence consists entirely of a StringLiteral token followed a semicolon. The semicolon may appear explicitly or may be inserted by automatic semicolon insertion. A Directive Prologue may be an empty sequence. You may be thinking of ES4-era unquoted use strict; pragma syntax, which was block scoped. In Harmony, use ...; should be a block-scoped pragma -- real syntax, no quotes. /be___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: use strict; prepended blindly to scripts in the wild
On Thu, Sep 9, 2010 at 1:09 AM, Dmitry Soshnikov dmitry.soshni...@gmail.com wrote: Currently, a site may normally concatenate 3rd-party libs with use strict at the global level. The technique is the same as with forgotten semicolon -- just to put an empty statement at the beginning of the end file. Thus the site's combined file won't be globally strict, however since a lib is tested before a production release (at least I hope so ;), then the lib's code should pass the strictness, and therefore, a use strict may be even removed from the lib's file. However, if not to remove, then an empty statement is enough. Unfortunately for this eminently reasonable (IMO) assumption, removing use strict can change the behaviour of a program, even beyond cases that would have thrown an error. For example, the type and value of |this| can be different, for cases where methods are called on primitives. I don't know if other languages with optional strictures share this property, but I suspect that a lot of people are going to stub their toe on ES5's use of use strict as cover for incompatible changes rather than strictly subsetting legal programs and behaviours. :-/ Mike ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: use strict; prepended blindly to scripts in the wild
2010/9/9 Dmitry Soshnikov dmitry.soshni...@gmail.com: On Tue, Sep 7, 2010 at 9:35 PM, Brendan Eich bren...@mozilla.com wrote: On Sep 7, 2010, at 10:28 AM, Boris Zbarsky wrote: On 9/7/10 1:21 PM, Brendan Eich wrote: See, e.g., https://bugzilla.mozilla.org/show_bug.cgi?id=593963 -- but this is not the first instance. Previously: https://bugzilla.mozilla.org/show_bug.cgi?id=579119. The latter wasn't blind. It was just a site concatenating a bunch of third-party scripts together, and one of the third-party scripts (correctly) using strict So that one is totally Amazon's flub, imo. Thanks -- this clarifies things, and makes me worry about more of the same. Blind concatenation is a feature as much as a bug in the history of JS. Combined with script inline content moving out to src= URL-named convent, it is how we end up with Unicode BOMs and !-- pseudo-comments in the middle of files. Currently, a site may normally concatenate 3rd-party libs with use strict at the global level. The technique is the same as with forgotten semicolon -- just to put an empty statement at the beginning of the end file. A forgotten semicolon at the end of the first concatenated file can be a problem though. Consider the concatenation of (function () { foo(); })() and (function () { bar() })() Independently loaded, you get a call to foo and a call to bar. Concatenated, you get a call to foo and a TypeError complaining that undefined is not a function. So in both cases naive concatenation introduces subtle bugs by changing the meaning of the first or lass statement in a compilation unit. Thus the site's combined file won't be globally strict, however since a lib is tested before a production release (at least I hope so ;), then the lib's code should pass the strictness, and therefore, a use strict may be even removed from the lib's file. However, if not to remove, then an empty statement is enough. ;/*1st lib*/use strict;eval = 10;/*2st lib*/use strict;arguments=20;/*our code*/ Dmitry. /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: use strict; prepended blindly to scripts in the wild
On Thu, Sep 9, 2010 at 6:32 PM, Brendan Eich bren...@mozilla.com wrote: On Sep 9, 2010, at 1:09 AM, Dmitry Soshnikov wrote: Thus the site's combined file won't be globally strict, however since a lib is tested before a production release (at least I hope so ;), then the lib's code should pass the strictness, and therefore, a use strict may be even removed from the lib's file. However, if not to remove, then an empty statement is enough. That does not disable strict mode. Actually it does (since a strict mode, and the directive prologue is an initial statement): use strict;eval=10 // strict, error but ;use strict;eval = 10; // non-strict, OK The problem at real sites including an intel.com property is that subsequent parts of the concatenation have had strict mode errors. The second part of the (combined) file is also evaluated in non-strict, because again, use strict is placed not at the initial position. So, the whole file is in non-strict. However, as mentioned Mike Shaver, there can be issues with vice-versa, turning to non-strict, e.g. non-object or even non-undefined /this/ value. So, the suggestion is just a workaround. Dmitry. ;/*1st lib*/use strict;eval = 10;/*2st lib*/use strict;arguments=20;/*our code*/ An example showing the problem would need a use nonstrict; directive after the first part of the concatenation, but there is no such directive. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Names strawman ready for discussion
On Thu, Sep 9, 2010 at 07:08, Tom Van Cutsem tomvc...@gmail.com wrote: Both of these seem to be compelling advantages of soft fields over names. However, I wonder if it would be possible to get the best of both worlds. IIUC, the Names proposal converts: private x; this.x = foo; this.x into: let x = new Name; this[x] = foo; this[x] Would it be possible to instead rewrite it to: let x = new ExplicitSoftField(); x.set(this, foo); x.get(this) (using the same rules for determining the scope of 'x' as detailed in the Names proposal) You would get the 'private' scoping of Names, and the concise syntax, without the limitations that MarkM raised. Am I missing something? +1 x could also be a WeakMap in the sample above. This reminds me; I still don't understand why we would want both ExplicitSoftField and WeakMap. If we make the API for WeakMap not so bare bone it can cover both use cases. The thing I like with the Names proposal compared to using WeakMaps is that using WeakMaps feels very backwards. -- erik ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: use strict; prepended blindly to scripts in the wild
On Sep 9, 2010, at 10:33 AM, Dmitry Soshnikov wrote: On Thu, Sep 9, 2010 at 6:32 PM, Brendan Eich bren...@mozilla.com wrote: On Sep 9, 2010, at 1:09 AM, Dmitry Soshnikov wrote: Thus the site's combined file won't be globally strict, however since a lib is tested before a production release (at least I hope so ;), then the lib's code should pass the strictness, and therefore, a use strict may be even removed from the lib's file. However, if not to remove, then an empty statement is enough. That does not disable strict mode. Actually it does (since a strict mode, and the directive prologue is an initial statement): use strict;eval=10 // strict, error but ;use strict;eval = 10; // non-strict, OK Oh, I see -- that solves the problem of strict mode in the second or later parts of the concatenation. But the problem that's already come up on the web has strict mode enabled in the first part, which complies with strict mode, but later parts do not -- and there's no way to disable for them. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: use strict; prepended blindly to scripts in the wild
On Thu, Sep 9, 2010 at 9:35 PM, Brendan Eich bren...@mozilla.com wrote: On Sep 9, 2010, at 10:33 AM, Dmitry Soshnikov wrote: On Thu, Sep 9, 2010 at 6:32 PM, Brendan Eich bren...@mozilla.com wrote: On Sep 9, 2010, at 1:09 AM, Dmitry Soshnikov wrote: Thus the site's combined file won't be globally strict, however since a lib is tested before a production release (at least I hope so ;), then the lib's code should pass the strictness, and therefore, a use strict may be even removed from the lib's file. However, if not to remove, then an empty statement is enough. That does not disable strict mode. Actually it does (since a strict mode, and the directive prologue is an initial statement): use strict;eval=10 // strict, error but ;use strict;eval = 10; // non-strict, OK Oh, I see -- that solves the problem of strict mode in the second or later parts of the concatenation. But the problem that's already come up on the web has strict mode enabled in the first part, which complies with strict mode, but later parts do not -- and there's no way to disable for them. OK, seems I didn't catch the goal then. I though, that there is some single js-holy-file, which is a combination of some 3rd-party js-files (libs). And one (the first one) of the libs uses strict mode, and other -- do not (that causes issues in the code of later parts, 'cause the whole file becomes strict). But that exactly I proposed -- to insert into the combined file an /empty statement/ _before_ the first part. Thus, the whole single (combined) file will be non-strict. Even if there are several strict directives later (from every part) -- all of them (including the first one) will be canceled because of this inserted empty statement at the beginning of the file. But repeat, there may be issues with different semantics of /this/ value in strict and non-strict modes. So, as noted, it's just a quick workaround. Also it won't help if a user uses dynamically loaded js-files from external sources. So, this issue may really be the issue for users of such external files. Dmitry. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: use strict; prepended blindly to scripts in the wild
On Sep 9, 2010, at 11:57 AM, Dmitry Soshnikov wrote: But that exactly I proposed -- to insert into the combined file an /empty statement/ _before_ the first part. Right. There's a rule, Dojo follows it IIRC, to prepend ; to all files, always. That will do the trick. But of course people don't all folllow that rule and nothing enforces it. Concatenation is never safe when done blindly, but use strict ups the ante. The particular problem is that browsers aren't yet checking use strict, so erroneous content is getting out into the wild. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Classes as Sugar is now ready for discussion
On Sun, Sep 5, 2010 at 6:33 PM, Mark S. Miller erig...@google.com wrote: http://wiki.ecmascript.org/doku.php?id=strawman:classes_as_sugar * Classes as Sugar All this looks a bit strange. From several positions. First, combination of classes and prototypes. Currently, the paradigm used in ECMAScript with delegation based prototypes does not differ much from a class-based paradigm with first-class dynamic classes. The good example is Python. You won't find a big difference between Python's (first-class dynamic) classes and prototypes+constructor in ECMAScript. Thus, the major aspects should be considered: methods/properties resolution and code-reuse stylistics. In both, ECMAScript and Python, a delegation based inheritance is used to achieve both objectives. I.e. Python's classes are just syntactic sugar of delegation based model used in ECMAScript. Thus (the lacks of your desugarred code): 1. you don't have a good code-reuse mechanism (which should be used the same -- a delegation to a class/prototype), i.e. every returned frozen instance has own properties/methods that is non efficient. 2. you don't have an inheritance (again code-reuse, but the code of parent prototypes). Both lacks may be avoided even in ES5 implementation. Though, the desugarred code will look ugly (with passing private state of objects to be able place all methods -- private and public in to the prototype (public methods) and its surrounding environment (private methods), having only one instance of a method for for a class). Using new things such Names or WeakMaps possibly it's even easier to achieve. In your approach, there is a code-reuse, but it's made as cloning, but not dispatching. Cloning (concatenative prototypes) is faster, but very inefficient by memory. So, it's even may be called a smart copy-paste, but not reuse (of the same memory). The part of this strawman I am least happy is the rules of this at http://wiki.ecmascript.org/doku.php?id=strawman:classes_as_sugar#delicate_self_reference. Suggestions appreciated. Thanks. The second one issue is that the sugar is not so sugarred. I think it should syntactically be minimalistic and do not use several forms of methods/functions (that will avoid the problem with /this/ value). As I see it: class Point(x, y) { private: var x = 10 var y = 20 function calculate(z) { var x = 30 // use this to refer instance // properties and distinguish from // local var of a function this.x + this.y + x + z } public: var z = 30 function foo(z) { this.bar() + this.calculate(z); } const function bar() { this.z + 10 } } class MyPoint(x, ...args) inherits Point { public: function foo() { super(this.x) + 30 } } Formal parameters may be moved to the initialize method. Also function expressions may be used to define a method conditionally: class MyPoint inherits Point { public: function initialize(x, ...args) { this.x = x; } function foo() { super(this.x) + 30 } // a FE function bar = debug ? (x, y) { ...} : (x) { ... }; } P.S.: I mean, if you want a classes-sugar, then it really should be a shugar and use all related things, including code-reuse implemented as delegation based inheritance (thus a prototype may be frozen for static classes and not -- for dynamic). Dmitry. -- 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: Classes as Sugar is now ready for discussion
As Brendan pointed out, the version evolution problem is nowhere near a solved issue in language design; the only approaches I know of that get close to it are the versioning of words in Forth and, depending on how you look at it, the dynamic code loading mechanisms of Erlang (and class loaders in Java). Insisting that we somehow come up with a mechanism to prevent conflicts seems like a pretty high bar; I'd like to hear more from people with such a view if that was indeed the blocking objection. -- Dirk On Thu, Sep 9, 2010 at 3:13 AM, Tom Van Cutsem tomvc...@gmail.com wrote: There's no mistake that dedicated syntax for traits would help users and implementors alike. However, while I (or others) could definitely come up with a 'traits-as-sugar', or even a 'traits-as-a-new-value' proposal, that still wouldn't solve the version evolution problem associated with trait composition (or any other traditional inheritance mechanism). As long as this remains a deal-breaker, I don't think it's worth looking into alternative traits proposals. As Dave said, traits.js is out there for people to experiment with. Any feedback on usability issues of the design in its current form are highly appreciated. 2010/9/9 David Herman dher...@mozilla.com Agreed; perhaps my question was not clear. If there was a Traits-like proposal that did include new syntax, would you be against it because you can implement something similar as a library without needing new semantics, or would you be more inclined to reserve judgement until you could actually review a proposal and see what the proposed benefits were? The latter (speaking for myself, of course). 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: Classes as Sugar is now ready for discussion
On Thu, Sep 9, 2010 at 10:37 PM, Brendan Eich bren...@mozilla.com wrote: On Sep 9, 2010, at 3:06 PM, Dirk Pranke wrote: As Brendan pointed out, the version evolution problem is nowhere near a solved issue in language design; the only approaches I know of that get close to it are the versioning of words in Forth and, depending on how you look at it, the dynamic code loading mechanisms of Erlang (and class loaders in Java). Insisting that we somehow come up with a mechanism to prevent conflicts seems like a pretty high bar; I'd like to hear more from people with such a view if that was indeed the blocking objection. That would be Waldemar :-). Again, I feel it is important to say that everyone in TC39 who spoke up averred that traits.js is a well-written library, compelling in many ways. However, here are some other issues with the library, which need to be restated or presented properly so that Waldemar is not painted as sole spoiler: 1. It's premature to standardize something so new. Again, the Array extras (map, filter, etc.) have been a de-facto standard for years, getters and setters for over a decade, bind-like library methods and JSON for quite a long while. 2. I didn't know this till yesterday, but the Bespin (Skywriter, gag ;-) team at Mozilla tried using traits.js and had to stop, because it was consuming too much memory. I understand that this is from the pervasive use in the library of |this|-binding and copying to instance properties of all methods, along with other uses of closures. There is no prototypal sharing of method, or anything like vtables. Some of this could be optimized by aggressively-optimizing VMs, but it carries a heavy intrinsic cost. I think this is the key issue. Tom and I designed the traits library so that the expected common pattern of use would be easily optimizable by VMs, with no surprising intrinsic costs. If we missed the mark -- if there are indeed hidden costs lurking here that we missed -- that would be interesting. The expected common pattern which we expect to be optimizable needs to be stated clearly. Loosely, it is when trait composition is sufficiently statically analyzable that it can be expanded as if to a call to Trait.create with a literal property-descriptor-map argument. We also discussed that this is a good reason to couple VM support with special syntax -- so the special syntax can sugar only (primarily?) that pattern which can be handled efficiently. The full library would still be available for expressiveness of patterns that we don't expect VMs to optimize. 3. The design, in trying to catch conflicts, copies this-bound methods, freezes objects, and avoids prototype-based delegation. Beyond the costs in 2, this makes for a harshly bright line between Object.create and Trait.create, and although it is cool that the two systems complement each other, more traditional JS hackers arguably want prototype-based delegation, even though it may carry a shadowing conflict risk down the road. Some JS hackers even want mutability, with spot-checks for conflicts instead of for all/ever guarantees. These are not points we've discussed enough in committee, since we didn't talk about traits again since March. As noted, some details are news to me, but good to hear later instead of never. Points 2 and 3 are related: traits.js aims at higher integrity, for robust composition, than many JS hackers prefer and would choose (from what I hear, now -- I'd be happy to hear stories of successful adoption of the traitsjs.org code to counter the Bespin experience). A number of people, and I'm one of them having heard all the feedback so far (although I cited the costs listed in 2 on this list when the proposal was first posted), believe that this integrity trade-off should not be forced by blessing one fairly costly and near-extreme point in the trade-off space as a core language feature. This gets back to point 1. It also relates to the recent objections to zero-inheritance classes as sugar, which have high integrity but no inheritance. /be -- Dirk On Thu, Sep 9, 2010 at 3:13 AM, Tom Van Cutsem tomvc...@gmail.com wrote: There's no mistake that dedicated syntax for traits would help users and implementors alike. However, while I (or others) could definitely come up with a 'traits-as-sugar', or even a 'traits-as-a-new-value' proposal, that still wouldn't solve the version evolution problem associated with trait composition (or any other traditional inheritance mechanism). As long as this remains a deal-breaker, I don't think it's worth looking into alternative traits proposals. As Dave said, traits.js is out there for people to experiment with. Any feedback on usability issues of the design in its current form are highly appreciated. 2010/9/9 David Herman dher...@mozilla.com Agreed; perhaps my question was not clear. If there was a Traits-like proposal that did include new
Re: Classes as Sugar is now ready for discussion
On Thu, Sep 9, 2010 at 10:37 PM, Brendan Eich bren...@mozilla.com wrote: On Sep 9, 2010, at 3:06 PM, Dirk Pranke wrote: As Brendan pointed out, the version evolution problem is nowhere near a solved issue in language design; the only approaches I know of that get close to it are the versioning of words in Forth and, depending on how you look at it, the dynamic code loading mechanisms of Erlang (and class loaders in Java). Insisting that we somehow come up with a mechanism to prevent conflicts seems like a pretty high bar; I'd like to hear more from people with such a view if that was indeed the blocking objection. That would be Waldemar :-). Again, I feel it is important to say that everyone in TC39 who spoke up averred that traits.js is a well-written library, compelling in many ways. However, here are some other issues with the library, which need to be restated or presented properly so that Waldemar is not painted as sole spoiler: 1. It's premature to standardize something so new. Again, the Array extras (map, filter, etc.) have been a de-facto standard for years, getters and setters for over a decade, bind-like library methods and JSON for quite a long while. 2. I didn't know this till yesterday, but the Bespin (Skywriter, gag ;-) team at Mozilla tried using traits.js and had to stop, because it was consuming too much memory. I understand that this is from the pervasive use in the library of |this|-binding and copying to instance properties of all methods, along with other uses of closures. There is no prototypal sharing of method, or anything like vtables. Some of this could be optimized by aggressively-optimizing VMs, but it carries a heavy intrinsic cost. 3. The design, in trying to catch conflicts, copies this-bound methods, freezes objects, and avoids prototype-based delegation. Beyond the costs in 2, this makes for a harshly bright line between Object.create and Trait.create, and although it is cool that the two systems complement each other, more traditional JS hackers arguably want prototype-based delegation, even though it may carry a shadowing conflict risk down the road. Some JS hackers even want mutability, with spot-checks for conflicts instead of for all/ever guarantees. These are not points we've discussed enough in committee, since we didn't talk about traits again since March. As noted, some details are news to me, but good to hear later instead of never. Points 2 and 3 are related: traits.js aims at higher integrity, for robust composition, than many JS hackers prefer and would choose (from what I hear, now -- I'd be happy to hear stories of successful adoption of the traitsjs.org code to counter the Bespin experience). Both the good and the bad news from the Bespin experience are exactly what Tom I expected in the absence of VM support. Also, the duality of Object.create vs Traits.create accommodates traditional vs high integrity quite well -- without AFAICT compromising either. A number of people, and I'm one of them having heard all the feedback so far (although I cited the costs listed in 2 on this list when the proposal was first posted), believe that this integrity trade-off should not be forced by blessing one fairly costly and near-extreme point in the trade-off space as a core language feature. This gets back to point 1. It also relates to the recent objections to zero-inheritance classes as sugar, which have high integrity but no inheritance. /be -- Dirk On Thu, Sep 9, 2010 at 3:13 AM, Tom Van Cutsem tomvc...@gmail.com wrote: There's no mistake that dedicated syntax for traits would help users and implementors alike. However, while I (or others) could definitely come up with a 'traits-as-sugar', or even a 'traits-as-a-new-value' proposal, that still wouldn't solve the version evolution problem associated with trait composition (or any other traditional inheritance mechanism). As long as this remains a deal-breaker, I don't think it's worth looking into alternative traits proposals. As Dave said, traits.js is out there for people to experiment with. Any feedback on usability issues of the design in its current form are highly appreciated. 2010/9/9 David Herman dher...@mozilla.com Agreed; perhaps my question was not clear. If there was a Traits-like proposal that did include new syntax, would you be against it because you can implement something similar as a library without needing new semantics, or would you be more inclined to reserve judgement until you could actually review a proposal and see what the proposed benefits were? The latter (speaking for myself, of course). Dave ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org
Re: Classes as Sugar is now ready for discussion
Also, the duality of Object.create vs Traits.create accommodates traditional vs high integrity quite well -- without AFAICT compromising either. It creates a false choice, though (all or nothing). IIUC, with Object.create, you don't even get the conflict checking. And then you've really lost the key benefit of traits. I think there's room for alternatives in the traits space -- for example, something similar wrt trait composition, but that didn't bind |this| or freeze. That way, you could still integrate traits with the existing prototype system. For example, to compose traits to create an object that you then use as the prototype for a constructor. This would allow for the vtables approach and would also give you the ability to specify initialization behavior to invoke on instantiation, which you can't do with traits.js. Dave ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Classes as Sugar is now ready for discussion
On Sep 9, 2010, at 4:06 PM, Mark S. Miller wrote: 1. It's premature to standardize something so new. Again, the Array extras (map, filter, etc.) have been a de-facto standard for years, getters and setters for over a decade, bind-like library methods and JSON for quite a long while. 2. I didn't know this till yesterday, but the Bespin (Skywriter, gag ;-) team at Mozilla tried using traits.js and had to stop, because it was consuming too much memory. I understand that this is from the pervasive use in the library of |this|-binding and copying to instance properties of all methods, along with other uses of closures. There is no prototypal sharing of method, or anything like vtables. Some of this could be optimized by aggressively-optimizing VMs, but it carries a heavy intrinsic cost. I think this is the key issue. Points 1 and 3 are worth addressing, if you are game. Tom and I designed the traits library so that the expected common pattern of use would be easily optimizable by VMs, with no surprising intrinsic costs. If we missed the mark -- if there are indeed hidden costs lurking here that we missed -- that would be interesting. You may recall the posts I made at the time: https://mail.mozilla.org/pipermail/es-discuss/2010-February/010830.html https://mail.mozilla.org/pipermail/es-discuss/2010-February/010832.html The expected common pattern which we expect to be optimizable needs to be stated clearly. Loosely, it is when trait composition is sufficiently statically analyzable that it can be expanded as if to a call to Trait.create with a literal property-descriptor-map argument. We also discussed that this is a good reason to couple VM support with special syntax -- so the special syntax can sugar only (primarily?) that pattern which can be handled efficiently. The full library would still be available for expressiveness of patterns that we don't expect VMs to optimize. It's true, syntax can help optimizability (and usability). But we never heard a proposal and it's hard to make one up without worrying about how |this|-binding works in detail, e.g. Does a call go through a vtable in the case where the method is invoked via a property reference, otherwise a bound method object is created (for the escaping funarg case)? And so on, in sufficient detail to see a path to trial implementation and interoperable observable semantics, including approximate or asymptotic cost models. /be 3. The design, in trying to catch conflicts, copies this-bound methods, freezes objects, and avoids prototype-based delegation. Beyond the costs in 2, this makes for a harshly bright line between Object.create and Trait.create, and although it is cool that the two systems complement each other, more traditional JS hackers arguably want prototype-based delegation, even though it may carry a shadowing conflict risk down the road. Some JS hackers even want mutability, with spot-checks for conflicts instead of for all/ever guarantees. These are not points we've discussed enough in committee, since we didn't talk about traits again since March. As noted, some details are news to me, but good to hear later instead of never. Points 2 and 3 are related: traits.js aims at higher integrity, for robust composition, than many JS hackers prefer and would choose (from what I hear, now -- I'd be happy to hear stories of successful adoption of the traitsjs.org code to counter the Bespin experience). A number of people, and I'm one of them having heard all the feedback so far (although I cited the costs listed in 2 on this list when the proposal was first posted), believe that this integrity trade-off should not be forced by blessing one fairly costly and near-extreme point in the trade-off space as a core language feature. This gets back to point 1. It also relates to the recent objections to zero-inheritance classes as sugar, which have high integrity but no inheritance. /be -- Dirk On Thu, Sep 9, 2010 at 3:13 AM, Tom Van Cutsem tomvc...@gmail.com wrote: There's no mistake that dedicated syntax for traits would help users and implementors alike. However, while I (or others) could definitely come up with a 'traits-as-sugar', or even a 'traits-as-a-new-value' proposal, that still wouldn't solve the version evolution problem associated with trait composition (or any other traditional inheritance mechanism). As long as this remains a deal-breaker, I don't think it's worth looking into alternative traits proposals. As Dave said, traits.js is out there for people to experiment with. Any feedback on usability issues of the design in its current form are highly appreciated. 2010/9/9 David Herman dher...@mozilla.com Agreed; perhaps my question was not clear. If there was a Traits-like proposal that did include new syntax, would you be against it because you can implement something similar as a library
Re: Classes as Sugar is now ready for discussion
On Thu, Sep 9, 2010 at 11:31 PM, David Herman dher...@mozilla.com wrote: Also, the duality of Object.create vs Traits.create accommodates traditional vs high integrity quite well -- without AFAICT compromising either. It creates a false choice, though (all or nothing). It does create a choice. What makes a choice false? The traits library is an open abstraction -- it doesn't encapsulate anything; it only provides some conveniences for sets of choices that seem to go together. It doesn't preclude others from making other choices, or from providing further abstractions for making those choices convenient. Of course, that doesn't mean we've chosen the right set of knobs. A better set of knobs would be great. But, IMO, simply having more knobs wouldn't be. IIUC, with Object.create, you don't even get the conflict checking. And then you've really lost the key benefit of traits. See http://code.google.com/p/es-lab/source/browse/trunk/src/traits/traits.js#150. Even with Object.create, you still get conflict detection, but with failure postponed from creation to usage. This is a more traditionally JavaScripty way to report failure anyway. I think there's room for alternatives in the traits space -- for example, something similar wrt trait composition, but that didn't bind |this| or freeze. That way, you could still integrate traits with the existing prototype system. For example, to compose traits to create an object that you then use as the prototype for a constructor. This would allow for the vtables approach and would also give you the ability to specify initialization behavior to invoke on instantiation, which you can't do with traits.js. Yes you can: function Point(x, y) { this.x = x; this.y = y; } Point.prototype = Object.create( SuperPoint.prototype, Trait.compose(.)); Is that the kind of usage you had in mind? -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Classes as Sugar is now ready for discussion
On Fri, Sep 10, 2010 at 5:30 AM, David Herman dher...@mozilla.com wrote: IIUC, with Object.create, you don't even get the conflict checking. And then you've really lost the key benefit of traits. See http://code.google.com/p/es-lab/source/browse/trunk/src/traits/traits.js#150. Even with Object.create, you still get conflict detection, but with failure postponed from creation to usage. This is a more traditionally JavaScripty way to report failure anyway. Ah, I see. I missed that part. Is the on-demand nature of conflict detection (for traits built with Object.create) somehow unavoidable, or was that simply a design choice? It actually was a design choice dating from before we switched to Object.create. Originally, we had a high-vs-low integrity switch in Traits.create. As Tom was implementing our design, he noticed that the low integrity case simplified down to being identical to Object.create. Seeing that, Tom realized that we didn't actually need a switch as people could just use Object.create directly. Tom, do I have the history of that right? function Point(x, y) { this.x = x; this.y = y; } Point.prototype = Object.create( SuperPoint.prototype, Trait.compose(.)); Is that the kind of usage you had in mind? Yes, exactly. Sorry for my oversight. Dave -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss