Re: Minimalist (why) classes ?
On Sun, Nov 13, 2011 at 9:49 PM, Brendan Eich bren...@mozilla.com wrote: On Nov 13, 2011, at 9:42 PM, Irakli Gozalishvili wrote: I think this discussion drifted into slightly diff direction. What I intended to say was that today all major frameworks use same patter to do subclassing. They all implement different APIs to do the following: function subclass() { // init …. } subclass.prototype = Object.create(superclass) Object.defineProperty(subclass.prototype, 'constructor', { value: subclass }) subclass.prototype.method = function() { //... } Yes, this is the heart of the matter. Not freezing, not shallow vs. deep property copying (where deep must deal with closures at least). Sorry I don't understand. Every function which accepts object references and embeds its arguments in [[Prototype]] (either in the return value or the instance created from the return value) faces the copy-ish problem. As I understand it, this is part of (or all of) the reason Allen's setPrototypeOf ( | ) operator only allows a literal on the right hand side. How can this be avoided? Object.extend used in my gist is BTW same as backbone's .extend Ok, good to know. (Jashkenas, you didn't propose it!) and is just a shortcut of the code above: var subclass = superclass.extend({ initialize: function() { // init ... }, method: function() { // …. } }) What I'm asking for is a standard function, no matter weather it's `Object.extend` or something else that makes it simple to do subclassing. Allen has been trying to make it be a combo of | and .{. Agree there could be a method, say Object.subclass (what a concept!). As soon as I call var a = b.subclass(d, e); we have to define what happens to |d| and |e|. Isn't that exactly what we have been discussing? jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Minimalist (why) classes ?
On Mon, Nov 14, 2011 at 11:48 AM, John J Barton johnjbar...@johnjbarton.com wrote: [snip] Sorry I don't understand. Every function which accepts object references and embeds its arguments in [[Prototype]] (either in the return value or the instance created from the return value) faces the copy-ish problem. This is a negligent conflation. Pass by reference is not the same as ensuring that when extending one object with another, the resulting object is not implicitly capable of mutating its source objects (as is the case in Selfish). In Prototype.js's Object.extend(), the behaviour is even worse: // Object.extend from prototype.js function extend(destination, source) { for (var property in source) destination[property] = source[property]; return destination; } var defaults = { config: { a: alpha, b: beta } }; function F( options ) { this.settings = extend( defaults, options ); } var f = new F({ config: { a: DESTROYED } }); console.log( defaults.config.a ); // DESTROYED Whoops! Now my `defaults` have been changed. If I had other functions relying on that object, everything becomes chaos. It's important to remember that Prototype.js has very little developer mindshare these days and should absolutely not be used as source material for spec reification. The tests I wrote for Selfish illustrate that it also has this behaviour, but is more deceiving because you think you're getting new instances. Rick ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Minimalist (why) classes ?
On Mon, Nov 14, 2011 at 10:42 AM, Rick Waldron waldron.r...@gmail.com wrote: On Mon, Nov 14, 2011 at 11:48 AM, John J Barton johnjbar...@johnjbarton.com wrote: [snip] Sorry I don't understand. Every function which accepts object references and embeds its arguments in [[Prototype]] (either in the return value or the instance created from the return value) faces the copy-ish problem. This is a negligent conflation. Ouch, that sounds really bad! Except I don't understand what you mean ;-) Pass by reference is not the same as ensuring that when extending one object with another, the resulting object is not implicitly capable of mutating its source objects (as is the case in Selfish). I don't understand this sentence. I guess you mean: The issues of extend() is not related to pass by reference vs pass by value. If so, I disagree. If extend() only allows object literals as arguments then you don't have to copy, deep or shallow. That's how syntax like Allen's | avoids the copy problem. But extend() can't limit its arguments to object literals. So it must deal with copy. Am I wrong? jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Minimalist (why) classes ?
On Nov 14, 2011, at 8:48 AM, John J Barton wrote: On Sun, Nov 13, 2011 at 9:49 PM, Brendan Eich bren...@mozilla.com wrote: On Nov 13, 2011, at 9:42 PM, Irakli Gozalishvili wrote: I think this discussion drifted into slightly diff direction. What I intended to say was that today all major frameworks use same patter to do subclassing. They all implement different APIs to do the following: function subclass() { // init …. } subclass.prototype = Object.create(superclass) Object.defineProperty(subclass.prototype, 'constructor', { value: subclass }) subclass.prototype.method = function() { //... } Yes, this is the heart of the matter. Not freezing, not shallow vs. deep property copying (where deep must deal with closures at least). Sorry I don't understand. I was agreeing with Irakli that subclass/superclass wiring is primal to classes. How one composes properties from various source objects is a different issue, not directly addressed by class syntax (yet). It is addressed by http://traitsjs.org/ and you can use an expression in the superclass position in the class head: class D extends Trait.create(...) {...}. Every function which accepts object references and embeds its arguments in [[Prototype]] (either in the return value or the instance created from the return value) faces the copy-ish problem. Irakli was suggesting separating that from setting [[Prototype]] of a new subclass prototype object created at the same time, with constructor wired appropriately. That's what class syntax does at minimum. You keep bringing in various extend alternatives, but these are separate from classes. Yes, even in the case when the class body is non-empty: in that event the elements define properties on the new class prototype object, which shadow any properties on the base class prototype object. Shadow, not copy. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Minimalist (why) classes ?
On Monday, 2011-11-14 at 10:42 , Rick Waldron wrote: The tests I wrote for Selfish illustrate that it also has this behaviour, but is more deceiving because you think you're getting new instances. Hey Rick, I'd be interested to see those tests since it's not supposed to mutate any arguments passed to it, and if that's a case it's a bug and I'd like to fix it. Thanks! ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Minimalist (why) classes ?
Irakli, pull request for the tests: https://github.com/Gozala/selfish/pull/1 On Mon, Nov 14, 2011 at 2:52 PM, Irakli Gozalishvili rfo...@gmail.comwrote: On Monday, 2011-11-14 at 10:42 , Rick Waldron wrote: The tests I wrote for Selfish illustrate that it also has this behaviour, but is more deceiving because you think you're getting new instances. Hey Rick, I'd be interested to see those tests since it's not supposed to mutate any arguments passed to it, and if that's a case it's a bug and I'd like to fix it. Thanks! ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Minimalist (why) classes ?
You keep bringing in various extend alternatives, but these are separate from classes. Yes, even in the case when the class body is non-empty: in that event the elements define properties on the new class prototype object, which shadow any properties on the base class prototype object. Shadow, not copy. Apologies if I was unclear; I was originally responding to you... Let's argue about specifics or we'll get nowhere. Do you think Irakli's selfish.js extend (https://github.com/Gozala/selfish/blob/master/selfish.js) is the way to go, or Prototype's quite different form? /be Rick /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: Minimalist (why) classes ?
On Nov 14, 2011, at 12:16 PM, Rick Waldron wrote: You keep bringing in various extend alternatives, but these are separate from classes. Yes, even in the case when the class body is non-empty: in that event the elements define properties on the new class prototype object, which shadow any properties on the base class prototype object. Shadow, not copy. Apologies if I was unclear; I was originally responding to you... Let's argue about specifics or we'll get nowhere. Do you think Irakli's selfish.js extend (https://github.com/Gozala/selfish/blob/master/selfish.js) is the way to go, or Prototype's quite different form? I did write that, and the specifics help (it's es-discuss), even when they go into a tangent or separate issue. But Irakli's message about inheritance via prototype wiring got me thinking that the crucial issue for classes (right now) is not composition, but prototypal inheritance. The super issue was handled separately but works in classes. But apart from | and some manual subcass-prototype construction and .constructor setting, we don't have a primitive for class inheritance as prototypal delegation -- that is, not one other than minimal classes. Again I'm not saying the issue John wants to hash out (which is hydra-headed) is unimportant or anything like that. Indeed some of us (Alex, Dave, Brendan, Allen) think Traits are excellent. But do they need syntax, or just de-jure codification as built-in library code after de-facto standardization? I think the latter. Remember, traitsjs.org is rather freeze-gun happy (Dr. Freeze!) and when it was proposed way back in March 2010 to TC39, we talked about less frosty alternatives. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Minimalist (why) classes ?
But do they need syntax, or just de-jure codification as built-in library code after de-facto standardization? I think the latter. Thanks for the clarification; when that discussion comes, I'll revive my points. Rick ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Minimalist (why) classes ?
On Fri, Nov 11, 2011 at 7:31 PM, Brendan Eich bren...@mozilla.com wrote: Class syntax is wanted to avoid some method calling boilerplate that's more verbose, arguably easier to get wrong, and harder to analyze and optimize. That's it. Hence, classes as sugar. If you find existing JS sweet enough, you won't want classes. /be I believe that the biggest advantage of a standard blessed way of declaring classes would be that it would become much easier to read each others code. For example: an experienced Java developer has spent thousands of hours staring at code that follows a standardized top-level pattern, and they have built up the specialized neural machinery that allows them to (for example) grok the top level structure of a class at a glance. (In much the same way that an expert chess player can see in a glance what a less experienced player would have to work out over minutes - or would never see at all). In current JS practice, almost every program uses a different way of defining the top level structures such as modules, classes, methods and so on - in an important sense every JS program is written in a somewhat different language, and is alien to everyone but it's author. - Regards David Ziegler d...@mudchicken.com ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Minimalist (why) classes ?
On Mon, Nov 14, 2011 at 11:51 AM, Brendan Eich bren...@mozilla.com wrote: On Nov 14, 2011, at 8:48 AM, John J Barton wrote: On Sun, Nov 13, 2011 at 9:49 PM, Brendan Eich bren...@mozilla.com wrote: On Nov 13, 2011, at 9:42 PM, Irakli Gozalishvili wrote: I think this discussion drifted into slightly diff direction. What I intended to say was that today all major frameworks use same patter to do subclassing. They all implement different APIs to do the following: function subclass() { // init …. } subclass.prototype = Object.create(superclass) Object.defineProperty(subclass.prototype, 'constructor', { value: subclass }) subclass.prototype.method = function() { //... } Yes, this is the heart of the matter. Not freezing, not shallow vs. deep property copying (where deep must deal with closures at least). Sorry I don't understand. I was agreeing with Irakli that subclass/superclass wiring is primal to classes. Irakli proposes a function; you are discussing classes. So perhaps rather than agreeing with Irakli you are drawing a parallel: you like the object created by Irakli's extend() and wish to take that into the class discussion? That's all fine. But I am focusing on the function vs (class) syntax issue. That is where Irakli's (why) classes comes from. How one composes properties from various source objects is a different issue, not directly addressed by class syntax (yet). It is addressed by http://traitsjs.org/ and you can use an expression in the superclass position in the class head: class D extends Trait.create(...) {...}. If we compare a |class| syntax class D extends B adds P; to Irakli's extend, we write: var D = B.extend(P); If both B and P can be expressions, then the forms are equivalent. That is, both forms have to come up with an answer for how the B and P are used in creating D. Every function which accepts object references and embeds its arguments in [[Prototype]] (either in the return value or the instance created from the return value) faces the copy-ish problem. Irakli was suggesting separating that from setting [[Prototype]] of a new subclass prototype object created at the same time, with constructor wired appropriately. That's what class syntax does at minimum. Well he didn't suggest that, but it is a good idea ;-) His extend() could be built out of a 'merge' and a 'subclass', something like: https://gist.github.com/1365284 You keep bringing in various extend alternatives, but these are separate from classes. Yes, we agree here totally. But from my perspective I would say You keep bringing up classes, but these are separate from the extend()-like functions. Yes, even in the case when the class body is non-empty: in that event the elements define properties on the new class prototype object, which shadow any properties on the base class prototype object. Shadow, not copy. I think some of my previous comments mixed up issues related to [[Prototype]] and issues related to properties. There are some similarities and, to further confuse us, much of the existing practice in this area uses property copies to set [[Prototype]] links via Foo.prototype/new Foo. I'll try to be better. In the form class D extends B adds P; or var D = B.extend(P); the properties on P shadow the properties on B. But the copy-ish issue fall on B and P individually. In Java/C++ languages B and P are highly constrained. Consequently the copy-ish issue we discuss here don't apply. If want B and P to be arbitrary expressions, then we have to face how the properties of D relate to the properties of B and P. I guess Allen's form is: var D = B | P; where P is constrained to be a literal. I believe it still allows B to have data values, which will be shared between instances of derived objects. jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Minimalist (why) classes ?
On Nov 14, 2011, at 2:07 PM, John J Barton wrote: Irakli proposes a function; you are discussing classes. So perhaps rather than agreeing with Irakli you are drawing a parallel: you like the object created by Irakli's extend() and wish to take that into the class discussion? Irakli and I are trying to separate concerns. We don't need to solve them all together. We don't even need to solve them all at once, if the composition concern is not unitary and has many solutions (my hydra-headed phrase), none of which is exclusive of any others. That's all fine. But I am focusing on the function vs (class) syntax issue. That is where Irakli's (why) classes comes from. Sort of. Irakli's post to which I was replying tried to get back to prototypal wiring. He does show a method definition too, but it does not work the way his selfish.js works. Hence (I think, if I'm reading him righ) his desire in the post to which I replied to get back on track. The problem is that selfish.js mixes in merging and notably freezing. The last in particular is unnecessary and it doesn't help us make progress. You won't find anyone (probably not even Irakli) arguing to standardize selfish.js as-is, instead of classes. How one composes properties from various source objects is a different issue, not directly addressed by class syntax (yet). It is addressed by http://traitsjs.org/ and you can use an expression in the superclass position in the class head: class D extends Trait.create(...) {...}. If we compare a |class| syntax class D extends B adds P; to Irakli's extend, we write: var D = B.extend(P); If both B and P can be expressions, then the forms are equivalent. No, expressions do not guarantee equivalence. Equivalence depends on crucial details about the syntax and semantics of P. We need to specify to be sure the forms are equivalent. With most of the classes proposals, they aren't. No freezing, for one. Issues of mutating [[Prototype]] vs. copyiing (shallow vs. deep) with [[Prototype]] update abound. That is, both forms have to come up with an answer for how the B and P are used in creating D. Here you're suggesting we make an API to underly class syntax, *whatever* the common semantics. That may be a good idea, but we need more details to be sure. No one has objected to APIs for syntactic sugar in general. But the general desire is not a commandment, and in particular, it can be impossible to constrain the semantics and avoid tarpits. For example, | has no API that works exactly the same. An Object.beget(lhs, rhs) would observably differ in the case where rhs was not a literal form that constructs a kind of object, in that lhs | rhs would be an error for any non-literal rhs. The API would have to copy, and now we are back to shallow vs. deep, and if deep, how to copy closures. So, not to be a broken record: it's crucial to specify the semantics before abstracting and asserting, or even arguing, that we should or must have APIs for all new syntax. In the form class D extends B adds P; or var D = B.extend(P); the properties on P shadow the properties on B. But the copy-ish issue fall on B and P individually. Nope, because there's no copy in the class D extend B { P } syntax. There is no expression evaluated to compute P as an object, and then reflection on that object to define properties of D's new prototype object. Instead the syntax of P as a class body can be specified entirely without resort to any kind of copy-ish copying. In Java/C++ languages B and P are highly constrained. Consequently the copy-ish issue we discuss here don't apply. If want B and P to be arbitrary expressions, That's the If I'm pushing back on. I don't necessarily want that as a good in itself (Irakli does). In order to decide if it's wanted, the it here needs a spec in the class syntax case. If that spec benefits from the syntax, in ways that are lost with a general expression -- in particular if the general expression form raises hard questions about cloning closures -- then the answer to this If is no. Irakli's selfish.js does a shallow merge-copy-then-freeze, so it dodges the closure copying issue. But Rick reports unwanted sharing, and I'm pretty sure many people object to the freeze. So what do you want for the copy-ish semantics, if you want the general expression form (that is, the API in addition to or underlying the syntax)? /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Minimalist (why) classes ?
On Mon, Nov 14, 2011 at 2:27 PM, Brendan Eich bren...@mozilla.com wrote: On Nov 14, 2011, at 2:07 PM, John J Barton wrote: Irakli proposes a function; you are discussing classes. So perhaps rather than agreeing with Irakli you are drawing a parallel: you like the object created by Irakli's extend() and wish to take that into the class discussion? Irakli and I are trying to separate concerns. We don't need to solve them all together. We don't even need to solve them all at once, if the composition concern is not unitary and has many solutions (my hydra-headed phrase), none of which is exclusive of any others. That's all fine. But I am focusing on the function vs (class) syntax issue. That is where Irakli's (why) classes comes from. Sort of. Irakli's post to which I was replying tried to get back to prototypal wiring. He does show a method definition too, but it does not work the way his selfish.js works. Hence (I think, if I'm reading him righ) his desire in the post to which I replied to get back on track. The problem is that selfish.js mixes in merging and notably freezing. The last in particular is unnecessary and it doesn't help us make progress. You won't find anyone (probably not even Irakli) arguing to standardize selfish.js as-is, instead of classes. How one composes properties from various source objects is a different issue, not directly addressed by class syntax (yet). It is addressed by http://traitsjs.org/ and you can use an expression in the superclass position in the class head: class D extends Trait.create(...) {...}. If we compare a |class| syntax class D extends B adds P; to Irakli's extend, we write: var D = B.extend(P); If both B and P can be expressions, then the forms are equivalent. No, expressions do not guarantee equivalence. Equivalence depends on crucial details about the syntax and semantics of P. We need to specify to be sure the forms are equivalent. With most of the classes proposals, they aren't. No freezing, for one. Issues of mutating [[Prototype]] vs. copyiing (shallow vs. deep) with [[Prototype]] update abound. That is, both forms have to come up with an answer for how the B and P are used in creating D. Here you're suggesting we make an API to underly class syntax, *whatever* the common semantics. I'm not suggesting such an API. In fact I am suggesting that such an API is not always possible. If the syntax is class D : B { pList } and requires that B be an identifier and pList list of properties, then the API would have to have restrictions on the arguments that I don't think we have a way to express. That may be a good idea, but we need more details to be sure. No one has objected to APIs for syntactic sugar in general. But the general desire is not a commandment, and in particular, it can be impossible to constrain the semantics and avoid tarpits. For example, | has no API that works exactly the same. An Object.beget(lhs, rhs) would observably differ in the case where rhs was not a literal form that constructs a kind of object, in that lhs | rhs would be an error for any non-literal rhs. The API would have to copy, and now we are back to shallow vs. deep, and if deep, how to copy closures. So, not to be a broken record: it's crucial to specify the semantics before abstracting and asserting, or even arguing, that we should or must have APIs for all new syntax. I am not arguing what we should or must have APIs for all new syntax. I'm not arguing anything about new syntax. You've already decided not to listen to anyone like me when it comes to new syntax, and I've already agreed that is a good decision. The only reason I brought up class syntax was illustrate that class syntax can force constraints on the inputs to the inheritance that functions cannot do. And BTW these constraints may well be the most important advantage of class syntax. These constraints prevent you from pointing the gun at yourself. In the form class D extends B adds P; or var D = B.extend(P); the properties on P shadow the properties on B. But the copy-ish issue fall on B and P individually. Nope, because there's no copy in the class D extend B { P } syntax. There is no expression evaluated to compute P as an object, and then reflection on that object to define properties of D's new prototype object. Instead the syntax of P as a class body can be specified entirely without resort to any kind of copy-ish copying. Well I did not write class D extend B { P } specifically because that would imply that the RHS is a literal. If it is a literal, then you don't have to copy, which is exactly my point: the heart of the problem is the copy demanded by functions but not by new syntax. In Java/C++ languages B and P are highly constrained. Consequently the copy-ish issue we discuss here don't apply. If want B and P to be arbitrary expressions, That's the If I'm pushing back
Re: Minimalist (why) classes ?
On Nov 14, 2011, at 3:16 PM, John J Barton wrote: I'm not suggesting such an API. In fact I am suggesting that such an API is not always possible. If the syntax is class D : B { pList } and requires that B be an identifier and pList list of properties, then the API would have to have restrictions on the arguments that I don't think we have a way to express. Right. BTW, no one proposes that B be an identiifer (which is a kind of expression). Static languages constrain B to be not only an identifier, but one declared previously as a class. We're not doing that. AFAIK all class proposals allow a general expression (probably AssignmenExpression in the grammar, to avoid comma problems) for B. I am not arguing what we should or must have APIs for all new syntax. I'm not arguing anything about new syntax. You've already decided not to listen to anyone like me when it comes to new syntax, and I've already agreed that is a good decision. I don't remember it that way, but ok. The only reason I brought up class syntax was illustrate that class syntax can force constraints on the inputs to the inheritance that functions cannot do. Good, ok. It sounded like the opposite, honest! And BTW these constraints may well be the most important advantage of class syntax. These constraints prevent you from pointing the gun at yourself. Right. Nope, because there's no copy in the class D extend B { P } syntax. There is no expression evaluated to compute P as an object, and then reflection on that object to define properties of D's new prototype object. Instead the syntax of P as a class body can be specified entirely without resort to any kind of copy-ish copying. Well I did not write class D extend B { P } specifically because that would imply that the RHS is a literal. No, braces don't mean only and ever literal. Function bodies are not literals, i.e. literal values. They're code bodies. Class bodies could be something else again, and are in Dave's minimial_classes proposal. But I take your point -- I was trying to be meta not concrete with the brackets. Moving along... If it is a literal, then you don't have to copy, which is exactly my point: the heart of the problem is the copy demanded by functions but not by new syntax. Great, we agree. Why did I think you were arguing the other side? Hrm. I want to survey the existing practice and create a set of tests illustrating the various choices and their trade offs. I don't expect any choice will satisfy everyone. A broad survey would be wonderful. Your taxonomy of sharing/copying is good to go. Whether we find one true way or several good approaches, this seeems worth doing. We don't have to standardize anything now (we should not rush) but analyzing the paths can only help (even if some are bad paths). /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Minimalist (why) classes ?
Good point. Note that you can easily do the same thing without copying, via prototypes: https://github.com/rauschma/proto-js On Nov 13, 2011, at 3:21 , Rick Waldron wrote: On Sat, Nov 12, 2011 at 7:08 PM, Brendan Eich bren...@mozilla.com wrote: snip Let's argue about specifics or we'll get nowhere. Do you think Irakli's selfish.js extend (https://github.com/Gozala/selfish/blob/master/selfish.js) is the way to go, or Prototype's quite different form? Neither of them are fit for standardization. Selfish and Prototype are both incapable of correctly deep copying arrays or objects, resulting in new instances being able to modify values of the base object's properties if those values are elements of an array or property values of an object - because the array and object property themselves are references, not real copies. PrototypeJS is painfully obvious, Selfish requires a demonstration. I forked/cloned the repo and added a branch with a set of tests: The branch: https://github.com/rwldrn/selfish/tree/test The commit: https://github.com/rwldrn/selfish/commit/ee55af5ec00074005fa74e9d9eb4be4dc4db5163 An Object.extend() that creates an object full of references is certainly not the way to go. Rick /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 -- Dr. Axel Rauschmayer a...@rauschma.de home: rauschma.de twitter: twitter.com/rauschma blog: 2ality.com ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Minimalist (why) classes ?
Neither of them are fit for standardization. Selfish and Prototype are both incapable of correctly deep copying arrays or objects, Why does it matter that they don't deep copy? Deep copying is a difficult problem that needs to be standardized separately. I've personally avoided deep copying for this reason and don't use it anymore. One can accept that an extend is merely a shallow copy properties by reference, because this (although limited) behavior is easy to understand. I have a version of Object.extendhttps://github.com/Raynos/pd/blob/master/src/pd.js#L82 that is a shallow own merge. However having a deep copy mechanism that works without obscure edge-cases would be great. Of course it would be nice if we had the choice of deep vs shallow copy within the API. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Minimalist (why) classes ?
It depends on what kind of `extends` you mean: - Inheritance: Even though data being kept in prototypes is rare, it’s usually better to chain prototypes even when ignoring aliasing problems (no redundant properties, instanceof works transitively). Performance degradation should be negligible due to internal optimizations. - Merging objects: Shallow copy is the way to go. On Nov 13, 2011, at 11:08 , Jake Verbaten wrote: Neither of them are fit for standardization. Selfish and Prototype are both incapable of correctly deep copying arrays or objects, Why does it matter that they don't deep copy? Deep copying is a difficult problem that needs to be standardized separately. I've personally avoided deep copying for this reason and don't use it anymore. One can accept that an extend is merely a shallow copy properties by reference, because this (although limited) behavior is easy to understand. I have a version of Object.extend that is a shallow own merge. However having a deep copy mechanism that works without obscure edge-cases would be great. Of course it would be nice if we had the choice of deep vs shallow copy within the API. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss -- Dr. Axel Rauschmayer a...@rauschma.de home: rauschma.de twitter: twitter.com/rauschma blog: 2ality.com ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Minimalist (why) classes ?
On 12/11/11 19:07, John J Barton wrote: This kind of discussion illustrates my point: JS is not sweet enough because we are missing core operations for constructing prototypes in a standard way. Agreed. I've always thought about JS objects as sets, but it feels weird that I don't get disjunction, intersection and other basic operations out of the box. Basically, I've missed primitives for: - Creating objects that share properties from other objects (Object.create) - Adding properties to an object (Object.extend) Object.extend(Object target, Object sources...) → Object (sources.reduce({|tgt, src| Object.keys(src).forEach({|key| tgt[key] = src[key]}) tgt }, target) Should `extend' copy all the properties? Only the own properties? I feel `own' properties make more sense. - Defining new objects that extends on the [[Prototype]], which is basically Object.create followed by copying the properties of one or more objects over to the new instance. (Object.clone? Object.inherit? I never felt `extend' quite says it all) Object.prototype.clone(Object parent, Object mixins...) → Object (Object.extend.apply(Object.create(parent), mixins)) - Merging (while possibly flattening, as objects can't have several [[Prototype]]s) objects. Object.merge(Object mixins...) → Object (x = Object.extend.apply({}, mixins)) Dicts are probably a better answer for this one though. - Creating instances from objects directly (new Stuff, Stuff.new), though I'm not sure there's much sense in having two different standard ways of doing the same thing. I guess JS is stuck with constructors =/ - Creating objects by removing/renaming certain properties from other objects, which is useful for object composition. Though I guess this would be handled by traits(?) Of course, you still need a better syntax to express it all, and the proposed extensions to object literals come close to minimalist classes: var foo = Base.clone({ method1() { }, method2() { }, get stuff() { } }) var foo = Base | { method1() { }, method2() { }, get stuff() { } } class foo extends Base { method1() { } method2() { } get stuff() { } } That is, if we disregard private and other modifiers. If such modifiers were added to the Object literal (meh?), it would be quite the same thing. Except a full-blown declarative class syntax could be better optimised and would allow for a sugary syntax if/when traits/type guards are added. var foo = Base | { #constant: 1, // or const @private_stuff: bar, // or private method1() { }, method2() { } get stuff() { } } class foo extends Base { @private_stuff: bar; // or private #constant: 1; // or const method1() { } method2() { } get stuff() { } } Except I'm not sure the @private could be made to work without creating confusing semantics around it, so object literals would still be one step behind. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Minimalist (why) classes ?
Should `extend' copy all the properties? Only the own properties? I feel `own' properties make more sense. I agree own makes more sense, we also want to specify whether we want to extend enumerable properties. Your example does not. - Defining new objects that extends on the [[Prototype]], which is basically Object.create followed by copying the properties of one or more objects over to the new instance. (Object.clone? Object.inherit? I never felt `extend' quite says it all) Object.prototype.clone(Object parent, Object mixins...) → Object (Object.extend.apply(Object.**create(parent), mixins)) I've been referring to this method as Object.makehttps://github.com/Raynos/pd/blob/master/src/pd.js#L120 it's defiantly a useful method, however I don't think clone, inherit or make are correct names for it. clone is probably the most suitable name, especially if it's on Object.prototype var foo = Base | { #constant: 1, // or const @private_stuff: bar, // or private method1() { }, method2() { } get stuff() { } } Except I'm not sure the @private could be made to work without creating confusing semantics around it, so object literals would still be one step behind. As far as I understand @private_stuff would desugar into a name object only available in scope of the object literal. var o = { @private_stuff: bar; method1() { } } var o = (function () { var private_stuff = name.create(); var ret = { method1() { } } ret[private_stuff] = bar; })(); I personally don't find that confusing. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Minimalist (why) classes ?
Except I'm not sure the @private could be made to work without creating confusing semantics around it, so object literals would still be one step behind. As far as I understand @private_stuff would desugar into a name object only available in scope of the object literal. The basic idea of private names is that you don't use names directly, but store them in a variable and use that variable whenever you need to refer to something: var _name = MyClass_private_a3cfb; function MyClass(name) { this[_name] = name; } The actual private names are very similar to _name above, but they are not strings, they are special objects that are never listed anywhere (one step beyond non-enumerable, if you will). Thus, the challenge is clear: You have to introduce variables such as _name in a manner that makes them accessible wherever you need them. var o = { @private_stuff: bar; method1() { } } var o = (function () { var private_stuff = name.create(); var ret = { method1() { } } ret[private_stuff] = bar; })(); I personally don't find that confusing. The latest ideas are about requiring a private section where you declare private_stuff. var obj = { private { private_stuff } @private_stuff: bar, method1() { return this.@private_stuff; } } It does desugar like you mention above. If you use constructor functions without any tricks, then scope is an issue: var private_stuff = name.create(); // it would be nice to have support for a private section here function MyClass(stuff) { this.@private_stuff = stuff; // same as this[private_stuff] } MyClass.prototype.method1 = function () { return this.@private_stuff; // same as this[private_stuff] } -- Dr. Axel Rauschmayer a...@rauschma.de twitter.com/rauschma Home: rauschma.de Blog: 2ality.com ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Minimalist (why) classes ?
On Nov 13, 2011, at 5:08 AM, Jake Verbaten rayn...@gmail.com wrote: Neither of them are fit for standardization. Selfish and Prototype are both incapable of correctly deep copying arrays or objects, Why does it matter that they don't deep copy? Deep copying is a difficult problem that needs to be standardized separately. It matters because I don't want data pollution across instances. It's not a hard problem at all, jQuery.extend() has had deep copy for years. I've personally avoided deep copying for this reason and don't use it anymore. One can accept that an extend is merely a shallow copy properties by reference, because this (although limited) behavior is easy to understand. I have a version of Object.extend that is a shallow own merge. However having a deep copy mechanism that works without obscure edge-cases would be great. Of course it would be nice if we had the choice of deep vs shallow copy within the API. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Minimalist (why) classes ?
A few more thoughts... On Nov 13, 2011, at 5:08 AM, Jake Verbaten rayn...@gmail.com wrote: Neither of them are fit for standardization. Selfish and Prototype are both incapable of correctly deep copying arrays or objects, Why does it matter that they don't deep copy? Deep copying is a difficult problem that needs to be standardized separately. I've personally avoided deep copying for this reason and don't use it anymore. One can accept that an extend is merely a shallow copy properties by reference, because this (although limited) behavior is easy to understand. Shallow copy is only good for one level of property lists whose assignment expressions are all primitive, anything that is a reference is going to allow the destination to mutate the source, this is wrong. I have a version of Object.extend that is a shallow own merge. However having a deep copy mechanism that works without obscure edge-cases would be great. Can you be specific? What obscure edge cases have you previously encountered? Of course it would be nice if we had the choice of deep vs shallow copy within the API. Agreed___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Minimalist (why) classes ?
However having a deep copy mechanism that works without obscure edge-cases would be great. Can you be specific? What obscure edge cases have you previously encountered? I don't have a list at hand, last time we talked about what it means to deep copy an arbitary ES-next structure we ran into questions of what it means to deep copy functions, closures and proxies. Deep copying data, i.e. anything that can be represented by JSON doesn't have too many edgecases. It would actually be nice to have an open lists of unsolved edge cases with generic deep copying. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Minimalist (why) classes ?
On Nov 13, 2011, at 11:03 AM, Jake Verbaten rayn...@gmail.com wrote: However having a deep copy mechanism that works without obscure edge-cases would be great. Can you be specific? What obscure edge cases have you previously encountered? I don't have a list at hand, last time we talked about what it means to deep copy an arbitary ES-next structure we ran into questions of what it means to deep copy functions, closures and proxies. Can you point me to existing discussion threads? Deep copying data, i.e. anything that can be represented by JSON doesn't have too many edgecases. It would actually be nice to have an open lists of unsolved edge cases with generic deep copying. This would definitely be useful.___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Minimalist (why) classes ?
On Sun, Nov 13, 2011 at 4:51 PM, Rick Waldron waldron.r...@gmail.comwrote: On Nov 13, 2011, at 11:03 AM, Jake Verbaten rayn...@gmail.com wrote: However having a deep copy mechanism that works without obscure edge-cases would be great. Can you be specific? What obscure edge cases have you previously encountered? I don't have a list at hand, last time we talked about what it means to deep copy an arbitary ES-next structure we ran into questions of what it means to deep copy functions, closures and proxies. Can you point me to existing discussion threads? The only thing I can find is https://mail.mozilla.org/pipermail/es-discuss/2011-October/017337.html This particular thread talked about | and how to make it work on object references rather then object literals. Since | returns a new object it would have to clone the object reference in some correct manner. Deep copying data, i.e. anything that can be represented by JSON doesn't have too many edgecases. It would actually be nice to have an open lists of unsolved edge cases with generic deep copying. This would definitely be useful. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Minimalist (why) classes ?
On Nov 13, 2011, at 9:24 AM, Jake Verbaten wrote: On Sun, Nov 13, 2011 at 4:51 PM, Rick Waldron waldron.r...@gmail.com wrote: On Nov 13, 2011, at 11:03 AM, Jake Verbaten rayn...@gmail.com wrote: However having a deep copy mechanism that works without obscure edge-cases would be great. Can you be specific? What obscure edge cases have you previously encountered? I don't have a list at hand, last time we talked about what it means to deep copy an arbitary ES-next structure we ran into questions of what it means to deep copy functions, closures and proxies. Can you point me to existing discussion threads? The only thing I can find is https://mail.mozilla.org/pipermail/es-discuss/2011-October/017337.html Quoting with s/identify/identity/g: No, generalized object clone is relatively hard. Some other issues: It isn't just the [[Class]] internal property. It is all the other representational and behavior invariants implied by [[Class]] What if the object is a Proxy instance? How should private name properties be handled. What if there are identity based internal state relationships within the object. What if there are identity bases external relationships about the object (eg, it's used as a key in a WeakMap) etc. In other language clone has generally evolved into a little frame that allows application level control of some or all of these decisions. I'm not saying that some sort of generalized clone wouldn't be useful. Just that it's not so simple. Allen This particular thread talked about | and how to make it work on object references rather then object literals. Since | returns a new object it would have to clone the object reference in some correct manner. Deep copying data, i.e. anything that can be represented by JSON doesn't have too many edgecases. It would actually be nice to have an open lists of unsolved edge cases with generic deep copying. This would definitely be useful. See above! The hard cases include: 1. Closures. 2. Proxies. 3. Private names. 4. Internal hidden state. 5. Side-table entries mapped to the object's identity. /be___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Minimalist (why) classes ?
On Nov 13, 2011, at 9:30 AM, Brendan Eich wrote: The hard cases include: 1. Closures. 2. Proxies. 3. Private names. 4. Internal hidden state. 5. Side-table entries mapped to the object's identity. In the case of objects implemented by C++ or whatever the host implementation language might be, the internal or side-table state may not even be representable in JS, even in strings (do not want raw pointers, or machine addresses however obfuscated, to leak to an attacker). /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Minimalist (why) classes ?
On Sun, Nov 13, 2011 at 7:42 AM, Rick Waldron waldron.r...@gmail.com wrote: On Nov 13, 2011, at 5:08 AM, Jake Verbaten rayn...@gmail.com wrote: Neither of them are fit for standardization. Selfish and Prototype are both incapable of correctly deep copying arrays or objects, Why does it matter that they don't deep copy? Deep copying is a difficult problem that needs to be standardized separately. It matters because I don't want data pollution across instances. It's not a hard problem at all, jQuery.extend() has had deep copy for years. Just a couple of observations: 1) There are two different issues here: flatten vs retain [[Prototype]] links and shallow vs deep copy. 2) I think the choice should be different for methods and data. The first order effect of inheritance is to re-use methods; for this purpose shallow copies and re-use by [[Prototype]] links works well. However, if you adopt shallow copies or re-use by [[Prototype]] links, the non-method data is copied by reference, causing write onto derived objects to write onto ancestor object values. This is only rarely the desired outcome. In Gonzala's selfish and in his gist, I believe the implicit assumption is that developers should adopt a pattern of use: ancestor class objects will have only function properties. The |initialize| method will define data properties. In this way the shallow copy and the use of [[Prototype]] links works for the methods and the data is chained through calls to ancestor initialize(). I think this is also implicit in Object.create(): LHS object is expected to be a pile of methods. This makes a lot of sense and it meshes well with class-thinking. What it says is: adopt a different strategy for methods and for data. For methods, retain the [[Prototype]] links; for data, flatten. The first-order effect is the same as old PrototypeJS solution but the second order effect, data in [[Prototype]] links vs data on the object, is different. No, I do not have a concrete proposal. But it seems to me that Gonzala's gist extend() should attach the data properties to the instance not the type. It only matters when the inputs have data properties and in that case you probably don't want them on the [[Prototype]] linked object. jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Minimalist (why) classes ?
On Sun, Nov 13, 2011 at 9:34 AM, Brendan Eich bren...@mozilla.com wrote: On Nov 13, 2011, at 9:30 AM, Brendan Eich wrote: The hard cases include: 1. Closures. 2. Proxies. 3. Private names. 4. Internal hidden state. 5. Side-table entries mapped to the object's identity. In the case of objects implemented by C++ or whatever the host implementation language might be, the internal or side-table state may not even be representable in JS, even in strings (do not want raw pointers, or machine addresses however obfuscated, to leak to an attacker). I think we are on the wrong path here. I guess we followed: a standard extend() needs a copy-ish operation; a copyish operation is like cloning; cloning is hard; OMG. But let's back up. We are looking for one or a few operations such that: var a = op(b,c,d,...); creates a useful result when we use |a| and we are using existing JS libraries for guidance. By definition there are no show stoppers here. We are creating new objects from existing objects using operations available to JS devs, but in standard and recommended way. The only two things can stop us from being successful: irreconcilable differences and inertia. jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Minimalist (why) classes ?
On Sun, Nov 13, 2011 at 2:36 AM, Axel Rauschmayer a...@rauschma.de wrote: It depends on what kind of `extends` you mean: - Inheritance: Even though data being kept in prototypes is rare, it’s usually better to chain prototypes even when ignoring aliasing problems (no redundant properties, instanceof works transitively). Performance degradation should be negligible due to internal optimizations. - Merging objects: Shallow copy is the way to go. Perhaps you mean: 'it depends on the use of the object returned by |extends()|'. But I don't understand your categories. Mine: Object-like: you want to use the returned object directly. I think a dev imagines extend() as a kind of initialization, a merger operation: var a = merge(b,c,d); In this case you do not expect deep copy, you expect shallow, reference copy. If I change d.color, I expect that a.color is changed. Or rather, I would say that a dev would not be surprised at this behavior. Class-like: you want to use the returned object indirectly, to create other objects via Foo.prototype/new Foo or similar operation. Here we are operating on two levels. In the abstract level we are combining objects to define factory; in the concrete level we are creating objects based on that factory. The data on the inputs to the abstract level are -- at most -- relevant as initial values for the concrete level. You want something like deep copy. As I mentioned elsewhere, the Object-like merge can be used (with care) on collections of methods then applied to Foo.prototype. That's how we get along now: one operation covers both cases just not always robustly. jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Minimalist (why) classes ?
I think this discussion drifted into slightly diff direction. What I intended to say was that today all major frameworks use same patter to do subclassing. They all implement different APIs to do the following: function subclass() { // init …. } subclass.prototype = Object.create(superclass) Object.defineProperty(subclass.prototype, 'constructor', { value: subclass }) subclass.prototype.method = function() { //... } Object.extend used in my gist is BTW same as backbone's .extend and is just a shortcut of the code above: var subclass = superclass.extend({ initialize: function() { // init ... }, method: function() { // …. } }) What I'm asking for is a standard function, no matter weather it's `Object.extend` or something else that makes it simple to do subclassing. Also lisper in me thinks that `Object.extend` method is better than dedicated class syntax cause it keeps language concise. In addition I think that if `Object.extend` will turn out to be broken it will be easier (not to say easy) to fix (`Object.extend = … `) then fixing `class Foo extends Bar`. Regards -- Irakli Gozalishvili Web: http://www.jeditoolkit.com/ Address: 29 Rue Saint-Georges, 75009 Paris, France (http://goo.gl/maps/3CHu) On Sunday, 2011-11-13 at 13:21 , Brendan Eich wrote: On Nov 13, 2011, at 11:28 AM, John J Barton wrote: On Sun, Nov 13, 2011 at 9:34 AM, Brendan Eich bren...@mozilla.com (mailto:bren...@mozilla.com) wrote: On Nov 13, 2011, at 9:30 AM, Brendan Eich wrote: The hard cases include: 1. Closures. 2. Proxies. 3. Private names. 4. Internal hidden state. 5. Side-table entries mapped to the object's identity. In the case of objects implemented by C++ or whatever the host implementation language might be, the internal or side-table state may not even be representable in JS, even in strings (do not want raw pointers, or machine addresses however obfuscated, to leak to an attacker). I think we are on the wrong path here. I guess we followed: a standard extend() needs a copy-ish operation; a copyish operation is like cloning; cloning is hard; OMG. That's not what happened. Some people are happy with shallow copy of properties available to ES5 reflection, or even a for-in loop. Others (Rick?) want deep, at least as an option. Deep could skip any private/internal/etc. properties, for sure. But deep tends to get into trouble because if you don't stay shallow, you run immediately into item 1: Closures. How would those be deeply copied, including their lexical environments? But let's back up. We are looking for one or a few operations such that: var a = op(b,c,d,...); creates a useful result when we use |a| and we are using existing JS libraries for guidance. By definition there are no show stoppers here. I agree, other than inability to agree on what to standardize. We are creating new objects from existing objects using operations available to JS devs, but in standard and recommended way. The only two things can stop us from being successful: irreconcilable differences and inertia. Ok, but this is all meta-pep-talk. What should the reconcilable standard be? /be ___ es-discuss mailing list es-discuss@mozilla.org (mailto:es-discuss@mozilla.org) https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Minimalist (why) classes ?
On Friday, 2011-11-11 at 18:38 , Brendan Eich wrote: Having written all this, I will repeat that I like your selfish work and the exemplar idea Thanks, that's really encouraging! ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Minimalist (why) classes ?
On Nov 13, 2011, at 9:42 PM, Irakli Gozalishvili wrote: I think this discussion drifted into slightly diff direction. What I intended to say was that today all major frameworks use same patter to do subclassing. They all implement different APIs to do the following: function subclass() { // init …. } subclass.prototype = Object.create(superclass) Object.defineProperty(subclass.prototype, 'constructor', { value: subclass }) subclass.prototype.method = function() { //... } Yes, this is the heart of the matter. Not freezing, not shallow vs. deep property copying (where deep must deal with closures at least). Object.extend used in my gist is BTW same as backbone's .extend Ok, good to know. (Jashkenas, you didn't propose it!) and is just a shortcut of the code above: var subclass = superclass.extend({ initialize: function() { // init ... }, method: function() { // …. } }) What I'm asking for is a standard function, no matter weather it's `Object.extend` or something else that makes it simple to do subclassing. Allen has been trying to make it be a combo of | and .{. Agree there could be a method, say Object.subclass (what a concept!). Also lisper in me thinks that `Object.extend` method is better than dedicated class syntax cause it keeps language concise. Sorry, JS isn't LISP. In addition I think that if `Object.extend` will turn out to be broken it will be easier (not to say easy) to fix (`Object.extend = … `) then fixing `class Foo extends Bar`. It would be about as hard either way. /be Regards -- Irakli Gozalishvili Web: http://www.jeditoolkit.com/ Address: 29 Rue Saint-Georges, 75009 Paris, France On Sunday, 2011-11-13 at 13:21 , Brendan Eich wrote: On Nov 13, 2011, at 11:28 AM, John J Barton wrote: On Sun, Nov 13, 2011 at 9:34 AM, Brendan Eich bren...@mozilla.com wrote: On Nov 13, 2011, at 9:30 AM, Brendan Eich wrote: The hard cases include: 1. Closures. 2. Proxies. 3. Private names. 4. Internal hidden state. 5. Side-table entries mapped to the object's identity. In the case of objects implemented by C++ or whatever the host implementation language might be, the internal or side-table state may not even be representable in JS, even in strings (do not want raw pointers, or machine addresses however obfuscated, to leak to an attacker). I think we are on the wrong path here. I guess we followed: a standard extend() needs a copy-ish operation; a copyish operation is like cloning; cloning is hard; OMG. That's not what happened. Some people are happy with shallow copy of properties available to ES5 reflection, or even a for-in loop. Others (Rick?) want deep, at least as an option. Deep could skip any private/internal/etc. properties, for sure. But deep tends to get into trouble because if you don't stay shallow, you run immediately into item 1: Closures. How would those be deeply copied, including their lexical environments? But let's back up. We are looking for one or a few operations such that: var a = op(b,c,d,...); creates a useful result when we use |a| and we are using existing JS libraries for guidance. By definition there are no show stoppers here. I agree, other than inability to agree on what to standardize. We are creating new objects from existing objects using operations available to JS devs, but in standard and recommended way. The only two things can stop us from being successful: irreconcilable differences and inertia. Ok, but this is all meta-pep-talk. What should the reconcilable standard be? /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: Minimalist (why) classes ?
On 11/11/11 23:44, John J Barton wrote: On Fri, Nov 11, 2011 at 4:48 PM, Brendan Eichbren...@mozilla.com wrote: On Nov 11, 2011, at 4:42 PM, John J Barton wrote: Object.extend() does not exist. Which one do you mean? I mean Object.extend does not exist. Irakli is using Function.prototype.extend, not something like PrototypeJS's Object.extend. Iraki wrote Object.extend(). `Object' is a function, though. So it shares stuff from the Function.prototype object :3 ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Minimalist (why) classes ?
On Nov 12, 2011, at 4:38 AM, Quildreen Motta wrote: On 11/11/11 23:44, John J Barton wrote: On Fri, Nov 11, 2011 at 4:48 PM, Brendan Eichbren...@mozilla.com wrote: On Nov 11, 2011, at 4:42 PM, John J Barton wrote: Object.extend() does not exist. Which one do you mean? I mean Object.extend does not exist. Irakli is using Function.prototype.extend, not something like PrototypeJS's Object.extend. Iraki wrote Object.extend(). `Object' is a function, though. So it shares stuff from the Function.prototype object :3 That's right. My point is that Irakli's .extend is quite different from PrototypeJS's, contrary to what John seemed to assume. IINM Irakli has a gist that defines Object.prototype.extend, which is inherited of course by Function.protoytpe and all functions (unless shadowed or cut off via null __proto__). But this .extend is not the two-argument one that does Swiss inheritance (http://www.crockford.com/javascript/inheritance.html). /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Minimalist (why) classes ?
On Sat, Nov 12, 2011 at 11:53 AM, Brendan Eich bren...@mozilla.com wrote: On Nov 12, 2011, at 4:38 AM, Quildreen Motta wrote: On 11/11/11 23:44, John J Barton wrote: On Fri, Nov 11, 2011 at 4:48 PM, Brendan Eichbren...@mozilla.com wrote: On Nov 11, 2011, at 4:42 PM, John J Barton wrote: Object.extend() does not exist. Which one do you mean? I mean Object.extend does not exist. Irakli is using Function.prototype.extend, not something like PrototypeJS's Object.extend. Iraki wrote Object.extend(). `Object' is a function, though. So it shares stuff from the Function.prototype object :3 That's right. My point is that Irakli's .extend is quite different from PrototypeJS's, contrary to what John seemed to assume. Irakli proposed his extend() for the same set of use cases covered by PrototypeJS's extend(): creating objects from prototypes. As Irakli says above his defn: --- // There is nothing new here, just standardizing what libraries already do // today, in a similar manner as Function.prototype.bind was standardized for // ES5. --- Of course his extend() is not Prototype's extend(), or Crockford's or Hewitt's, or Resig's, etc, etc. That's exactly the problem. IINM Irakli has a gist that defines Object.prototype.extend, which is inherited of course by Function.protoytpe and all functions (unless shadowed or cut off via null __proto__). But this .extend is not the two-argument one that does Swiss inheritance (http://www.crockford.com/javascript/inheritance.html). This kind of discussion illustrates my point: JS is not sweet enough because we are missing core operations for constructing prototypes in a standard way. jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Minimalist (why) classes ?
Let's argue about specifics or we'll get nowhere. Do you think Irakli's selfish.js extend ( https://github.com/Gozala/selfish/blob/master/selfish.js) is the way to go, or Prototype's quite different form? I'd personally prefer Prototype's extend because it actually extends an object rather then creating a new object whom's [[Prototype]] is the extended object. Even though the latter may be useful, I'd rather have an Object.make or Object.createSimple for that. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Minimalist (why) classes ?
On Sat, Nov 12, 2011 at 7:08 PM, Brendan Eich bren...@mozilla.com wrote: snip Let's argue about specifics or we'll get nowhere. Do you think Irakli's selfish.js extend ( https://github.com/Gozala/selfish/blob/master/selfish.js) is the way to go, or Prototype's quite different form? Neither of them are fit for standardization. Selfish and Prototype are both incapable of correctly deep copying arrays or objects, resulting in new instances being able to modify values of the base object's properties if those values are elements of an array or property values of an object - because the array and object property themselves are references, not real copies. PrototypeJS is painfully obvious, Selfish requires a demonstration. I forked/cloned the repo and added a branch with a set of tests: The branch: https://github.com/rwldrn/selfish/tree/test The commit: https://github.com/rwldrn/selfish/commit/ee55af5ec00074005fa74e9d9eb4be4dc4db5163 An Object.extend() that creates an object full of references is certainly not the way to go. Rick /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: Minimalist (why) classes ?
On Sat, Nov 12, 2011 at 4:15 PM, Jake Verbaten rayn...@gmail.com wrote: Let's argue about specifics or we'll get nowhere. Do you think Irakli's selfish.js extend (https://github.com/Gozala/selfish/blob/master/selfish.js) is the way to go, or Prototype's quite different form? I'd personally prefer Prototype's extend because it actually extends an object rather then creating a new object whom's [[Prototype]] is the extended object. We could start by classifying the existing solutions. Perhaps there are better terms, here is my start: shallow vs deep usual defn: http://en.wikipedia.org/wiki/Object_copy merge colliding properties are resolved by selecting a winner, typically the left most object flatten the properties of the [[Prototype]] (proto-linked objects) become 'own' properties of the result own the own-properties are used Prototype's two argument extend(): produces an object equal to the flatten shallow merge on the arguments.. https://github.com/sstephenson/prototype/blob/master/src/prototype/lang/object.js#L51 Gonzala's gist's multi-argument extend() produces a function object with a .prototype from shallow merge own on the arguments, a prototype chain linking this.prototype, properties from |this|, and a body that creates an object I agree that calling Gonzala's function extend() might be confusing. We could all it Object.class() ;-) I don't agree that Prototype's extend() is clearly a winner Even though the latter may be useful, I'd rather have an Object.make or Object.createSimple for that. I think the primitive we need to agree on is the copy. jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Minimalist (why) classes ?
Hi, I have posted this to the long thread of Minimalist Classes, but since I have not got any response, I assume it got lost into a long discussion. So I thought I'll give it another try on fresh thread. I do really liked direction that Jeremy tried to push classes to, but still I don't understand why do we need to introduce new syntax to the language. From what I can tell, lack of classes or special syntax for creating ones, is not a problem. Problem is amount of ceremony one needs to perform inherit or subclass if you like. Also, I think we don't need new `class` expression to solve actual problems we have, simple function will do the job perfectly here, also it will add zero learning curve! I forked Jeremy's proposal and modified it to ilustrate how existing subclassing problems can be solved without introducing new constructs to the language or adding more verbosity. Please also note that there is nothing new here, lot's of frameworks do this already (hide prototype machinery), but each does it with it's own flavored API which is IMO another problem that standardization should solve. The classes problem is very similar to `Function.prototype.bind` that ES5 solved greatly, why not do the same for classes ? https://gist.github.com/1355701 In addition I tried to address few other concerns I had with a proposal: - `constructor` property as initializer is poor choice raising many questions (what will be prototype of constructor property if it's used in more then one class, if it's frozen etc). - Some people in the community would love to have frozen classes others value flexibility, simple functions make it easy to build first out of second without becoming a second class citizen. Please note, that I intentionally omitted `super` as it's separate problem that is / must be discussed in the separate thread / proposal. Regards -- Irakli Gozalishvili Web: http://www.jeditoolkit.com/ Address: 29 Rue Saint-Georges, 75009 Paris, France (http://goo.gl/maps/3CHu) Regards -- Irakli Gozalishvili Web: http://www.jeditoolkit.com/ Address: 29 Rue Saint-Georges, 75009 Paris, France (http://goo.gl/maps/3CHu) ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Minimalist (why) classes ?
Thats exact port of proposal that Jeremy wrote here: https://gist.github.com/1329619 I could write add examples from the classes proposal if that wolud help: http://wiki.ecmascript.org/doku.php?id=harmony:classes Regards -- Irakli Gozalishvili Web: http://www.jeditoolkit.com/ Address: 29 Rue Saint-Georges, 75009 Paris, France (http://goo.gl/maps/3CHu) On Friday, 2011-11-11 at 16:05 , John J Barton wrote: On Fri, Nov 11, 2011 at 3:47 PM, Irakli Gozalishvili rfo...@gmail.com (mailto:rfo...@gmail.com) wrote: Hi, I have posted this to the long thread of Minimalist Classes, but since I have not got any response, I assume it got lost into a long discussion. So I thought I'll give it another try on fresh thread. I do really liked direction that Jeremy tried to push classes to, but still I don't understand why do we need to introduce new syntax to the language. From what I can tell, lack of classes or special syntax for creating ones, is not a problem. Problem is amount of ceremony one needs to perform inherit or subclass if you like. Also, I think we don't need new `class` expression to solve actual problems we have, simple function will do the job perfectly here, also it will add zero learning curve! I forked Jeremy's proposal and modified it to ilustrate how existing subclassing problems can be solved without introducing new constructs to the language or adding more verbosity. Please also note that there is nothing new here, lot's of frameworks do this already (hide prototype machinery), but each does it with it's own flavored API which is IMO another problem that standardization should solve. The classes problem is very similar to `Function.prototype.bind` that ES5 solved greatly, why not do the same for classes ? https://gist.github.com/1355701 Just FYI, I found the listing confusing, since the examples seem unrelated to each other and there is no reference to the corresponding 'class' proposal. jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Minimalist (why) classes ?
On Nov 11, 2011, at 4:09 PM, Irakli Gozalishvili wrote: Thats exact port of proposal that Jeremy wrote here: https://gist.github.com/1329619 I could write add examples from the classes proposal if that wolud help: http://wiki.ecmascript.org/doku.php?id=harmony:classes Maybe, but I think that you'd be beating a dead horse. Class syntax is wanted to avoid some method calling boilerplate that's more verbose, arguably easier to get wrong, and harder to analyze and optimize. That's it. Hence, classes as sugar. If you find existing JS sweet enough, you won't want classes. /be Regards -- Irakli Gozalishvili Web: http://www.jeditoolkit.com/ Address: 29 Rue Saint-Georges, 75009 Paris, France On Friday, 2011-11-11 at 16:05 , John J Barton wrote: On Fri, Nov 11, 2011 at 3:47 PM, Irakli Gozalishvili rfo...@gmail.com wrote: Hi, I have posted this to the long thread of Minimalist Classes, but since I have not got any response, I assume it got lost into a long discussion. So I thought I'll give it another try on fresh thread. I do really liked direction that Jeremy tried to push classes to, but still I don't understand why do we need to introduce new syntax to the language. From what I can tell, lack of classes or special syntax for creating ones, is not a problem. Problem is amount of ceremony one needs to perform inherit or subclass if you like. Also, I think we don't need new `class` expression to solve actual problems we have, simple function will do the job perfectly here, also it will add zero learning curve! I forked Jeremy's proposal and modified it to ilustrate how existing subclassing problems can be solved without introducing new constructs to the language or adding more verbosity. Please also note that there is nothing new here, lot's of frameworks do this already (hide prototype machinery), but each does it with it's own flavored API which is IMO another problem that standardization should solve. The classes problem is very similar to `Function.prototype.bind` that ES5 solved greatly, why not do the same for classes ? https://gist.github.com/1355701 Just FYI, I found the listing confusing, since the examples seem unrelated to each other and there is no reference to the corresponding 'class' proposal. jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Minimalist (why) classes ?
On Fri, Nov 11, 2011 at 4:31 PM, Brendan Eich bren...@mozilla.com wrote: On Nov 11, 2011, at 4:09 PM, Irakli Gozalishvili wrote: Thats exact port of proposal that Jeremy wrote here: https://gist.github.com/1329619 I could write add examples from the classes proposal if that wolud help: http://wiki.ecmascript.org/doku.php?id=harmony:classes Maybe, but I think that you'd be beating a dead horse. Class syntax is wanted to avoid some method calling boilerplate that's more verbose, arguably easier to get wrong, and harder to analyze and optimize. That's it. Hence, classes as sugar. If you find existing JS sweet enough, you won't want classes. If I understand Iraki's proposal, then, no we don't find JS sweet enough. Object.extend() does not exist. Similar but not identical functions are widely used. We would like a standard form built-in to the runtime. Or is this already in the standard but not implemented? jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Minimalist (why) classes ?
On Nov 11, 2011, at 4:42 PM, John J Barton wrote: Object.extend() does not exist. Which one do you mean? Irakli is using Function.prototype.extend, not something like PrototypeJS's Object.extend. Similar but not identical functions are widely used. We would like a standard form built-in to the runtime. You have to specify. But anyway, adding something specific, say Irakli's Function.prototype.extend, would not address the goals of classes-as-sugar. Or is this already in the standard but not implemented? What this do you mean, *exactly*? No fair acting like I didn't get you a free hot dog while I was selling hamburgers! You have to give (with specifics) to hope to get; you have to play to win. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Minimalist (why) classes ?
What I'm suggesting is to sugar current patterns, without adding new syntax similar to how Funciton.prototype.bind was added. And maybe in next iteration add special syntax if it still we be wanted. It's just so much easier to fix `Object.extend` if it will end up to be a wrong fit than change a special class syntax. BTW I have updated examples to illustrate exactly what is problematic requires sugar https://gist.github.com/1355701 Class syntax is wanted to avoid some method calling boilerplate that's more verbose, In my examples it actually takes same amount of chars: class Foo extends Bar {} VS var Bar = Foo.extend({}) arguably easier to get wrong, and harder to analyze and optimize. That's it. Arguably indeed, IMO increasing surface of language makes surface of things that can be made wrong bigger, increasing probability of making things wrong. Regards -- Irakli Gozalishvili Web: http://www.jeditoolkit.com/ Address: 29 Rue Saint-Georges, 75009 Paris, France (http://goo.gl/maps/3CHu) On Friday, 2011-11-11 at 16:31 , Brendan Eich wrote: On Nov 11, 2011, at 4:09 PM, Irakli Gozalishvili wrote: Thats exact port of proposal that Jeremy wrote here: https://gist.github.com/1329619 I could write add examples from the classes proposal if that wolud help: http://wiki.ecmascript.org/doku.php?id=harmony:classes Maybe, but I think that you'd be beating a dead horse. Class syntax is wanted to avoid some method calling boilerplate that's more verbose, arguably easier to get wrong, and harder to analyze and optimize. That's it. Hence, classes as sugar. If you find existing JS sweet enough, you won't want classes. /be Regards -- Irakli Gozalishvili Web: http://www.jeditoolkit.com/ Address: 29 Rue Saint-Georges, 75009 Paris, France (http://goo.gl/maps/3CHu) On Friday, 2011-11-11 at 16:05 , John J Barton wrote: On Fri, Nov 11, 2011 at 3:47 PM, Irakli Gozalishvili rfo...@gmail.com (mailto:rfo...@gmail.com) wrote: Hi, I have posted this to the long thread of Minimalist Classes, but since I have not got any response, I assume it got lost into a long discussion. So I thought I'll give it another try on fresh thread. I do really liked direction that Jeremy tried to push classes to, but still I don't understand why do we need to introduce new syntax to the language. From what I can tell, lack of classes or special syntax for creating ones, is not a problem. Problem is amount of ceremony one needs to perform inherit or subclass if you like. Also, I think we don't need new `class` expression to solve actual problems we have, simple function will do the job perfectly here, also it will add zero learning curve! I forked Jeremy's proposal and modified it to ilustrate how existing subclassing problems can be solved without introducing new constructs to the language or adding more verbosity. Please also note that there is nothing new here, lot's of frameworks do this already (hide prototype machinery), but each does it with it's own flavored API which is IMO another problem that standardization should solve. The classes problem is very similar to `Function.prototype.bind` that ES5 solved greatly, why not do the same for classes ? https://gist.github.com/1355701 Just FYI, I found the listing confusing, since the examples seem unrelated to each other and there is no reference to the corresponding 'class' proposal. jjb ___ es-discuss mailing list es-discuss@mozilla.org (mailto:es-discuss@mozilla.org) https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Minimalist (why) classes ?
On Fri, Nov 11, 2011 at 4:48 PM, Brendan Eich bren...@mozilla.com wrote: On Nov 11, 2011, at 4:42 PM, John J Barton wrote: Object.extend() does not exist. Which one do you mean? I mean Object.extend does not exist. Irakli is using Function.prototype.extend, not something like PrototypeJS's Object.extend. Iraki wrote Object.extend(). Similar but not identical functions are widely used. We would like a standard form built-in to the runtime. You have to specify. But anyway, adding something specific, say Irakli's Function.prototype.extend, would not address the goals of classes-as-sugar. True by your definition, but not relevant, since I'm not claiming any goals classes are covered. Iraki is, but I guess he missed your point about our opinion on classes being irrelevant (which makes sense to FWIW).. Or is this already in the standard but not implemented? What this do you mean, *exactly*? Of course I cannot answer exactly. If I could we would not need a standard. No fair acting like I didn't get you a free hot dog while I was selling hamburgers! We need hot dogs. Hopefully someone selling other things will offer hot dogs if we keep asking. You have to give (with specifics) to hope to get; you have to play to win. Ok sorry I did not know the rules. jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Minimalist (why) classes ?
On Nov 11, 2011, at 5:02 PM, Irakli Gozalishvili rfo...@gmail.com wrote: What I'm suggesting is to sugar Sugar usually means new syntax, not methods, but no worries. current patterns, without adding new syntax similar to how Funciton.prototype.bind was added. That ES5 addition was years late, a bit different from the de-facto standard, and it is still verbose and a bit hard to optimize compared to lexical-only |this| forms such as block lambdas. Still good to have, but we are not operating under ES3.1's artificial no new syntax regime. And maybe in next iteration add special syntax if it still we be wanted. Iterations take 3 years anyway, no savings and potentially big tax on community. It's just so much easier to fix `Object.extend` if it will end up to be a wrong fit than change a special class syntax. No, it is not easy to fix anything once standardized. Having written all this, I will repeat that I like your selfish work and the exemplar idea, and I would not want over-minimal classes instead or alongside. Minimizing too much defeats the purpose of adding class syntax. Hence my desire for batteries and leather included. BTW I have updated examples to illustrate exactly what is problematic requires sugar https://gist.github.com/1355701 Class syntax is wanted to avoid some method calling boilerplate that's more verbose, In my examples it actually takes same amount of chars: class Foo extends Bar {} VS var Bar = Foo.extend({}) arguably easier to get wrong, and harder to analyze and optimize. That's it. Not if classes also provide statics, privates, constructor(@x, @y) {} shorthand, etc. Arguably indeed, IMO increasing surface of language makes surface of things that can be made wrong bigger, increasing probability of making things wrong. Not the semantics, though. That is the point of desugaring. Getting the syntax right, or not adding it till we do, is still required. /be Regards -- Irakli Gozalishvili Web: http://www.jeditoolkit.com/ Address: 29 Rue Saint-Georges, 75009 Paris, France On Friday, 2011-11-11 at 16:31 , Brendan Eich wrote: On Nov 11, 2011, at 4:09 PM, Irakli Gozalishvili wrote: Thats exact port of proposal that Jeremy wrote here: https://gist.github.com/1329619 I could write add examples from the classes proposal if that wolud help: http://wiki.ecmascript.org/doku.php?id=harmony:classes Maybe, but I think that you'd be beating a dead horse. Class syntax is wanted to avoid some method calling boilerplate that's more verbose, arguably easier to get wrong, and harder to analyze and optimize. That's it. Hence, classes as sugar. If you find existing JS sweet enough, you won't want classes. /be Regards -- Irakli Gozalishvili Web: http://www.jeditoolkit.com/ Address: 29 Rue Saint-Georges, 75009 Paris, France On Friday, 2011-11-11 at 16:05 , John J Barton wrote: On Fri, Nov 11, 2011 at 3:47 PM, Irakli Gozalishvili rfo...@gmail.com wrote: Hi, I have posted this to the long thread of Minimalist Classes, but since I have not got any response, I assume it got lost into a long discussion. So I thought I'll give it another try on fresh thread. I do really liked direction that Jeremy tried to push classes to, but still I don't understand why do we need to introduce new syntax to the language. From what I can tell, lack of classes or special syntax for creating ones, is not a problem. Problem is amount of ceremony one needs to perform inherit or subclass if you like. Also, I think we don't need new `class` expression to solve actual problems we have, simple function will do the job perfectly here, also it will add zero learning curve! I forked Jeremy's proposal and modified it to ilustrate how existing subclassing problems can be solved without introducing new constructs to the language or adding more verbosity. Please also note that there is nothing new here, lot's of frameworks do this already (hide prototype machinery), but each does it with it's own flavored API which is IMO another problem that standardization should solve. The classes problem is very similar to `Function.prototype.bind` that ES5 solved greatly, why not do the same for classes ? https://gist.github.com/1355701 Just FYI, I found the listing confusing, since the examples seem unrelated to each other and there is no reference to the corresponding 'class' proposal. jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss