Fwd: [JS-internals] additional test for 15.10.6.2, RegExp.prototype.exec
From: Brendan Eich bren...@mozilla.com Subject: Re: [JS-internals] additional test for 15.10.6.2, RegExp.prototype.exec Date: 27 June 2013 0:16:49 GMT+02:00 To: Paul Ruizendaal p...@planet.nl Please resend to es-discuss. At least two browsers agree on each side of the fence, so this isn't just a mozilla.dev.tech.js-engine.internal issue. /be Paul Ruizendaal wrote: The Spidermonkey test suite contains the following test (in file ecma_5/RegExp/exec.js): r = /abc/; r.lastIndex = -17; res = r.exec(cdefg); assertEq(res, null); assertEq(r.lastIndex, -17); In my understanding this test is wrong, lastIndex should be 0 due to step 9.a.(i). Safari and Firefox report -17, Chrome and IE report 0. I guess it is a tricky part of the spec as most real world implementations will move the iteration of step 9 into the [[Match]] routine as to enable first character optimizations and alike. The correct behavior is not covered in test262. Recommend to add the following test: /* * @es5id 15.10.6.2 (step 9.a.i) * @description If the pattern does not match, lastIndex is always set to 0, even if the 'global' flag is false. */ function testCase() { var r = /abc/; r.lastIndex = -17; res = r.exec(defg); return r.lastIndex===0; } Note that the original Spidermonkey test is in the public domain, according to the file header. This post is also placed in the public domain. Paul ___ dev-tech-js-engine-internals mailing list dev-tech-js-engine-intern...@lists.mozilla.org https://lists.mozilla.org/listinfo/dev-tech-js-engine-internals ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: [JS-internals] additional test for 15.10.6.2, RegExp.prototype.exec
Note that we have a bug[1] open and a patch in review for that now. As of now, it looks like a bug we're going to fix, but Jeff might come to a different conclusion during the review. [1]: https://bugzilla.mozilla.org/show_bug.cgi?id=887676 On Fri, Jun 28, 2013 at 1:23 PM, Paul Ruizendaal p...@planet.nl wrote: From: Brendan Eich bren...@mozilla.com Subject: Re: [JS-internals] additional test for 15.10.6.2, RegExp.prototype.exec Date: 27 June 2013 0:16:49 GMT+02:00 To: Paul Ruizendaal p...@planet.nl Please resend to es-discuss. At least two browsers agree on each side of the fence, so this isn't just a mozilla.dev.tech.js-engine.internal issue. /be Paul Ruizendaal wrote: The Spidermonkey test suite contains the following test (in file ecma_5/RegExp/exec.js): r = /abc/; r.lastIndex = -17; res = r.exec(cdefg); assertEq(res, null); assertEq(r.lastIndex, -17); In my understanding this test is wrong, lastIndex should be 0 due to step 9.a.(i). Safari and Firefox report -17, Chrome and IE report 0. I guess it is a tricky part of the spec as most real world implementations will move the iteration of step 9 into the [[Match]] routine as to enable first character optimizations and alike. The correct behavior is not covered in test262. Recommend to add the following test: /* * @es5id 15.10.6.2 (step 9.a.i) * @description If the pattern does not match, lastIndex is always set to 0, even if the 'global' flag is false. */ function testCase() { var r = /abc/; r.lastIndex = -17; res = r.exec(defg); return r.lastIndex===0; } Note that the original Spidermonkey test is in the public domain, according to the file header. This post is also placed in the public domain. Paul ___ dev-tech-js-engine-internals mailing list dev-tech-js-engine-intern...@lists.mozilla.org https://lists.mozilla.org/listinfo/dev-tech-js-engine-internals ___ 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: Why does Array.from accept non-iterable arraylikes?
On Thu, Jun 27, 2013 at 1:04 PM, Dean Landolt d...@deanlandolt.com wrote: On Thu, Jun 27, 2013 at 11:56 AM, Jason Orendorff jason.orendo...@gmail.com wrote: If you mean a library function that expects either an iterable or a dictionary, then it would correctly treat your non-iterable data object as a dictionary. So... I guess I don't see the problem. Everything seems fine. Dean, I would appreciate a response to this. An example of a specific case where there would be an actual problem would help the conversation tremendously. Surely length is a more common database column name than iterator. So if you're right, surely we already have these problems with existing library functions that take arraylike objects. Is that the case? Are there confusing bug reports and hacked-in fallbacks? Apples and oranges -- people don't use arrays as maps. People won't use iterables as maps either; the kind of maps we are talking about are ObjectLiterals, and they are not iterable. (You can iterate over their properties, though, using a 4-line generator or Object.keys().) The reason I brought up that example is that people *do* use objects with .length properties as arraylikes, leading to potential ambiguity about whether an object with a .length property is a plain-Object map or an arraylike. I thought perhaps that was the sort of confusion you were concerned about. Perhaps a better example would be `hasOwnProperty` -- I know there have been bug reports. The MDN page goes out of its way to warn about this [1]: This is a problem because .hasOwnProperty is an operation that people naturally want to apply to plain-Object maps. .iterator() is not, because plain Objects are not iterable. -j ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Destructuring and default parameters in functions
Good to see that the expected functionality is also how it is intended to function. Hopefully the bug Brandon referred to will be fixed soon, so it can be tested in a browser. By using default params and destructuring a neat module loading syntax can be defined (as opposed to the import syntax of ES6 or the array in AMD): https://gist.github.com/mariusGundersen/5884450 Marius Gundersen On Thu, Jun 27, 2013 at 8:27 PM, Brandon Benvie bben...@mozilla.com wrote: On 6/27/2013 3:19 AM, Marius Gundersen wrote: Or maybe it just isn't implemented in Firefox? This is correct. https://bugzilla.mozilla.org/**show_bug.cgi?id=884372https://bugzilla.mozilla.org/show_bug.cgi?id=884372 __**_ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/**listinfo/es-discusshttps://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Skeleton for July agenda
You guys are finally going to talk about closure! :P On Fri, Jun 28, 2013 at 8:03 AM, Alex Russell slightly...@google.comwrote: ...is here: https://github.com/tc39/agendas/blob/master/2013/07.md Feel free to submit pull requests or, if you are a committee member, ask to be added to the editor's group (just send me your github username and I'll sort it out). Regards ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss -- - Matthew Robb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Why does Array.from accept non-iterable arraylikes?
On Fri, Jun 28, 2013 at 9:59 AM, Jason Orendorff jason.orendo...@gmail.comwrote: On Thu, Jun 27, 2013 at 1:04 PM, Dean Landolt d...@deanlandolt.com wrote: On Thu, Jun 27, 2013 at 11:56 AM, Jason Orendorff jason.orendo...@gmail.com wrote: If you mean a library function that expects either an iterable or a dictionary, then it would correctly treat your non-iterable data object as a dictionary. So... I guess I don't see the problem. Everything seems fine. Dean, I would appreciate a response to this. An example of a specific case where there would be an actual problem would help the conversation tremendously. Surely length is a more common database column name than iterator. So if you're right, surely we already have these problems with existing library functions that take arraylike objects. Is that the case? Are there confusing bug reports and hacked-in fallbacks? Apples and oranges -- people don't use arrays as maps. People won't use iterables as maps either; the kind of maps we are talking about are ObjectLiterals, and they are not iterable. (You can iterate over their properties, though, using a 4-line generator or Object.keys().) The reason I brought up that example is that people *do* use objects with .length properties as arraylikes, leading to potential ambiguity about whether an object with a .length property is a plain-Object map or an arraylike. I thought perhaps that was the sort of confusion you were concerned about. You've got bigger problems if you're trying this -- the language defines semantics for `length` on strings and arrays -- generic code would be foolish to try and go further. But this example does in fact kill my argument (see below). An aside -- yes, in my ideal world there would be a unique symbol that stood in for the `count` of a thing (how many distinct `items` it has). More than one, in fact, since there are competing notions of counts on the same kind of thing. If designed carefully this kind of approach could go a long way toward cleaning up the notion of types in javascript...but I'm way off topic... Perhaps a better example would be `hasOwnProperty` -- I know there have been bug reports. The MDN page goes out of its way to warn about this [1]: This is a problem because .hasOwnProperty is an operation that people naturally want to apply to plain-Object maps. .iterator() is not, because plain Objects are not iterable. I was missing this detail -- I remember the discussion around this but for some reason was assuming a different design with a default iterator on Object.prototype, and the built-in iterator methods deferring to this). Admittedly this weakens my arguments. But I still wonder how the actual built-in iterators are expected to be shimmed (without shimming a whole module system)? From this thread I believe *this* is the core problem that has yet to be addressed. If solved it would also make system symbols much less inconvenient for polyfills. From this perspective it seems unnecessary to, umm, pee in the namespace pool. But yeah, my strongest arguments for iterator-as-symbol are pretty well mooted :) ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
[no subject]
I know this has been batted around already. I know everybody's totally stoked about class sugar in ES6. I just wanted to register my protest. I made my arguments in this talk at Fluent: http://ericleads.com/2013/06/classical-inheritance-is-obsolete-how-to-think-in-prototypal-oo/ I'm already seeing nasty codebase arthritis creep into JavaScript projects thanks to things like Backbone.View.extend() being essentially mandatory. Providing sugar to extend classes in JavaScript proper is like officially sanctioning that nonsense. I'm not the only one who feels that way. Here's an excerpt from one viewer's comment on my presentation: I think this will only get worse with ES6 and I am rather upset about it. While 'class' will be elective of course, I can only imagine more and more libraries adopting the ES6 class pattern, and then we will wind up facing the same set of challenges that exist in the Java world. In my opinion, the clamoring for class in JavaScript is because JavaScript tries to hide prototypes, rather than make it easy to deal with them. Instead of class, we should let library authors continue to experiment with other inheritance patterns in JavaScript. Here's an example: https://github.com/dilvie/stampit We do need a bit more object sugar in JS, but I think we should wait for some patterns to gain a foothold in the wild, and only when popular patterns emerge and have time to be tested and proven to be well-thought-out and a valuable addition (unlike Backbone's .extend(), which is causing lots of problems in the real world), only THEN should the idea be blessed by the specification. Is class a good idea in JavaScript? I say, prove it. In fact, anything that can have a reference implementation should be proven - not just by implementing it to see if it can work, but if it can be polyfilled (or something like it could be polyfilled), put it in a library and see if it catches on before you add it to the spec, and everybody starts to write about it in their new JavaScript features posts. So far, NO IMPLEMENTATION of class in JavaScript has become a de-facto standard. I think we should set the bar a little higher where a new feature could actually cause damage to the language ecosystem. Until Backbone came along and made .extend() the default way to create any Backbone object, it was very easy for a JavaScript programmer to spend an entire career having never extended from an existing class. And that was a good thing. $.02 ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re:
On Fri, Jun 28, 2013 at 10:42 AM, Eric Elliott e...@ericleads.com wrote: I know this has been batted around already. I know everybody's totally stoked about class sugar in ES6. I just wanted to register my protest. I made my arguments in this talk at Fluent: http://ericleads.com/2013/06/classical-inheritance-is-obsolete-how-to-think-in-prototypal-oo/ I'm already seeing nasty codebase arthritis creep into JavaScript projects thanks to things like Backbone.View.extend() being essentially mandatory. Providing sugar to extend classes in JavaScript proper is like officially sanctioning that nonsense. I'm not the only one who feels that way. Here's an excerpt from one viewer's comment on my presentation: I think this will only get worse with ES6 and I am rather upset about it. While 'class' will be elective of course, I can only imagine more and more libraries adopting the ES6 class pattern, and then we will wind up facing the same set of challenges that exist in the Java world. In my opinion, the clamoring for class in JavaScript is because JavaScript tries to hide prototypes, rather than make it easy to deal with them. Instead of class, we should let library authors continue to experiment with other inheritance patterns in JavaScript. Here's an example: https://github.com/dilvie/stampit We do need a bit more object sugar in JS, but I think we should wait for some patterns to gain a foothold in the wild, and only when popular patterns emerge and have time to be tested and proven to be well-thought-out and a valuable addition (unlike Backbone's .extend(), which is causing lots of problems in the real world), only THEN should the idea be blessed by the specification. Is class a good idea in JavaScript? I say, prove it. In fact, anything that can have a reference implementation should be proven - not just by implementing it to see if it can work, but if it can be polyfilled (or something like it could be polyfilled), put it in a library and see if it catches on before you add it to the spec, and everybody starts to write about it in their new JavaScript features posts. So far, NO IMPLEMENTATION of class in JavaScript has become a de-facto standard. I think we should set the bar a little higher where a new feature could actually cause damage to the language ecosystem. Until Backbone came along and made .extend() the default way to create any Backbone object, it was very easy for a JavaScript programmer to spend an entire career having never extended from an existing class. And that was a good thing. Lots and *lots* of code already uses the class pattern is JS, because the class pattern is nothing more than: function Foo(){...} Foo.prototype = ...; Foo.prototype.method1 = function(){...} The class syntax just makes this super-common idiom easier to read and write. ~TJ ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re:
I'm not here to discuss the mechanics of what class does. I'm just saying we shouldn't do it in the spec. There are better alternatives that pose less threat to the JavaScript ecosystem. A handful of libraries and JavaScript authors twisting prototypes to make them less useful is one thing. Getting a blessing from on-high for people to teach that it's how to do inheritance in JavaScript in teaching materials is quite another thing. My arguments (and a few suggested alternatives) are in the video. If you're going to blow off what I have to say about it because you don't have time to watch a video, I guess the conversation is over. =) - Eric On Fri, Jun 28, 2013 at 10:45 AM, Tab Atkins Jr. jackalm...@gmail.comwrote: On Fri, Jun 28, 2013 at 10:42 AM, Eric Elliott e...@ericleads.com wrote: I know this has been batted around already. I know everybody's totally stoked about class sugar in ES6. I just wanted to register my protest. I made my arguments in this talk at Fluent: http://ericleads.com/2013/06/classical-inheritance-is-obsolete-how-to-think-in-prototypal-oo/ I'm already seeing nasty codebase arthritis creep into JavaScript projects thanks to things like Backbone.View.extend() being essentially mandatory. Providing sugar to extend classes in JavaScript proper is like officially sanctioning that nonsense. I'm not the only one who feels that way. Here's an excerpt from one viewer's comment on my presentation: I think this will only get worse with ES6 and I am rather upset about it. While 'class' will be elective of course, I can only imagine more and more libraries adopting the ES6 class pattern, and then we will wind up facing the same set of challenges that exist in the Java world. In my opinion, the clamoring for class in JavaScript is because JavaScript tries to hide prototypes, rather than make it easy to deal with them. Instead of class, we should let library authors continue to experiment with other inheritance patterns in JavaScript. Here's an example: https://github.com/dilvie/stampit We do need a bit more object sugar in JS, but I think we should wait for some patterns to gain a foothold in the wild, and only when popular patterns emerge and have time to be tested and proven to be well-thought-out and a valuable addition (unlike Backbone's .extend(), which is causing lots of problems in the real world), only THEN should the idea be blessed by the specification. Is class a good idea in JavaScript? I say, prove it. In fact, anything that can have a reference implementation should be proven - not just by implementing it to see if it can work, but if it can be polyfilled (or something like it could be polyfilled), put it in a library and see if it catches on before you add it to the spec, and everybody starts to write about it in their new JavaScript features posts. So far, NO IMPLEMENTATION of class in JavaScript has become a de-facto standard. I think we should set the bar a little higher where a new feature could actually cause damage to the language ecosystem. Until Backbone came along and made .extend() the default way to create any Backbone object, it was very easy for a JavaScript programmer to spend an entire career having never extended from an existing class. And that was a good thing. Lots and *lots* of code already uses the class pattern is JS, because the class pattern is nothing more than: function Foo(){...} Foo.prototype = ...; Foo.prototype.method1 = function(){...} The class syntax just makes this super-common idiom easier to read and write. ~TJ ___ 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:
On Fri, Jun 28, 2013 at 11:31 AM, Eric Elliott e...@ericleads.com wrote: I'm not here to discuss the mechanics of what class does. I'm just saying we shouldn't do it in the spec. There are better alternatives that pose less threat to the JavaScript ecosystem. A handful of libraries and JavaScript authors twisting prototypes to make them less useful is one thing. Getting a blessing from on-high for people to teach that it's how to do inheritance in JavaScript in teaching materials is quite another thing. It is how you do (single) inheritance in JS. In your OP, you say I think we should wait for some patterns to gain a foothold in the wild. Single inheritance via prototype chains is an immensely popular pattern for this kind of thing. You do qualify your statement by saying we should wait for *good* patterns, but single inheritance is perfectly good for some things, and adequate for quite a bit else. There are certainly better patterns, but none of them have gotten wide traction yet. We definitely want to pursue something like mixins in the future, but in ES6 we purposely went for a maximally minimal class syntax, adding as little as possible while still achieving the readability and usability gains of having a dedicated syntax. For example, when we come up with a good mixin pattern, adding it to the class syntax is as easy as doing class Foo mixin Bar, Baz, Qux {...}. No clash with extends; it just slots in cleanly. My arguments (and a few suggested alternatives) are in the video. If you're going to blow off what I have to say about it because you don't have time to watch a video, I guess the conversation is over. =) In our private conversation, I just asked for a text version, as it's several times faster to read text than listen to a talk. It would likely take you roughly as much time to write out the points you want us to take from the video as I, individually, would save by being able to read them instead of having to watch the video. When multiplied over the whole mailing list (or at least the people interested enough in this thread to care), the balance of time is clearly on the side of just spend the time writing out what you want to say. ~TJ ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re:
I've already invested significant time in trying to shed more light on this topic. In my book, in that video, in blog posts, and now here. Take your pick. The cliff notes for the lazy (with sketchnotes!) What I want to say has been said many times before: class inheritance causes problems that do not even need to exist in JavaScript. The Gang of Four considered this so important, that they made it one of two principles which are a central theme in the Design Patterns Book... but even the first principle is related, so I'll start there: Program to an interface, not an implementation, If you need a reference to the parent class in the implementation of the child class (the part that is expressed in the code of the language user), that is a violation of that principle. That is why super is considered to be a code smell. http://martinfowler.com/bliki/CallSuper.html and Favor composition over class inheritance. The reason for that is that deep inheritance hierarchies are too tightly coupled (child to parent), and too dependent on parent implementation (see above). These problems cause code arthritis as projects mature and you begin to inherit from sub-classes. Eventually that leads inevitably to brittleness, and the famed gorilla banana problem. The problem with object-oriented languages is they’ve got all this implicit environment that they carry around with them. You wanted a banana but what you got was a gorilla holding the banana and the entire jungle. - Joe Armstrong, Coders at Work Debugging such structures can be challenging. Changing them can force large, time consuming refactors, and in some cases, complete project rewrites. I've seen this happen in the real world again-and-again. Mostly in C++ and Java. When I came to JavaScript in the late 90's, it seemed like there was some relief from that. I just didn't see things like that happening very much... despite being involved in JavaScript-heavy serious applications for almost all of my career Until Backbone caught on and made .extend() the defacto way to reuse code in a very popular library. Then suddenly everybody started subclassing in JavaScript like it was a brand new idea. Then I started seeing those problems I thought we'd left behind resurface in real-world applications for companies producing apps with millions of users. Serious problems with major code bases in the wild... because people were running with a pattern that was never a good idea. It is a particularly bad idea in JavaScript primarily because using it is actually harder than using the better alternatives that already exist natively (notably a single prototype (not a userland chain), and dynamic object extension, which makes mixin implementations trivial). My argument is that it should *stay harder to implement*. Not only do we not need class, what we have is much easier, much more flexible, and dramatically less problematic. Some great alternatives to classes include modules (particularly those that export functions), factory functions, object literals, Object.create(), and simple dynamic object extension. You can combine all these and create some neat sugar that doesn't involve single-ancestor inheritance, tight coupling between parent and child, and encouraging users to think in a broken paradigm. More reading (if you can find the time): Sketchnotes - http://instagram.com/p/Z6ocvmRJSf/ Slideshow source - https://github.com/dilvie/fluent-prototypal-oo Blog post - http://ericleads.com/2013/02/fluent-javascript-three-different-kinds-of-prototypal-oo/ Different author, similar message - http://davidwalsh.name/javascript-objects (3 parts) - Eric Elliott On Fri, Jun 28, 2013 at 11:40 AM, Tab Atkins Jr. jackalm...@gmail.com wrote: On Fri, Jun 28, 2013 at 11:31 AM, Eric Elliott e...@ericleads.com wrote: I'm not here to discuss the mechanics of what class does. I'm just saying we shouldn't do it in the spec. There are better alternatives that pose less threat to the JavaScript ecosystem. A handful of libraries and JavaScript authors twisting prototypes to make them less useful is one thing. Getting a blessing from on-high for people to teach that it's how to do inheritance in JavaScript in teaching materials is quite another thing. It is how you do (single) inheritance in JS. In your OP, you say I think we should wait for some patterns to gain a foothold in the wild. Single inheritance via prototype chains is an immensely popular pattern for this kind of thing. You do qualify your statement by saying we should wait for *good* patterns, but single inheritance is perfectly good for some things, and adequate for quite a bit else. There are certainly better patterns, but none of them have gotten wide traction yet. We definitely want to pursue something like mixins in the future, but in ES6 we purposely went for a maximally minimal class syntax, adding as little as possible while still achieving the readability and usability gains
Re:
I would like to humbly submit that for every one time I've wished there was sugar for single inheritance (which, admittedly, I have), there are hundreds of instances in which sugar around duck typing would have been more beneficial. I realize that's a little bit apples and oranges, but I feel like it's worth stressing that in most real world applications there is more pain involved downstream of object creation than in the object creation itself. I have quite a few more thoughts on that topic, but as I fear this may qualify as a derailment, I'll hush up unless there's more interest in going there. :-) On Fri, Jun 28, 2013 at 4:14 PM, Eric Elliott e...@ericleads.com wrote: I've already invested significant time in trying to shed more light on this topic. In my book, in that video, in blog posts, and now here. Take your pick. The cliff notes for the lazy (with sketchnotes!) What I want to say has been said many times before: class inheritance causes problems that do not even need to exist in JavaScript. The Gang of Four considered this so important, that they made it one of two principles which are a central theme in the Design Patterns Book... but even the first principle is related, so I'll start there: Program to an interface, not an implementation, If you need a reference to the parent class in the implementation of the child class (the part that is expressed in the code of the language user), that is a violation of that principle. That is why super is considered to be a code smell. http://martinfowler.com/bliki/CallSuper.html and Favor composition over class inheritance. The reason for that is that deep inheritance hierarchies are too tightly coupled (child to parent), and too dependent on parent implementation (see above). These problems cause code arthritis as projects mature and you begin to inherit from sub-classes. Eventually that leads inevitably to brittleness, and the famed gorilla banana problem. The problem with object-oriented languages is they’ve got all this implicit environment that they carry around with them. You wanted a banana but what you got was a gorilla holding the banana and the entire jungle. - Joe Armstrong, Coders at Work Debugging such structures can be challenging. Changing them can force large, time consuming refactors, and in some cases, complete project rewrites. I've seen this happen in the real world again-and-again. Mostly in C++ and Java. When I came to JavaScript in the late 90's, it seemed like there was some relief from that. I just didn't see things like that happening very much... despite being involved in JavaScript-heavy serious applications for almost all of my career Until Backbone caught on and made .extend() the defacto way to reuse code in a very popular library. Then suddenly everybody started subclassing in JavaScript like it was a brand new idea. Then I started seeing those problems I thought we'd left behind resurface in real-world applications for companies producing apps with millions of users. Serious problems with major code bases in the wild... because people were running with a pattern that was never a good idea. It is a particularly bad idea in JavaScript primarily because using it is actually harder than using the better alternatives that already exist natively (notably a single prototype (not a userland chain), and dynamic object extension, which makes mixin implementations trivial). My argument is that it should *stay harder to implement*. Not only do we not need class, what we have is much easier, much more flexible, and dramatically less problematic. Some great alternatives to classes include modules (particularly those that export functions), factory functions, object literals, Object.create(), and simple dynamic object extension. You can combine all these and create some neat sugar that doesn't involve single-ancestor inheritance, tight coupling between parent and child, and encouraging users to think in a broken paradigm. More reading (if you can find the time): Sketchnotes - http://instagram.com/p/Z6ocvmRJSf/ Slideshow source - https://github.com/dilvie/fluent-prototypal-oo Blog post - http://ericleads.com/2013/02/fluent-javascript-three-different-kinds-of-prototypal-oo/ Different author, similar message - http://davidwalsh.name/javascript-objects (3 parts) - Eric Elliott On Fri, Jun 28, 2013 at 11:40 AM, Tab Atkins Jr. jackalm...@gmail.com wrote: On Fri, Jun 28, 2013 at 11:31 AM, Eric Elliott e...@ericleads.com wrote: I'm not here to discuss the mechanics of what class does. I'm just saying we shouldn't do it in the spec. There are better alternatives that pose less threat to the JavaScript ecosystem. A handful of libraries and JavaScript authors twisting prototypes to make them less useful is one thing. Getting a blessing from on-high for people to teach that it's how to do inheritance in JavaScript in teaching materials is
Re:
Hi Eric, Le 28/06/2013 19:42, Eric Elliott a écrit : I know this has been batted around already. Has it? :-p I know everybody's totally stoked about class sugar in ES6. I just wanted to register my protest. I made my arguments in this talk at Fluent: http://ericleads.com/2013/06/classical-inheritance-is-obsolete-how-to-think-in-prototypal-oo/ Adding the class keyword into JavaScript does not mean adding all the constructs that Java has and all the problems that come along. Given the *current* ES6 class proposal, what issues do you see that would affect code maintainability? I'm already seeing nasty codebase arthritis creep into JavaScript projects thanks to things like Backbone.View.extend() being essentially mandatory. Don't use Backbone? Can you expand on an example of what you call nasty codebase arthritis using Backbone? Providing sugar to extend classes in JavaScript proper is like officially sanctioning that nonsense. I'm not the only one who feels that way. Here's an excerpt from one viewer's comment on my presentation: I think this will only get worse with ES6 and I am rather upset about it. While 'class' will be elective of course, I can only imagine more and more libraries adopting the ES6 class pattern, and then we will wind up facing the same set of challenges that exist in the Java world. ES6 classes will desugar at runtime into JavaScript objects as we know them. How does the introduction of ES6 classes bring challenges that don't already exist in JS? Please be specific and provide examples. Having two keywords in common (class and extends) doesn't mean issues in one language will shift to the other. Also, having a new syntax sugar doesn't take anything off of the language; solutions of yesterday will work tomorrow. In my opinion, the clamoring for class in JavaScript is because JavaScript tries to hide prototypes, rather than make it easy to deal with them. Not sure where you got that from. It's been a very clear goal to make ES6 classes desugar into objects as we know them. This constraint causes some headaches (semantics of upcoming private keyword comes to mind :-) ), but everyone I've read from on that list stands by this constraint. Instead of class, we should let library authors continue to experiment with other inheritance patterns in JavaScript. Here's an example: https://github.com/dilvie/stampit We do need a bit more object sugar in JS, but I think we should wait for some patterns to gain a foothold in the wild, and only when popular patterns emerge and have time to be tested and proven to be well-thought-out and a valuable addition (unlike Backbone's .extend(), which is causing lots of problems in the real world), only THEN should the idea be blessed by the specification. The author experimentation can happen even if there is a class syntax in the language. Is class a good idea in JavaScript? I say, prove it. In fact, anything that can have a reference implementation should be proven - not just by implementing it to see if it can work, but if it can be polyfilled (or something like it could be polyfilled), put it in a library and see if it catches on before you add it to the spec, and everybody starts to write about it in their new JavaScript features posts. I'm just someone sending emails, but what you're describing (prototype features in libraries and spec what catches on) is how I have observed TC39 working. Function.prototype.bind comes from that (jQuery, underscore). Array functional methods (jQuery each, SpiderMonkey). Arrow functions (CoffeeScript). Promises!! I think examples of ES5/6 picking things that have proven to work are numerous. Polyfillability is good if possible, but shouldn't be a goal. Some things lack in the language semantics. Those are usually things you can't polyfill. So far, NO IMPLEMENTATION of class in JavaScript has become a de-facto standard. I think we should set the bar a little higher where a new feature could actually cause damage to the language ecosystem. Lots of people have been asking for classes, lots of terrible libraries trying to emulate what can be done in Java have been implemented. And Backbone.extends now. And many others to come. ES6 is coming up with a class syntax that will satisfy these people and desugars to ES5 runtime semantics. That's a good tradeoff in my opinion. I'm not very interested in the classical vs prototypal battle. Both are barely different mechanisms of specialization. At the pace we're at, the class syntax will make it into ES6. People want it, they will have some form of it, that's inevitable. It's in TypeScript and CoffeeScript; even if it wasn't in the core language, you'll have to deal with codebases using classes in the future. I'm however very interested if you could take a look at the current proposal and tell if you can pin down how the current proposal makes classes harmful for code maintainability. Thanks, David
Re:
I'm not very interested in the classical vs prototypal battle. Both are barely different mechanisms of specialization. I couldn't disagree with that more strongly. Just because you can mimic class easily with prototypes doesn't make them barely different. If you're not interested in that conversation, you can safely ignore everything else I have to say, because you've effectively blown it off. Stick your head in the sand if you like. The problem doesn't go away. I'm however very interested if you could take a look at the current proposal and tell if you can pin down how the current proposal makes classes harmful for code maintainability. Basically, my argument is that the whole paradigm of a class with a single ancestor, and any mention of that ancestor in the implementation of the child (referring to the parent in the constructor, for instance), is fundamentally flawed and problematic. `extends` harms code maintainability by virtue of creating the brittle hierarchy / gorilla-banana problem I've already described. The problem isn't how it's done in JavaScript or ES6. The problem is that it's done at all. Class gets people thinking in a fundamentally broken paradigm for good OO design. I saw a recent example of one of the problems with single-ancestor inheritance in a talk. I wish I could remember which one. The illustrations were great: Animal - Walking - Monkey - Human - Flying - Bird - Bee - Swimming - Fish - Whale Now we need alligator and duck. I understand that JavaScript doesn't restrict you from doing things like mixins as well... but when you're 14 months into a project, and THEN you have to add the alligator, suddenly you're mixing paradigms in ways that diverge significantly from the style of the rest of the code base. At this point, the code is already arthritic and brittle. Fitting these things in at this point is a lot less trivial. If you're relying on things like super in the rest of the code, how does the new stuff properly invoke the constructors of multiple ancestors which are designed to be single ancestors? I can tell you how I've seen these situations handled in the real world, virtually everywhere the problem has cropped up (pretty much everywhere that class was relied on heavily). Massive refactors. Code rewrites. Lots of wasted time. Class sugar might save developers a few keystrokes today, but it will come back to bite them hard later. Lots of people are paying for Backbone's .extend(). If it added value, that would be one thing. But it doesn't actually do anything that couldn't have been done just by replacing it with a constructor that produced objects that could be passed into those constructors to produce new objects. I have seen the problems in code at Adobe, at Tout, and at BandPage (my last three jobs, that all used Backbone). The problem isn't with Backbone's particular implementation. I had the same problems in C++, Java, and with John Resig's Simple Inheritance in JavaScript. The problem isn't with the ES6 implementation. It's the whole paradigm. - Eric On Fri, Jun 28, 2013 at 2:27 PM, David Bruant bruan...@gmail.com wrote: Hi Eric, Le 28/06/2013 19:42, Eric Elliott a écrit : I know this has been batted around already. Has it? :-p I know everybody's totally stoked about class sugar in ES6. I just wanted to register my protest. I made my arguments in this talk at Fluent: http://ericleads.com/2013/06/classical-inheritance-is-obsolete-how-to-think-in-prototypal-oo/ Adding the class keyword into JavaScript does not mean adding all the constructs that Java has and all the problems that come along. Given the *current* ES6 class proposal, what issues do you see that would affect code maintainability? I'm already seeing nasty codebase arthritis creep into JavaScript projects thanks to things like Backbone.View.extend() being essentially mandatory. Don't use Backbone? Can you expand on an example of what you call nasty codebase arthritis using Backbone? Providing sugar to extend classes in JavaScript proper is like officially sanctioning that nonsense. I'm not the only one who feels that way. Here's an excerpt from one viewer's comment on my presentation: I think this will only get worse with ES6 and I am rather upset about it. While 'class' will be elective of course, I can only imagine more and more libraries adopting the ES6 class pattern, and then we will wind up facing the same set of challenges that exist in the Java world. ES6 classes will desugar at runtime into JavaScript objects as we know them. How does the introduction of ES6 classes bring challenges that don't already exist in JS? Please be specific and provide examples. Having two keywords in common (class and extends) doesn't mean issues in one language will shift to the other. Also, having a new syntax sugar doesn't take anything off of the language; solutions of yesterday will work tomorrow. In my opinion, the
Re:
Le 29/06/2013 00:14, Eric Elliott a écrit : I'm however very interested if you could take a look at the current proposal and tell if you can pin down how the current proposal makes classes harmful for code maintainability. Basically, my argument is that the whole paradigm of a class with a single ancestor, and any mention of that ancestor in the implementation of the child (referring to the parent in the constructor, for instance), is fundamentally flawed and problematic. `extends` harms code maintainability by virtue of creating the brittle hierarchy / gorilla-banana problem I've already described. The problem isn't how it's done in JavaScript or ES6. The problem is that it's done at all. Class gets people thinking in a fundamentally broken paradigm for good OO design The rest of JavaScript remains. ES6 classes are just a sugar on top of the ES5 runtime concepts (objects with [[Prototype]], [[Get]], [[Set]], etc.). People already think in a broken way when it comes to software. Software is hard. Lots of people model data inside strings. I believe this is a much bigger problem than classes. What's the solution for stringly typed code? I saw a recent example of one of the problems with single-ancestor inheritance in a talk. I wish I could remember which one. I believe it was this talk by Angus Croll https://speakerdeck.com/anguscroll/the-why-and-how-of-mixins-in-flight The illustrations were great: Animal - Walking - Monkey - Human - Flying - Bird - Bee - Swimming - Fish - Whale Now we need alligator and duck. I understand that JavaScript doesn't restrict you from doing things like mixins as well... but when you're 14 months into a project, and THEN you have to add the alligator, suddenly you're mixing paradigms in ways that diverge significantly from the style of the rest of the code base. At this point, the code is already arthritic and brittle. Fitting these things in at this point is a lot less trivial. Classes and the single-ancestor pattern are limited in the sort of objects they can model. Animals are such an example. But you can model other simpler things that don't have properties that cross over. Classes can work for these cases. I believe that these cases are numerous and classes can work for them. Classical inheritance is a problem when that's the only tool you have. But if you have a decent understanding of what you're trying to model, you can use classes when that fits and other more appropriate mechanisms when they're available. The very tool you use to model something can already be of help to others to understand the shape of what you're modeling. If you're relying on things like super in the rest of the code, how does the new stuff properly invoke the constructors of multiple ancestors which are designed to be single ancestors? Does the ES6 super has the same issue than the Java one? I really don't feel I have enough expertise in the matter to say yet. I can tell you how I've seen these situations handled in the real world, virtually everywhere the problem has cropped up (pretty much everywhere that class was relied on heavily). Massive refactors. Code rewrites. Lots of wasted time. Yes, when the wrong tool is used for a job, people pay it later. It also happens in JavaScript. In my experience, it's often more a problem of not understanding your model enough when first writing the code. In my experience again, it's hard to plan everything in advance and choosing class or not class is rarely the heart of the problem when you've mis-modeled your software. Class sugar might save developers a few keystrokes today, but it will come back to bite them hard later. Lots of people are paying for Backbone's .extend(). If it added value, that would be one thing. But it doesn't actually do anything that couldn't have been done just by replacing it with a constructor that produced objects that could be passed into those constructors to produce new objects. This sort of argument leads us nowhere. By that argument, we can remove maybe 70% of the JS built-ins. All the Math functions and constants can go, all Array.prototype algorithms... Object.create isn't even necessary if you have functions and 'new', etc. Classes offer a nice sugar to cover *some* use cases, *some* modelisation cases. Among expert-enough people, using classes may become the sign of simple models (when there is no need for specialization) or simple specialization patterns. That's a good thing. It's not big, but it's a good thing. I have seen the problems in code at Adobe, at Tout, and at BandPage (my last three jobs, that all used Backbone). I would be interested in see code samples describing your problem. I do believe you and I agree with you by intuition, but I would love to have a fully-fleshed example to study it and fully understand it to understand if some code maintainability issues. The problem isn't with Backbone's
Re:
Eric - On class-based inheritance Gang of Four says prefer composition to inheritance, not avoid inheritance altogether. As you suggest near the end of your last reply, you can use composition or injection with any of those constructors in the inheritance hierarchy to add or override behavior. It does not follow that we should never use an inheritance hierarchy for generally shared or default behavior. If the argument is against the class extends super syntax in ES6, I agree it's not necessary in ES. But as others have pointed out, it's an opt-in feature that we won't be forced to use (big thank you to everyone for supporting backward compatibility). As David Bruant noted, some prefer not to use Object.create() and just use new function() instead (I'm one of them - I'm guilty). If the argument is against them in all cases, we still have to use care with mixins (see ActiveRecord for an extreme case) and interfaces, etc., as even a change to a trait or interface can have consequences downstream. Out here in Userland I've seen the same pathology you describe in several codebases - it also happens with CSS descendant rules and id selectors, !important rules and inline style attributes to override them *this one time*. But, I haven't seen coupling as a *problem* with inheritance per se so much as that a constructor is doing *any* work at all - by which I mean side-effects - which is an argument for using Object.create - which I now note with irony. The one thing that saved us from dread of *OMG we have to re-visit everything* has been reliance on unit tests - test-driven-development, or test-during-development really does reduce the fear of later confusion - but that's another discussion entirely. Sorry for preaching to the choir and/or ruffling feathers DFKaye From: David Bruant bruan...@gmail.com To: Eric Elliott e...@ericleads.com Cc: es-discuss es-discuss@mozilla.org Sent: Friday, June 28, 2013 3:55 PM Subject: Re: Le 29/06/2013 00:14, Eric Elliott a écrit : I'm however very interested if you could take a look at the current proposal and tell if you can pin down how the current proposal makes classes harmful for code maintainability. Basically, my argument is that the whole paradigm of a class with a single ancestor, and any mention of that ancestor in the implementation of the child (referring to the parent in the constructor, for instance), is fundamentally flawed and problematic. `extends` harms code maintainability by virtue of creating the brittle hierarchy / gorilla-banana problem I've already described. The problem isn't how it's done in JavaScript or ES6. The problem is that it's done at all. Class gets people thinking in a fundamentally broken paradigm for good OO design The rest of JavaScript remains. ES6 classes are just a sugar on top of the ES5 runtime concepts (objects with [[Prototype]], [[Get]], [[Set]], etc.). People already think in a broken way when it comes to software. Software is hard. Lots of people model data inside strings. I believe this is a much bigger problem than classes. What's the solution for stringly typed code? I saw a recent example of one of the problems with single-ancestor inheritance in a talk. I wish I could remember which one. I believe it was this talk by Angus Croll https://speakerdeck.com/anguscroll/the-why-and-how-of-mixins-in-flight The illustrations were great: Animal - Walking - Monkey - Human - Flying - Bird - Bee - Swimming - Fish - Whale Now we need alligator and duck. I understand that JavaScript doesn't restrict you from doing things like mixins as well... but when you're 14 months into a project, and THEN you have to add the alligator, suddenly you're mixing paradigms in ways that diverge significantly from the style of the rest of the code base. At this point, the code is already arthritic and brittle. Fitting these things in at this point is a lot less trivial. Classes and the single-ancestor pattern are limited in the sort of objects they can model. Animals are such an example. But you can model other simpler things that don't have properties that cross over. Classes can work for these cases. I believe that these cases are numerous and classes can work for them. Classical inheritance is a problem when that's the only tool you have. But if you have a decent understanding of what you're trying to model, you can use classes when that fits and other more appropriate mechanisms when they're available. The very tool you use to model something can already be of help to others to understand the shape of what you're modeling. If you're relying on things like super in the rest of the code, how does the new stuff properly invoke the constructors of multiple ancestors which are designed to be
Re:
The rest of JavaScript remains. ES6 classes are just a sugar on top of the ES5 runtime concepts (objects with [[Prototype]], [[Get]], [[Set]], etc.). When class is blessed by the spec, many people will interpret it as the default way that objects are created and inheritance is done in JavaScript. I see that as a sad outcome for the JavaScript community. Perhaps temporarily convenient for people from a classical background -- temporarily, but in the long run, they are not served by it. My question to you is this: Does class bring value to JavaScript that is currently missing? People already think in a broken way when it comes to software. Software is hard. Lots of people model data inside strings. I believe this is a much bigger problem than classes. What's the solution for stringly typed code? What you want for a good UX (yes, programming languages have UX) is a pit of success -- where people do the right thing by default. A `class` keyword gives people a pit of dispair... where it's very easy to fall into doing the wrong thing by default. Instead of class sugar, we need sugar around less problematic forms of code reuse. http://www.codinghorror.com/blog/2007/08/falling-into-the-pit-of-success.html There's good reason that class hierarchy problems have always been so common in C++ and Java, but were almost non-existent in JavaScript until very recently -- and it's not just because people are only just now using JavaScript to build large applications. Some of us have been doing that since the 90's. JavaScript's prototypal inheritance is a pit of success. Class is a pit of dispair. Classes and the single-ancestor pattern are limited in the sort of objects they can model. Animals are such an example. But you can model other simpler things that don't have properties that cross over. Classes can work for these cases. Yes, classes are limited. Unfortunately, most developers don't see the limitations coming, and that's the crux of the problem. Counting on them to foresee problems coming when requirements are constantly changing is a losing strategy. Can you give me examples of where `class` adds enough value to make up for all its shortcomings, or is it really just a bit of sugar to help developers avoid typing a little more? By that argument, we can remove maybe 70% of the JS built-ins. Except that most built-ins in JavaScript add significant value *without* adding significant danger that can cost developers months in refactors and rewrites. Among expert-enough people, using classes may become the sign of simple models (when there is no need for specialization) or simple specialization patterns. That's a good thing. It's not big, but it's a good thing. A very simple factory abstraction can do the same -- and it doesn't require expert-enough people, and it's much more flexible and capable (see stampit, for example https://github.com/dilvie/stampit ). Again - without the danger that comes with `class`. Does the ES6 super has the same issue than the Java one? I really don't feel I have enough expertise in the matter to say yet. Yes. `super()` is problematic because you have to remember to call it, or remember not to call it, or even think about whether or not you should be calling it. If there are instantiation details that need to be handled, they should be hooked so that they happen automatically. There are several good patterns for that. stampit() automatically adds init methods to a callback queue and guarantees that they all run automatically. The developer doesn't need to think about it. Init hooks can completely replace the need for `super()`. I haven't called `super()` on anything since ... 2010? And I code large JavaScript applications every day for a living. Feels great to be liberated from it. choosing class or not class is rarely the heart of the problem when you've mis-modeled your software. It's a lot harder to mismodel your software when your objects are composed, rather than relying on brittle class inheritance structures. That's the whole reason you should favor composition over class inheritance. Want to fix class in ES6? Call it something else, replace extends with mixin, remove super, and allow any number of init functions to be added, rather than relying on a single constructor. No, the problem is when people limit the way they think about software through this only one paradigm. If this paradigm is here alongside others, I don't see the problem. People have the choice. JavaScript is confusing enough to people without adding `class`. Sometimes giving people more choice is a bad thing: http://www.amazon.com/The-Paradox-Choice-More-Less/dp/0060005696 - Eric On Fri, Jun 28, 2013 at 3:55 PM, David Bruant bruan...@gmail.com wrote: Le 29/06/2013 00:14, Eric Elliott a écrit : I'm however very interested if you could take a look at the current proposal and tell if you can pin down how the current proposal makes classes harmful for code maintainability. Basically,
Re:
Gang of Four says prefer composition to inheritance, not avoid inheritance altogether. That wasn't such an easy choice in Java or C++. It's a down-right trivial choice in JavaScript. As you suggest near the end of your last reply, you can use composition or injection with any of those constructors in the inheritance hierarchy to add or override behavior. When you're working in an established codebase, it's much harder to go against the grain of momentum than your reply suggests. For example, project x had been using Backbone.View.extend(), and has a 6-generation class hierarchy. Now the root level's constructor function is doing something that the youngest child needs to override -- but every other ancestor relies on that functionality, and the youngest relies on functionality of its ancestors in-between. (This was an actual situation in an actual codebase with over 100,000 lines of client-side JavaScript). Since all the descendant classes relied on the implementation of the ancestors (through .super() calls), the mess was not easy to detangle. It wasn't simply a matter of grafting some stuff on to an object after the fact. Single-parent hierarchies make it hard to do selective inheritance. (I refer you again to the gorilla banana problem). If the code had relied less on sub-classing views, and more on mixins, this problem never would have come up. Rely on an interface, not an implementation - violated by sublassing and super(). If the argument is against the class extends super syntax in ES6, I agree it's not necessary in ES. But as others have pointed out, it's an opt-in feature that we won't be forced to use See the pit of dispair vs pit of success argument I made in my last reply. I haven't seen coupling as a *problem* withinheritance per se so much as that a constructor is doing *any* work at all - by which I mean side-effects I could not agree more about avoiding side-effects, but inheritance (even without instantiation side-effects) still suffers from other problems. Notably the specialization problem of single-ancestor inheritance, which leads to collections of similar objects with unexpectedly divergent properties. Composition / mixins give you easy selective inheritance. (See also, the gorilla banana argument). Yes, you can selectively inherit by copying properties, but not if your constructors are used for private state (which is often a good thing -- it allows you to hide implementation details so that users of your API can program to your interface, not your implementation). If you're using patterns like the ones found in Stampit, you don't have that problem, either. - Eric On Fri, Jun 28, 2013 at 5:07 PM, david kaye dfk...@yahoo.com wrote: Eric - On class-based inheritance Gang of Four says prefer composition to inheritance, not avoid inheritance altogether. As you suggest near the end of your last reply, you can use composition or injection with any of those constructors in the inheritance hierarchy to add or override behavior. It does not follow that we should never use an inheritance hierarchy for generally shared or default behavior. If the argument is against the class extends super syntax in ES6, I agree it's not necessary in ES. But as others have pointed out, it's an opt-in feature that we won't be forced to use (big thank you to everyone for supporting backward compatibility). As David Bruant noted, some prefer not to use Object.create() and just use new function() instead (I'm one of them - I'm guilty). If the argument is against them in all cases, we still have to use care with mixins (see ActiveRecord for an extreme case) and interfaces, etc., as even a change to a trait or interface can have consequences downstream. Out here in Userland I've seen the same pathology you describe in several codebases - it also happens with CSS descendant rules and id selectors, !important rules and inline style attributes to override them *this one time*. But, I haven't seen coupling as a *problem* with inheritance per se so much as that a constructor is doing *any* work at all - by which I mean side-effects - which is an argument for using Object.create - which I now note with irony. The one thing that saved us from dread of *OMG we have to re-visit everything* has been reliance on unit tests - test-driven-development, or test-during-development really does reduce the fear of later confusion - but that's another discussion entirely. Sorry for preaching to the choir and/or ruffling feathers DFKaye -- *From:* David Bruant bruan...@gmail.com *To:* Eric Elliott e...@ericleads.com *Cc:* es-discuss es-discuss@mozilla.org *Sent:* Friday, June 28, 2013 3:55 PM *Subject:* Re: Le 29/06/2013 00:14, Eric Elliott a écrit : I'm however very interested if you could take a look at the current proposal and tell if you can pin down how the current proposal makes classes harmful for code
Re:
Le 29 juin 2013 à 00:14, Eric Elliott e...@ericleads.com a écrit : snip I saw a recent example of one of the problems with single-ancestor inheritance in a talk. I wish I could remember which one. The illustrations were great: Animal - Walking - Monkey - Human - Flying - Bird - Bee - Swimming - Fish - Whale Now we need alligator and duck. Interesting challenge! It may be hard to resolve in some languages, but in JavaScript, you merely need some imagination. Given: ```js class Flying extends Animal { // implementation of Flying } class Swimming extends Animal { // implementation of Swimming } ``` it could be quickly refactored as following (I assume that the implementation of Swimming is sufficiently well-written; otherwise some amendments in its implementation might be needed): ```js class Flying extends Animal { // implementation of Flying } function addSwimming(Animal) { class Swimming extends Animal { // implementation of Swimming } return Swimming } var Swimming = addSwimming(Animal) var FlyingSwimming = addSwimming(Flying) class Duck extends FlyingSwiming { } ``` (It is true that `Duck instanceof Swimming` doesn't hold; however, duck-typing forbids the use of `instanceof` and even any typelike-check.) Note how JavaScript remains dynamic, even in the face of the ES6-class-sugar. —Claude___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss