RE: Object.define ==> Object.mixin??
On Dec 11, 2012, at 10:19 AM, Andrea Giammarchi wrote: > Agreed, getOwnPropertyNames is way more appropriate if the topic is: use > all ES5 features for mixins too. I totally agree as well. > Also, the Nicolas example is potentially disaster prone, not in that > specific form, but in the way a getter with private scope access could be. > Imagine many objects using that specific object as mixin with that name > getter, > if there was a setter too the first one that will use it will overwrite the > returned value for all other objects. > I think propertie swith getters and setters will cause as many headaches as > objects and arrays in function prototypes did before already but hey, if you > know what you are doing, I believe there's no other solution for "universally > capable mixin method" Possibly, however, symbols are the solution to the headache right? With the introduction of symbols, we're able to easily tie internal state to objects rather than scope. var $name = new Symbol(); var Person = { get name() { return this[$name]; }, set name(value) { this[$name] = value; } }; var John = Object.mixin({ }, Person); John.name = 'John'; var Sam = Object.mixin({ }, Person); Sam.name = 'Sam; John.name; // => 'John' Sam.name; // => 'Sam' Nathan ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Object.define ==> Object.mixin??
On Dec 12, 2012, at 2:27 PM, Brandon Benvie wrote: > The spec says for the various Object functions that the properties are > iterated in "list order". Doesn't this indicate the order is defined? Except that the List in question is created "containing the names of each enumerable own property of props" and it doesn't say in what order they are placed when initially populating the list. Allen > > > On Wed, Dec 12, 2012 at 4:57 PM, John J Barton > wrote: > > > > On Wed, Dec 12, 2012 at 11:13 AM, Allen Wirfs-Brock > wrote: > > On Dec 12, 2012, at 10:10 AM, John J Barton wrote: > >> On Wed, Dec 12, 2012 at 10:05 AM, Allen Wirfs-Brock >> wrote: >> >> On Dec 12, 2012, at 9:50 AM, John J Barton wrote: >> ... >> > But most of all we want this feature to land and not just spin around here. >> > >> > jjb >> >> As Object.mixin or as Object.define?? >> >> Object.mixin >> > > What should be the effect of trying to "mixin" a property that already exists > (as an own property) of the target object. > > Object.define(target,src) would presumably have redefined such properties > using the Object.defineProperty rules. Is that what Object.mixin should do. > It could, have different rules. > > For example, it could simply replace an existing target property (if the > existing property is configurable). Or it could skip existing properties or > throw an error if a property exists. > > Replace is attractive, but it may or may not be what you want for accessor > properties. Consider: > > var objTarget = {get foo() {/*target*/...}}); > Object.mixin(objTarget, {set foo(v) {/*src*/...}}); > > after the mixin do you want objTarget to look like: >{set foo(v) {/*src*/...}} //replace semantics gives you this > or >{set foo(v) {/*src*/...}, > get foo() {/*target*/...} } //Object.defineProperty semantics gives you > this > > The general character of Object.mixin is to produce an object with all of the > properties of both arguments. In the case of duplicate *properties* we want > replace LHS with RHS. In my opinion your example is not such a duplicate. > Rather we have two functions one on each argument. I would expect the general > character to apply: two functions on the result. > > Or maybe this should just throw. Either of the above choices will cause > surprising errors if the developer expected the other result. > > jjb > > > > Allen > > > ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Object.define ==> Object.mixin??
The spec says for the various Object functions that the properties are iterated in "list order". Doesn't this indicate the order is defined? On Wed, Dec 12, 2012 at 4:57 PM, John J Barton wrote: > > > > On Wed, Dec 12, 2012 at 11:13 AM, Allen Wirfs-Brock > wrote: > >> >> On Dec 12, 2012, at 10:10 AM, John J Barton wrote: >> >> On Wed, Dec 12, 2012 at 10:05 AM, Allen Wirfs-Brock < >> al...@wirfs-brock.com> wrote: >> >>> >>> On Dec 12, 2012, at 9:50 AM, John J Barton wrote: >>> ... >>> > But most of all we want this feature to land and not just spin around >>> here. >>> > >>> > jjb >>> >>> As Object.mixin or as Object.define?? >>> >> >> Object.mixin >> >> >> What should be the effect of trying to "mixin" a property that already >> exists (as an own property) of the target object. >> >> Object.define(target,src) would presumably have redefined such properties >> using the Object.defineProperty rules. Is that what Object.mixin should do. >> It could, have different rules. >> >> For example, it could simply replace an existing target property (if the >> existing property is configurable). Or it could skip existing properties >> or throw an error if a property exists. >> >> Replace is attractive, but it may or may not be what you want for >> accessor properties. Consider: >> >> var objTarget = {get foo() {/*target*/...}}); >> Object.mixin(objTarget, {set foo(v) {/*src*/...}}); >> >> after the mixin do you want objTarget to look like: >>{set foo(v) {/*src*/...}} //replace semantics gives you this >> or >>{set foo(v) {/*src*/...}, >> get foo() {/*target*/...} } //Object.defineProperty semantics gives >> you this >> > > The general character of Object.mixin is to produce an object with all of > the properties of both arguments. In the case of duplicate *properties* we > want replace LHS with RHS. In my opinion your example is not such a > duplicate. Rather we have two functions one on each argument. I would > expect the general character to apply: two functions on the result. > > Or maybe this should just throw. Either of the above choices will cause > surprising errors if the developer expected the other result. > > jjb > > > >> >> Allen >> >> > ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Object.define ==> Object.mixin??
On Wed, Dec 12, 2012 at 11:13 AM, Allen Wirfs-Brock wrote: > > On Dec 12, 2012, at 10:10 AM, John J Barton wrote: > > On Wed, Dec 12, 2012 at 10:05 AM, Allen Wirfs-Brock > wrote: > >> >> On Dec 12, 2012, at 9:50 AM, John J Barton wrote: >> ... >> > But most of all we want this feature to land and not just spin around >> here. >> > >> > jjb >> >> As Object.mixin or as Object.define?? >> > > Object.mixin > > > What should be the effect of trying to "mixin" a property that already > exists (as an own property) of the target object. > > Object.define(target,src) would presumably have redefined such properties > using the Object.defineProperty rules. Is that what Object.mixin should do. > It could, have different rules. > > For example, it could simply replace an existing target property (if the > existing property is configurable). Or it could skip existing properties > or throw an error if a property exists. > > Replace is attractive, but it may or may not be what you want for accessor > properties. Consider: > > var objTarget = {get foo() {/*target*/...}}); > Object.mixin(objTarget, {set foo(v) {/*src*/...}}); > > after the mixin do you want objTarget to look like: >{set foo(v) {/*src*/...}} //replace semantics gives you this > or >{set foo(v) {/*src*/...}, > get foo() {/*target*/...} } //Object.defineProperty semantics gives > you this > The general character of Object.mixin is to produce an object with all of the properties of both arguments. In the case of duplicate *properties* we want replace LHS with RHS. In my opinion your example is not such a duplicate. Rather we have two functions one on each argument. I would expect the general character to apply: two functions on the result. Or maybe this should just throw. Either of the above choices will cause surprising errors if the developer expected the other result. jjb > > Allen > > ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Object.define ==> Object.mixin??
I think the latter should replace the previous as overwrite and would not care much about same property name with only a getter VS only a setter. If a developer wants both it can use mixin() to define the descriptor. Back to Nicolas third parameter, true is not as powerful as a function(target, name, newDescriptor) => objectDescriptor that will eventually let a developer decide if the newDescriptor should be used or the old one, regardless possible errors caused if target.getOwnPropertyDescriptor(name) cannot be overwritten . In this case the developer might intercept the case and decide if merge descriptors retrieving the currentOne, if any, return the current one, if any, or return the new one regardless. Thoughts? On Wed, Dec 12, 2012 at 11:13 AM, Allen Wirfs-Brock wrote: > > On Dec 12, 2012, at 10:10 AM, John J Barton wrote: > > On Wed, Dec 12, 2012 at 10:05 AM, Allen Wirfs-Brock > wrote: > >> >> On Dec 12, 2012, at 9:50 AM, John J Barton wrote: >> ... >> > But most of all we want this feature to land and not just spin around >> here. >> > >> > jjb >> >> As Object.mixin or as Object.define?? >> > > Object.mixin > > > What should be the effect of trying to "mixin" a property that already > exists (as an own property) of the target object. > > Object.define(target,src) would presumably have redefined such properties > using the Object.defineProperty rules. Is that what Object.mixin should do. > It could, have different rules. > > For example, it could simply replace an existing target property (if the > existing property is configurable). Or it could skip existing properties > or throw an error if a property exists. > > Replace is attractive, but it may or may not be what you want for accessor > properties. Consider: > > var objTarget = {get foo() {/*target*/...}}); > Object.mixin(objTarget, {set foo(v) {/*src*/...}}); > > after the mixin do you want objTarget to look like: >{set foo(v) {/*src*/...}} //replace semantics gives you this > or >{set foo(v) {/*src*/...}, > get foo() {/*target*/...} } //Object.defineProperty semantics gives > you this > > Allen > > > ___ > es-discuss mailing list > es-discuss@mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > > ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Object.define ==> Object.mixin??
On Wed, Dec 12, 2012 at 11:57 AM, Allen Wirfs-Brock wrote: >>> How would throwing early versus throwing late make any different to you? > >> Because 1) late is a waste, the result is undefined anyway, 2) the exception >> thrown is a lie, the operation did not die on the property reported but >> continued and failed to die on an unreported number of subsequent >> properties/ > > Arguably, the operation didn't "die" at all. Instead it made a best effort > to do everything that was requested that could possibly be done. I'll leave > it to MarkM , if he wants to make more of a case. I don't know that I have anything to add to the arguments already made in this thread -- and I consider those arguments sufficient. As to the above argument against, I don't understand it. In the absence of proxies and with a non-deterministic update order, any outcome by the new proposed ES6 rule is an allowed outcome by the ES5 rule. In this sense, it is not even a breaking change. The only remaining objection above I see is "is a waste". I don't care about a bit of extra runtime overhead in the thrown-error case. -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Object.define ==> Object.mixin??
On Dec 12, 2012, at 11:40 AM, John J Barton wrote: > > > > On Wed, Dec 12, 2012 at 11:20 AM, Allen Wirfs-Brock > wrote: > > On Dec 12, 2012, at 10:52 AM, John J Barton wrote: > >> >> >> >> On Wed, Dec 12, 2012 at 10:44 AM, Allen Wirfs-Brock >> wrote: >> >> On Dec 12, 2012, at 10:23 AM, John J Barton wrote: >> >>> >>> >>> >>> On Wed, Dec 12, 2012 at 10:18 AM, Allen Wirfs-Brock >>> wrote: >>> >>> On Dec 12, 2012, at 10:05 AM, Brandon Benvie wrote: >>> All the Object functions that operate on multiple properties are currently specified using pendingException which reports the first thrown exception after going through all the properties. defineProperties, freeze, etc. >>> >>> In, ES6. This is a breaking (hopefully nothing) change from ES5 that was >>> suggested by Mark Miller. >>> >>> The desire is to decrease the non-determinism that an early throw >>> introduces. >>> >>> How can multiple calls to Object.mixin with identical state result in >>> different results? >> >> Because the order that the source properties are visited is unspecified. It >> can differ among implementations and in theory could even differ within a >> single implementation. >> >>> >>> In the ES6 approach all property updates that can occur will occur, before >>> the exception is thrown instead of leaving the object in a less well >>> defined partially updated state. >>> >>> If an exception is thrown because of an error in Object.mixin, what state >>> is the object in? Will the spec define that state? >> >> Yes, all property additions (to the target object) that can complete will >> complete. >> >> And I assume then that the exception thrown will be 1) standardized, 2) >> specify the properties that are undefined on the target as a result of >> exceptions, and 3) provide those exceptions. That seems to be what we need >> to have any chance to use this feature. >> > > It is currently specified as a whatever exception is first thrown by an > operation upon an individual property. Those exceptions are specified at a > more primitive level. > > So the results are not in fact the same across browsers. The effect of upon the target object will be the same. The exception thrown (in the absence of the use of Proxies) will always be a TypeError. The only variations is which property might me named in the implementation dependent text that might be attached to such TypeErrors. > > > In general, the ES spec doesn't specify anything about thrown exception other > than which specific exception "class" to throw. It does not specify a > message or any other added payload. > > I'm not sure that there is an actual utilitarian use cause for this behavior. > > > That is my objection to the late-exception definition: unless you know which > properties failed and why, the mixin result is in an undefined state. The > details of the state are not useful. > > It is more about minimizing non-determinism that might impact > interoperability among implementations. > > IMO your best argument would be: >To insure interoperable implementations in the presence of unspecified > property order and property errors. Basically, that is the same argument. Except that the property errors are specified. It is the order that is unspecified. > > I think that argument is weak because all implementation should have the same > outcome in the presence of errors: the result is not useful. Nevertheless, I > can imaging a use for the interoperability in cross-browser test suites. > > > How would throwing early versus throwing late make any different to you? > > Because 1) late is a waste, the result is undefined anyway, 2) the exception > thrown is a lie, the operation did not die on the property reported but > continued and failed to die on an unreported number of subsequent properties/ Arguably, the operation didn't "die" at all. Instead it made a best effort to do everything that was requested that could possibly be done. I'll leave it to MarkM , if he wants to make more of a case. > > But if you've already decided this, let's move on: we need Object.mixin more > than we need one with any particular exception properties. > > jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Object.define ==> Object.mixin??
On Wed, Dec 12, 2012 at 11:20 AM, Allen Wirfs-Brock wrote: > > On Dec 12, 2012, at 10:52 AM, John J Barton wrote: > > > > > On Wed, Dec 12, 2012 at 10:44 AM, Allen Wirfs-Brock > wrote: > >> >> On Dec 12, 2012, at 10:23 AM, John J Barton wrote: >> >> >> >> >> On Wed, Dec 12, 2012 at 10:18 AM, Allen Wirfs-Brock < >> al...@wirfs-brock.com> wrote: >> >>> >>> On Dec 12, 2012, at 10:05 AM, Brandon Benvie wrote: >>> >>> All the Object functions that operate on multiple properties are >>> currently specified using *pendingException* which reports the first >>> thrown exception after going through all the properties. defineProperties, >>> freeze, etc. >>> >>> >>> In, ES6. This is a breaking (hopefully nothing) change from ES5 that >>> was suggested by Mark Miller. >>> >>> The desire is to decrease the non-determinism that an early throw >>> introduces. >>> >> >> How can multiple calls to Object.mixin with identical state result in >> different results? >> >> >> Because the order that the source properties are visited is unspecified. >> It can differ among implementations and in theory could even differ within >> a single implementation. >> >> >> >>> In the ES6 approach all property updates that can occur will occur, >>> before the exception is thrown instead of leaving the object in a less well >>> defined partially updated state. >>> >> >> If an exception is thrown because of an error in Object.mixin, what state >> is the object in? Will the spec define that state? >> >> >> Yes, all property additions (to the target object) that can complete >> will complete. >> > > And I assume then that the exception thrown will be 1) standardized, 2) > specify the properties that are undefined on the target as a result of > exceptions, and 3) provide those exceptions. That seems to be what we need > to have any chance to use this feature. > > > It is currently specified as a whatever exception is first thrown by an > operation upon an individual property. Those exceptions are specified at a > more primitive level. > So the results are not in fact the same across browsers. > > In general, the ES spec doesn't specify anything about thrown exception > other than which specific exception "class" to throw. It does not specify > a message or any other added payload. > > I'm not sure that there is an actual utilitarian use cause for this > behavior. > That is my objection to the late-exception definition: unless you know which properties failed and why, the mixin result is in an undefined state. The details of the state are not useful. > It is more about minimizing non-determinism that might impact > interoperability among implementations. > IMO your best argument would be: To insure interoperable implementations in the presence of unspecified property order and property errors. I think that argument is weak because all implementation should have the same outcome in the presence of errors: the result is not useful. Nevertheless, I can imaging a use for the interoperability in cross-browser test suites. > > How would throwing early versus throwing late make any different to you? > Because 1) late is a waste, the result is undefined anyway, 2) the exception thrown is a lie, the operation did not die on the property reported but continued and failed to die on an unreported number of subsequent properties/ But if you've already decided this, let's move on: we need Object.mixin more than we need one with any particular exception properties. jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Object.define ==> Object.mixin??
On Dec 12, 2012, at 10:52 AM, John J Barton wrote: > > > > On Wed, Dec 12, 2012 at 10:44 AM, Allen Wirfs-Brock > wrote: > > On Dec 12, 2012, at 10:23 AM, John J Barton wrote: > >> >> >> >> On Wed, Dec 12, 2012 at 10:18 AM, Allen Wirfs-Brock >> wrote: >> >> On Dec 12, 2012, at 10:05 AM, Brandon Benvie wrote: >> >>> All the Object functions that operate on multiple properties are currently >>> specified using pendingException which reports the first thrown exception >>> after going through all the properties. defineProperties, freeze, etc. >> >> In, ES6. This is a breaking (hopefully nothing) change from ES5 that was >> suggested by Mark Miller. >> >> The desire is to decrease the non-determinism that an early throw >> introduces. >> >> How can multiple calls to Object.mixin with identical state result in >> different results? > > Because the order that the source properties are visited is unspecified. It > can differ among implementations and in theory could even differ within a > single implementation. > >> >> In the ES6 approach all property updates that can occur will occur, before >> the exception is thrown instead of leaving the object in a less well defined >> partially updated state. >> >> If an exception is thrown because of an error in Object.mixin, what state is >> the object in? Will the spec define that state? > > Yes, all property additions (to the target object) that can complete will > complete. > > And I assume then that the exception thrown will be 1) standardized, 2) > specify the properties that are undefined on the target as a result of > exceptions, and 3) provide those exceptions. That seems to be what we need > to have any chance to use this feature. > It is currently specified as a whatever exception is first thrown by an operation upon an individual property. Those exceptions are specified at a more primitive level. In general, the ES spec doesn't specify anything about thrown exception other than which specific exception "class" to throw. It does not specify a message or any other added payload. I'm not sure that there is an actual utilitarian use cause for this behavior. It is more about minimizing non-determinism that might impact interoperability among implementations. How would throwing early versus throwing late make any different to you? Allen ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Object.define ==> Object.mixin??
I'd vote for replacing duplicate properties by default (as I tend to see this as the common case). That being said, the mixin functions I use tend to have an optional third argument that let's you change that behavior, such as: // regular Object.mixin(receiver,supplier); // safe Object.mixin(receiver, supplier, true); -N On 12/12/2012 11:13 AM, Allen Wirfs-Brock wrote: On Dec 12, 2012, at 10:10 AM, John J Barton wrote: On Wed, Dec 12, 2012 at 10:05 AM, Allen Wirfs-Brock mailto:al...@wirfs-brock.com>> wrote: On Dec 12, 2012, at 9:50 AM, John J Barton wrote: ... > But most of all we want this feature to land and not just spin around here. > > jjb As Object.mixin or as Object.define?? Object.mixin What should be the effect of trying to "mixin" a property that already exists (as an own property) of the target object. Object.define(target,src) would presumably have redefined such properties using the Object.defineProperty rules. Is that what Object.mixin should do. It could, have different rules. For example, it could simply replace an existing target property (if the existing property is configurable). Or it could skip existing properties or throw an error if a property exists. Replace is attractive, but it may or may not be what you want for accessor properties. Consider: var objTarget = {get foo() {/*target*/...}}); Object.mixin(objTarget, {set foo(v) {/*src*/...}}); after the mixin do you want objTarget to look like: {set foo(v) {/*src*/...}} //replace semantics gives you this or {set foo(v) {/*src*/...}, get foo() {/*target*/...} } //Object.defineProperty semantics gives you this Allen ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss -- ___ Nicholas C. Zakas http://www.nczonline.net ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Object.define ==> Object.mixin??
On Dec 12, 2012, at 10:10 AM, John J Barton wrote: > On Wed, Dec 12, 2012 at 10:05 AM, Allen Wirfs-Brock > wrote: > > On Dec 12, 2012, at 9:50 AM, John J Barton wrote: > ... > > But most of all we want this feature to land and not just spin around here. > > > > jjb > > As Object.mixin or as Object.define?? > > Object.mixin > What should be the effect of trying to "mixin" a property that already exists (as an own property) of the target object. Object.define(target,src) would presumably have redefined such properties using the Object.defineProperty rules. Is that what Object.mixin should do. It could, have different rules. For example, it could simply replace an existing target property (if the existing property is configurable). Or it could skip existing properties or throw an error if a property exists. Replace is attractive, but it may or may not be what you want for accessor properties. Consider: var objTarget = {get foo() {/*target*/...}}); Object.mixin(objTarget, {set foo(v) {/*src*/...}}); after the mixin do you want objTarget to look like: {set foo(v) {/*src*/...}} //replace semantics gives you this or {set foo(v) {/*src*/...}, get foo() {/*target*/...} } //Object.defineProperty semantics gives you this Allen ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Object.define ==> Object.mixin??
On Wed, Dec 12, 2012 at 10:44 AM, Allen Wirfs-Brock wrote: > > On Dec 12, 2012, at 10:23 AM, John J Barton wrote: > > > > > On Wed, Dec 12, 2012 at 10:18 AM, Allen Wirfs-Brock > wrote: > >> >> On Dec 12, 2012, at 10:05 AM, Brandon Benvie wrote: >> >> All the Object functions that operate on multiple properties are >> currently specified using *pendingException* which reports the first >> thrown exception after going through all the properties. defineProperties, >> freeze, etc. >> >> >> In, ES6. This is a breaking (hopefully nothing) change from ES5 that was >> suggested by Mark Miller. >> >> The desire is to decrease the non-determinism that an early throw >> introduces. >> > > How can multiple calls to Object.mixin with identical state result in > different results? > > > Because the order that the source properties are visited is unspecified. > It can differ among implementations and in theory could even differ within > a single implementation. > > > >> In the ES6 approach all property updates that can occur will occur, >> before the exception is thrown instead of leaving the object in a less well >> defined partially updated state. >> > > If an exception is thrown because of an error in Object.mixin, what state > is the object in? Will the spec define that state? > > > Yes, all property additions (to the target object) that can complete will > complete. > And I assume then that the exception thrown will be 1) standardized, 2) specify the properties that are undefined on the target as a result of exceptions, and 3) provide those exceptions. That seems to be what we need to have any chance to use this feature. jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Object.define ==> Object.mixin??
On Dec 12, 2012, at 10:23 AM, John J Barton wrote: > > > > On Wed, Dec 12, 2012 at 10:18 AM, Allen Wirfs-Brock > wrote: > > On Dec 12, 2012, at 10:05 AM, Brandon Benvie wrote: > >> All the Object functions that operate on multiple properties are currently >> specified using pendingException which reports the first thrown exception >> after going through all the properties. defineProperties, freeze, etc. > > In, ES6. This is a breaking (hopefully nothing) change from ES5 that was > suggested by Mark Miller. > > The desire is to decrease the non-determinism that an early throw introduces. > > > How can multiple calls to Object.mixin with identical state result in > different results? Because the order that the source properties are visited is unspecified. It can differ among implementations and in theory could even differ within a single implementation. > > In the ES6 approach all property updates that can occur will occur, before > the exception is thrown instead of leaving the object in a less well defined > partially updated state. > > If an exception is thrown because of an error in Object.mixin, what state is > the object in? Will the spec define that state? Yes, all property additions (to the target object) that can complete will complete. Allen > > jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Object.define ==> Object.mixin??
A contrived example but it demonstrates the problem Object.mixin({}, Proxy({ a: 5, b: 10, c: 20 }, { getOwnPropertyDescriptor(target, key){ if (key === 'b' && Math.random() * .5) { throw 'halt'; } return Reflect.getOwnPropertyDescriptor(target, key); } })); In ES5 rules there's no way to know whether 'c' will be in the returned object or not, so that demonstrates actual non-determinism. The more common case is a deterministic result that's unobvious to the developer as to be nearly the same effective result. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Enumerability is still important (was: Re: Object.define ==> Object.mixin??)
On Dec 11, 2012, at 10:42 AM, Herby Vojčík wrote: > > > Allen Wirfs-Brock wrote: >> 3) I don't see any reason that it should be restricted to enumerable >> properties. If the intend is to deprecate enumerable along with for-in >> then we should be adding new functionality that is sensitive to the >> state of the enumerable attribute. >> >> Allen > > Well, I had a real-world issue in which enumerability (and non-enumerability > of methods) was still important. > > In Amber, the Smalltalk implementation that compiles to JavaScript, there > were issues[1], which failed with jQuery.ajax call. The object passed as > options parameter was a HashedCollection, which mimicked JS object (keys as > strings etc.), but the methods inherited via prototype striked back. JQuery > read all properties (own as well as inherited), which makes sense, one can > have templates and Object.create() from them, Object.defineProperty also > honours inherited properties. > > But some of the inherited properties make this fail or eat 100%CPU. Similar > problem appeared with jQuery.css call (though I can't find an issue, it was > probably only on the mailinglist). > > The fix[2] was to make methods non-enumerable. Interesting... > > Now, jQuery takes enumerability (and I think not only jQuery does this) as a > rough equivalent of "published" so it treats enumerables as visible part of > object and non-enumerables are ignored for object-holding-some-data scenario. > > If enumerable is to be deprecated, how should this be solved? If jQuery stops > to honour inherited attributes, it would break Object.create()d data passed > in. If not, one cannot safely pass in instance of the class with method, > because methods will be included in the properties. Neither the enumerable attribute or for-in is going away. So, as long as jQuery keeps using for-in the Amber fix will be fine. The more interesting question is, in a future ES6 fully deployed world, what should jQuery use instead of for-in for the equivalent purpose and should the enumerable attribute have an effect upon it. Should it use the keys(obj) iterator function (or the Dict(obj).keys idiom discussed at the last TC39.meeting)? Should such "keys" functions/methods report non-enumerable properties? Probably, the most important question concerns whether user defined methods (particularly in class definitions) should be enumerable. The reason TC39 (rather abruptly) decided to switch from concise methods being non-enumerable to enumerable was because nobody had a full understanding for the full breadth of how the existing web depends upon enumerability. The jQuery usage is a good example. The prevailing argument is that in ES<=5.1 all user defined properties are enumerable (except those defined using Object.defineProperty and friends), so the safest thing is to continue that tradition and make properties defined via concise methods enumerable. For example, replacing: jquery.mixin({ foo: funtion() {}, bar: function() {} }); with jquery.mixin({ foo() {}, bar() {} }); shouldn't break anything. It's a bigger stretch, but the same logic applies to: jquery.mixin(new class { foo() {}, bar() {} }); If anybody has a strong counter argument, now would be the time to make it. Allen > > Thanks, Herby > > [1] https://github.com/NicolasPetton/amber/issues/217, > https://github.com/NicolasPetton/amber/issues/88 > [2] https://github.com/NicolasPetton/amber/pull/202 > ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Object.define ==> Object.mixin??
In order to know what the end state will be for any given property, you currently need to know whether every preceding property throws or not. With the ES6 change, there's no interdependence between properties as to whether they'll end up being visited or not. On Wed, Dec 12, 2012 at 1:23 PM, John J Barton wrote: > > > > On Wed, Dec 12, 2012 at 10:18 AM, Allen Wirfs-Brock > wrote: > >> >> On Dec 12, 2012, at 10:05 AM, Brandon Benvie wrote: >> >> All the Object functions that operate on multiple properties are >> currently specified using *pendingException* which reports the first >> thrown exception after going through all the properties. defineProperties, >> freeze, etc. >> >> >> In, ES6. This is a breaking (hopefully nothing) change from ES5 that was >> suggested by Mark Miller. >> >> The desire is to decrease the non-determinism that an early throw >> introduces. >> > > How can multiple calls to Object.mixin with identical state result in > different results? > > >> In the ES6 approach all property updates that can occur will occur, >> before the exception is thrown instead of leaving the object in a less well >> defined partially updated state. >> > > If an exception is thrown because of an error in Object.mixin, what state > is the object in? Will the spec define that state? > > jjb > ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Object.define ==> Object.mixin??
Yeah, it makes sense. If a property throws then you're going to end up with a partially completed action either way (unless the very first one fails in the ES5 rules), so it's better to fail predictably. While the iteration order of the keys is defined, in this case it's usually not useful for ending up in a predictable end state in the face of errors. On Wed, Dec 12, 2012 at 1:18 PM, Allen Wirfs-Brock wrote: > > On Dec 12, 2012, at 10:05 AM, Brandon Benvie wrote: > > All the Object functions that operate on multiple properties are currently > specified using *pendingException* which reports the first thrown > exception after going through all the properties. defineProperties, freeze, > etc. > > > In, ES6. This is a breaking (hopefully nothing) change from ES5 that was > suggested by Mark Miller. > > The desire is to decrease the non-determinism that an early throw > introduces. In the ES6 approach all property updates that can occur will > occur, before the exception is thrown instead of leaving the object in a > less well defined partially updated state. > > Allen > > > > > ___ > es-discuss mailing list > es-discuss@mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > > > ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Object.define ==> Object.mixin??
On Wed, Dec 12, 2012 at 10:18 AM, Allen Wirfs-Brock wrote: > > On Dec 12, 2012, at 10:05 AM, Brandon Benvie wrote: > > All the Object functions that operate on multiple properties are currently > specified using *pendingException* which reports the first thrown > exception after going through all the properties. defineProperties, freeze, > etc. > > > In, ES6. This is a breaking (hopefully nothing) change from ES5 that was > suggested by Mark Miller. > > The desire is to decrease the non-determinism that an early throw > introduces. > How can multiple calls to Object.mixin with identical state result in different results? > In the ES6 approach all property updates that can occur will occur, before > the exception is thrown instead of leaving the object in a less well > defined partially updated state. > If an exception is thrown because of an error in Object.mixin, what state is the object in? Will the spec define that state? jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Object.define ==> Object.mixin??
On Dec 12, 2012, at 10:05 AM, Brandon Benvie wrote: > All the Object functions that operate on multiple properties are currently > specified using pendingException which reports the first thrown exception > after going through all the properties. defineProperties, freeze, etc. In, ES6. This is a breaking (hopefully nothing) change from ES5 that was suggested by Mark Miller. The desire is to decrease the non-determinism that an early throw introduces. In the ES6 approach all property updates that can occur will occur, before the exception is thrown instead of leaving the object in a less well defined partially updated state. Allen > ___ > es-discuss mailing list > es-discuss@mozilla.org > https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Object.define ==> Object.mixin??
On Wed, Dec 12, 2012 at 10:05 AM, Allen Wirfs-Brock wrote: > > On Dec 12, 2012, at 9:50 AM, John J Barton wrote: > ... > > But most of all we want this feature to land and not just spin around > here. > > > > jjb > > As Object.mixin or as Object.define?? > Object.mixin jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Object.define ==> Object.mixin??
Brandon Benvie wrote: Works well as an arrow function due to not needing to turn it into a block body, although forEach and a comma would work too. Object.mixin = (target, source) => Object.keys(source).reduce((target, key) => Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)) ), target); Ah. Yeah. Guess I am really not very much functional. Probably the unneeded ever-copied same result-to-argument premature optimization was ringing, too. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Object.define ==> Object.mixin??
All the Object functions that operate on multiple properties are currently specified using *pendingException* which reports the first thrown exception after going through all the properties. defineProperties, freeze, etc. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Object.define ==> Object.mixin??
On Dec 12, 2012, at 9:50 AM, John J Barton wrote: ... > But most of all we want this feature to land and not just spin around here. > > jjb As Object.mixin or as Object.define?? Allen ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Object.define ==> Object.mixin??
On Wed, Dec 12, 2012 at 9:42 AM, Brandon Benvie wrote: > Ah yes errors. It should probably have similar semantics to how > defineProperties works now...attempting each property and holding errors > until the end, no? Same for assign. No, we want early errors and accurate line numbers. > > function mixin(target, source){ > if (Type(target) !== 'Object') throw new TypeError ("target must be an > object"); > No, Object.keys() will report TypeError: Object.keys called on non-object > if (Type(source) !== 'Object') throw new TypeError("source must be an > object"); > > var error; > Object.keys(source).forEach(function(key){ // or getOwnPropertyNames? > try { > Object.defineProperty(target, key, > Object.getOwnPropertyDescriptor(source, key)); > } catch (e) { > error || (error = e); > } > }); > > if (error) throw error; > return target; > } > But most of all we want this feature to land and not just spin around here. jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Object.define ==> Object.mixin??
a single property from a mixin that cannot be defined could compromise entirely the behavior so I would actually throw instantly then I believe no try catch is even necessary there, correct? On Wed, Dec 12, 2012 at 9:42 AM, Brandon Benvie wrote: > Ah yes errors. It should probably have similar semantics to how > defineProperties works now...attempting each property and holding errors > until the end, no? Same for assign. > > function mixin(target, source){ > if (Type(target) !== 'Object') throw new TypeError ("target must be an > object"); > if (Type(source) !== 'Object') throw new TypeError("source must be an > object"); > > var error; > Object.keys(source).forEach(function(key){ // or getOwnPropertyNames? > try { > Object.defineProperty(target, key, > Object.getOwnPropertyDescriptor(source, key)); > } catch (e) { > error || (error = e); > } > }); > > if (error) throw error; > return target; > } > > On Wednesday, December 12, 2012, Andrea Giammarchi wrote: >> >> >> also thinking about try/catch to avoid mixin overwrite ... I believe it's >> OK if that throws an error but then it should throw regardless if the >> target object had already that property defined ? >> >> ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Object.define ==> Object.mixin??
Ah yes errors. It should probably have similar semantics to how defineProperties works now...attempting each property and holding errors until the end, no? Same for assign. function mixin(target, source){ if (Type(target) !== 'Object') throw new TypeError ("target must be an object"); if (Type(source) !== 'Object') throw new TypeError("source must be an object"); var error; Object.keys(source).forEach(function(key){ // or getOwnPropertyNames? try { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); } catch (e) { error || (error = e); } }); if (error) throw error; return target; } On Wednesday, December 12, 2012, Andrea Giammarchi wrote: > > > also thinking about try/catch to avoid mixin overwrite ... I believe it's > OK if that throws an error but then it should throw regardless if the > target object had already that property defined ? > > ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Object.define ==> Object.mixin??
agreed, and actually one of the best case I've seen in a while for Array#reduce. Can I write this as it should be for those who'll read one day later on and making it also static ? "mixin" in Object || Object.defineProperty(Object, "mixin", { value: function mixin(target, source) { return Object.getOwnPropertyNames(source).reduce(function (target, name) { return Object.defineProperty( target, name, Object.getOwnPropertyDescriptor(source, name) ); }, target); } }); also thinking about try/catch to avoid mixin overwrite ... I believe it's OK if that throws an error but then it should throw regardless if the target object had already that property defined ? br On Wed, Dec 12, 2012 at 7:43 AM, Brandon Benvie wrote: > Works well as an arrow function due to not needing to turn it into a block > body, although forEach and a comma would work too. > > Object.mixin = (target, source) => > Object.keys(source).reduce((target, key) => > Object.defineProperty(target, key, > Object.getOwnPropertyDescriptor(source, key)) >), target); > > ___ > 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
Enumerability is still important (was: Re: Object.define ==> Object.mixin??)
Allen Wirfs-Brock wrote: 3) I don't see any reason that it should be restricted to enumerable properties. If the intend is to deprecate enumerable along with for-in then we should be adding new functionality that is sensitive to the state of the enumerable attribute. Allen Well, I had a real-world issue in which enumerability (and non-enumerability of methods) was still important. In Amber, the Smalltalk implementation that compiles to JavaScript, there were issues[1], which failed with jQuery.ajax call. The object passed as options parameter was a HashedCollection, which mimicked JS object (keys as strings etc.), but the methods inherited via prototype striked back. JQuery read all properties (own as well as inherited), which makes sense, one can have templates and Object.create() from them, Object.defineProperty also honours inherited properties. But some of the inherited properties make this fail or eat 100%CPU. Similar problem appeared with jQuery.css call (though I can't find an issue, it was probably only on the mailinglist). The fix[2] was to make methods non-enumerable. Now, jQuery takes enumerability (and I think not only jQuery does this) as a rough equivalent of "published" so it treats enumerables as visible part of object and non-enumerables are ignored for object-holding-some-data scenario. If enumerable is to be deprecated, how should this be solved? If jQuery stops to honour inherited attributes, it would break Object.create()d data passed in. If not, one cannot safely pass in instance of the class with method, because methods will be included in the properties. Thanks, Herby [1] https://github.com/NicolasPetton/amber/issues/217, https://github.com/NicolasPetton/amber/issues/88 [2] https://github.com/NicolasPetton/amber/pull/202 ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Object.define ==> Object.mixin??
Works well as an arrow function due to not needing to turn it into a block body, although forEach and a comma would work too. Object.mixin = (target, source) => Object.keys(source).reduce((target, key) => Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)) ), target); ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Object.define ==> Object.mixin??
Rick Waldron wrote: On Tue, Dec 11, 2012 at 12:28 PM, Allen Wirfs-Brock mailto:al...@wirfs-brock.com>> wrote: It also made me think that perhaps Object.mixin might be a more intuitive name for such a function. This name is certainly more real-word-friendly. The example code that follows "A pure ECMAScript 5 version of mixin() would be:" is basically what I imagined Object.define would be, but with a slight modification in that Object.assign returns the target object, so should Object.mixin: Yes. Object.mixin = function(receiver, supplier) { return Object.keys(supplier).reduce(function(receiver, property) { return Object.defineProperty( receiver, property, Object.getOwnPropertyDescriptor(supplier, property) ); }, receiver); }; I know this may look like a nitpick, but, why such clever code? I had the problem reading it (I just skipped it); I see no "reducing" process here. Maybe I am just not functional enough. I wouldn't use inject:into: when doing this in smalltalk, but do:. What's wrong with forEach followed by return receiver? Rick Herby ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Object.define ==> Object.mixin??
what I think is a very valid use case for mixins based on ES5 features var MixIt = Object.defineProperties({}, { name: { enumerable: true, get: function () { // notify or do stuff return this._name; }, set: function (_name) { // notify or do stuff this._name = _name; } }, _name: { writable: true } }); while super is unknown concept in ES5 but if de-sugared as Constructor.prototype.method.call(this, argN) in ES6 then is implicitly valid/doesn't need to be modified? br On Tue, Dec 11, 2012 at 10:29 AM, Rick Waldron wrote: > > > > On Tue, Dec 11, 2012 at 1:27 PM, Allen Wirfs-Brock > wrote: > >> >> 2) It needs to rebind super references >> >> 3) I don't see any reason that it should be restricted to enumerable >> >> properties. If the intend is to deprecate enumerable along with for-in >> then >> >> we should be adding new functionality that is sensitive to the state >> of the >> >> enumerable attribute. >> > >> > "should not"? >> >> Right, should not! >> > > To clarify, I assumed you meant "should not", based on the rationale and > that is what I was agreeing to. > > Rick > > > ___ > 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: Object.define ==> Object.mixin??
On Dec 11, 2012, at 10:19 AM, Andrea Giammarchi wrote: > Agreed, getOwnPropertyNames is way more appropriate if the topic is: use all > ES5 features for mixins too. > > Also, the Nicolas example is potentially disaster prone, not in that specific > form, but in the way a getter with private scope access could be. > > Imagine many objects using that specific object as mixin with that name > getter, if there was a setter too the first one that will use it will > overwrite the returned value for all other objects. > > I think propertie swith getters and setters will cause as many headaches as > objects and arrays in function prototypes did before already but hey, if you > know what you are doing, I believe there's no other solution for "universally > capable mixin method" I had a proposal for creating accessors that would only over-ride half of an inherited get/set pair: http://wiki.ecmascript.org/doku.php?id=harmony:object_initialiser_super#super_in_accessor_property_definitions I let it fade away because, 1) it was kind of ugly, and 2) there were other more important things to put energy into. Allen ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Object.define ==> Object.mixin??
On Tue, Dec 11, 2012 at 1:27 PM, Allen Wirfs-Brock wrote: > >> 2) It needs to rebind super references > >> 3) I don't see any reason that it should be restricted to enumerable > >> properties. If the intend is to deprecate enumerable along with for-in > then > >> we should be adding new functionality that is sensitive to the state of > the > >> enumerable attribute. > > > > "should not"? > > Right, should not! > To clarify, I assumed you meant "should not", based on the rationale and that is what I was agreeing to. Rick ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Object.define ==> Object.mixin??
On Dec 11, 2012, at 10:19 AM, Mark S. Miller wrote: > On Tue, Dec 11, 2012 at 10:12 AM, Allen Wirfs-Brock > wrote: >> >> >> Except, >> 1) It needs to iterate own keys, not just string valued property names so it >> will pick up properties whose keys are symbols >> 2) It needs to rebind super references >> 3) I don't see any reason that it should be restricted to enumerable >> properties. If the intend is to deprecate enumerable along with for-in then >> we should be adding new functionality that is sensitive to the state of the >> enumerable attribute. > > "should not"? Right, should not! Allen ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Object.define ==> Object.mixin??
On Tue, Dec 11, 2012 at 1:12 PM, Allen Wirfs-Brock wrote: > > On Dec 11, 2012, at 10:00 AM, Rick Waldron wrote: > > > > > On Tue, Dec 11, 2012 at 12:28 PM, Allen Wirfs-Brock > wrote: > >> I'm the past we discussed issues surrounding the semantic differences >> between "put" and "define" and we've agreed to include Object.assign in >> ES6. We have also discussed Object.define but have not yet made a decision >> to include it. >> >> Nicholas Zaka recently posted a short article that addresses issues >> relating to the assign/define distinction >> http://www.nczonline.net/blog/2012/12/11/are-your-mixins-ecmascript-5-compatible/ >> as they already surface in ES5. >> >> For me, this article reenforces that we really need to have something >> like Object.define in ES6. >> >> It also made me think that perhaps Object.mixin might be a more intuitive >> name for such a function. >> > > This name is certainly more real-word-friendly. > > The example code that follows "A pure ECMAScript 5 version of mixin() > would be:" is basically what I imagined Object.define would be, but with a > slight modification in that Object.assign returns the target object, so > should Object.mixin: > > > Except, > 1) It needs to iterate own keys, not just string valued property names so > it will pick up properties whose keys are symbols > 2) It needs to rebind super references > 3) I don't see any reason that it should be restricted to enumerable > properties. If the intend is to deprecate enumerable along with for-in then > we should be adding new functionality that is sensitive to the state of the > enumerable attribute. > Agreed with all three points. Rick > > Allen > > > > > > Object.mixin = function(receiver, supplier) { > return Object.keys(supplier).reduce(function(receiver, property) { > return Object.defineProperty( > receiver, property, Object.getOwnPropertyDescriptor(supplier, > property) > ); > }, receiver); > }; > > > var a = {}, name = "Rick"; > > var b = Object.mixin(a, { > get name() { > return name; > } > }); > > console.log( a.name ); // "Rick" > console.log( b.name ); // "Rick" > console.log( a === b ); // true > > > Rick > > > ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Object.define ==> Object.mixin??
On Tue, Dec 11, 2012 at 10:12 AM, Allen Wirfs-Brock wrote: > > On Dec 11, 2012, at 10:00 AM, Rick Waldron wrote: > > > > > On Tue, Dec 11, 2012 at 12:28 PM, Allen Wirfs-Brock > wrote: >> >> I'm the past we discussed issues surrounding the semantic differences >> between "put" and "define" and we've agreed to include Object.assign in ES6. >> We have also discussed Object.define but have not yet made a decision to >> include it. >> >> Nicholas Zaka recently posted a short article that addresses issues >> relating to the assign/define distinction >> http://www.nczonline.net/blog/2012/12/11/are-your-mixins-ecmascript-5-compatible/ >> as they already surface in ES5. >> >> For me, this article reenforces that we really need to have something like >> Object.define in ES6. >> >> It also made me think that perhaps Object.mixin might be a more intuitive >> name for such a function. > > > This name is certainly more real-word-friendly. > > The example code that follows "A pure ECMAScript 5 version of mixin() would > be:" is basically what I imagined Object.define would be, but with a slight > modification in that Object.assign returns the target object, so should > Object.mixin: > > > Except, > 1) It needs to iterate own keys, not just string valued property names so it > will pick up properties whose keys are symbols > 2) It needs to rebind super references > 3) I don't see any reason that it should be restricted to enumerable > properties. If the intend is to deprecate enumerable along with for-in then > we should be adding new functionality that is sensitive to the state of the > enumerable attribute. "should not"? > > Allen > > > > > > Object.mixin = function(receiver, supplier) { > return Object.keys(supplier).reduce(function(receiver, property) { > return Object.defineProperty( > receiver, property, Object.getOwnPropertyDescriptor(supplier, > property) > ); > }, receiver); > }; > > > var a = {}, name = "Rick"; > > var b = Object.mixin(a, { > get name() { > return name; > } > }); > > console.log( a.name ); // "Rick" > console.log( b.name ); // "Rick" > console.log( a === b ); // true > > > Rick > > > > ___ > es-discuss mailing list > es-discuss@mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Object.define ==> Object.mixin??
Agreed, getOwnPropertyNames is way more appropriate if the topic is: use all ES5 features for mixins too. Also, the Nicolas example is potentially disaster prone, not in that specific form, but in the way a getter with private scope access could be. Imagine many objects using that specific object as mixin with that name getter, if there was a setter too the first one that will use it will overwrite the returned value for all other objects. I think propertie swith getters and setters will cause as many headaches as objects and arrays in function prototypes did before already but hey, if you know what you are doing, I believe there's no other solution for "universally capable mixin method" br On Tue, Dec 11, 2012 at 10:12 AM, Allen Wirfs-Brock wrote: > > On Dec 11, 2012, at 10:00 AM, Rick Waldron wrote: > > > > > On Tue, Dec 11, 2012 at 12:28 PM, Allen Wirfs-Brock > wrote: > >> I'm the past we discussed issues surrounding the semantic differences >> between "put" and "define" and we've agreed to include Object.assign in >> ES6. We have also discussed Object.define but have not yet made a decision >> to include it. >> >> Nicholas Zaka recently posted a short article that addresses issues >> relating to the assign/define distinction >> http://www.nczonline.net/blog/2012/12/11/are-your-mixins-ecmascript-5-compatible/ >> as they already surface in ES5. >> >> For me, this article reenforces that we really need to have something >> like Object.define in ES6. >> >> It also made me think that perhaps Object.mixin might be a more intuitive >> name for such a function. >> > > This name is certainly more real-word-friendly. > > The example code that follows "A pure ECMAScript 5 version of mixin() > would be:" is basically what I imagined Object.define would be, but with a > slight modification in that Object.assign returns the target object, so > should Object.mixin: > > > Except, > 1) It needs to iterate own keys, not just string valued property names so > it will pick up properties whose keys are symbols > 2) It needs to rebind super references > 3) I don't see any reason that it should be restricted to enumerable > properties. If the intend is to deprecate enumerable along with for-in then > we should be adding new functionality that is sensitive to the state of the > enumerable attribute. > > Allen > > > > > > Object.mixin = function(receiver, supplier) { > return Object.keys(supplier).reduce(function(receiver, property) { > return Object.defineProperty( > receiver, property, Object.getOwnPropertyDescriptor(supplier, > property) > ); > }, receiver); > }; > > > var a = {}, name = "Rick"; > > var b = Object.mixin(a, { > get name() { > return name; > } > }); > > console.log( a.name ); // "Rick" > console.log( b.name ); // "Rick" > console.log( a === b ); // true > > > Rick > > > > ___ > 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: Object.define ==> Object.mixin??
On Dec 11, 2012, at 10:00 AM, Rick Waldron wrote: > > > > On Tue, Dec 11, 2012 at 12:28 PM, Allen Wirfs-Brock > wrote: > I'm the past we discussed issues surrounding the semantic differences between > "put" and "define" and we've agreed to include Object.assign in ES6. We have > also discussed Object.define but have not yet made a decision to include it. > > Nicholas Zaka recently posted a short article that addresses issues relating > to the assign/define distinction > http://www.nczonline.net/blog/2012/12/11/are-your-mixins-ecmascript-5-compatible/ > as they already surface in ES5. > > For me, this article reenforces that we really need to have something like > Object.define in ES6. > > It also made me think that perhaps Object.mixin might be a more intuitive > name for such a function. > > This name is certainly more real-word-friendly. > > The example code that follows "A pure ECMAScript 5 version of mixin() would > be:" is basically what I imagined Object.define would be, but with a slight > modification in that Object.assign returns the target object, so should > Object.mixin: Except, 1) It needs to iterate own keys, not just string valued property names so it will pick up properties whose keys are symbols 2) It needs to rebind super references 3) I don't see any reason that it should be restricted to enumerable properties. If the intend is to deprecate enumerable along with for-in then we should be adding new functionality that is sensitive to the state of the enumerable attribute. Allen > > Object.mixin = function(receiver, supplier) { > return Object.keys(supplier).reduce(function(receiver, property) { > return Object.defineProperty( > receiver, property, Object.getOwnPropertyDescriptor(supplier, property) > ); > }, receiver); > }; > > > var a = {}, name = "Rick"; > > var b = Object.mixin(a, { > get name() { > return name; > } > }); > > console.log( a.name ); // "Rick" > console.log( b.name ); // "Rick" > console.log( a === b ); // true > > > Rick > ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Object.define ==> Object.mixin??
On Tue, Dec 11, 2012 at 12:28 PM, Allen Wirfs-Brock wrote: > I'm the past we discussed issues surrounding the semantic differences > between "put" and "define" and we've agreed to include Object.assign in > ES6. We have also discussed Object.define but have not yet made a decision > to include it. > > Nicholas Zaka recently posted a short article that addresses issues > relating to the assign/define distinction > http://www.nczonline.net/blog/2012/12/11/are-your-mixins-ecmascript-5-compatible/ > as they already surface in ES5. > > For me, this article reenforces that we really need to have something like > Object.define in ES6. > > It also made me think that perhaps Object.mixin might be a more intuitive > name for such a function. > This name is certainly more real-word-friendly. The example code that follows "A pure ECMAScript 5 version of mixin() would be:" is basically what I imagined Object.define would be, but with a slight modification in that Object.assign returns the target object, so should Object.mixin: Object.mixin = function(receiver, supplier) { return Object.keys(supplier).reduce(function(receiver, property) { return Object.defineProperty( receiver, property, Object.getOwnPropertyDescriptor(supplier, property) ); }, receiver); }; var a = {}, name = "Rick"; var b = Object.mixin(a, { get name() { return name; } }); console.log( a.name ); // "Rick" console.log( b.name ); // "Rick" console.log( a === b ); // true Rick ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Object.define ==> Object.mixin??
Wholeheartedly agree with this. For library authoring it's a necessity, so a define like function is always the first thing in any .js file I make. The need for library authors is obvious but if I recall the conclusion was that those authors would be able to handle it themselves and to push off on codifying it into the language so popular patterns could emerge. I think that article well outlines how this is actually a need and concern in authoring of non-library code. Specifically, accessors are a part of the language (and are going to see more and more use as ES5 becomes the baseline) and in order to correctly handle those for structure-copying you must use descriptor-aware functions. On Tue, Dec 11, 2012 at 12:28 PM, Allen Wirfs-Brock wrote: > I'm the past we discussed issues surrounding the semantic differences > between "put" and "define" and we've agreed to include Object.assign in > ES6. We have also discussed Object.define but have not yet made a decision > to include it. > > Nicholas Zaka recently posted a short article that addresses issues > relating to the assign/define distinction > http://www.nczonline.net/blog/2012/12/11/are-your-mixins-ecmascript-5-compatible/ > as they already surface in ES5. > > For me, this article reenforces that we really need to have something like > Object.define in ES6. > > It also made me think that perhaps Object.mixin might be a more intuitive > name for such a function. > > Allen > > ___ > es-discuss mailing list > es-discuss@mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > > ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss