Re: Operator overloading for non-value objects
Le 13 janv. 2014 à 11:45, Anne van Kesteren ann...@annevk.nl a écrit : In a discussion I had with Alex Russell as how to do comparison for URL objects it ended up with desiring url == url2 to work. It escaped me at that point that I already discussed this briefly and Brendan explained why face-to-face. However, I forgot what he said :/ The alternative, either something like url.equals(url2) or URL.equal(url, url2) or url.toString() == url2.toString() is somewhat Java-esque. Is that what we should do? And if so, opinions on which variant? -- http://annevankesteren.nl/ ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss Consider the following objects: url, url2, ... : URL objects location, location2, ... : Location objects a, a2, : HTMLAnchorElement objects All these objects implement URLUtils according to the WhatWG specs, and are therefore stringified using their `href` attribute. Now, which one of these equalities should work by just comparing the stringification? url == url2 location == url location == location2 a == url a == location a == a2 For me, I couldn't say. But in any case, my intention is clearer (and not too Java-esque) by writing the following: a.href == location.href In the worst case, when I don't know if I have a string or an URLUtils object, I just ensure that at least one member of the equality operator is stringified—and, most importantly, that it is evident from reading my code that one member is stringified: a.href == url String(whatever) == url —Claude ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Operator overloading for non-value objects
In the worst case, when I don't know if I have a string or an URLUtils object, I just ensure that at least one member of the equality operator is stringified—and, most importantly, that it is evident from reading my code that one member is stringified: a.href == url String(whatever) == url Is an equality operator which requires one to remember such details a good, dependable equality operator? Does it really even express a meaningful concept of equality? Attaching more nuance on top of == via overloading seems like it will make things worse, not better. Brendan, can you provide a value class example which includes a user-defined ==? I'd like to see it in context. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Operator overloading for non-value objects
I think there are cases where the intent of `==` can be clear such Point2D or Point3D comparison, as well as generic collections. In this case I am simulating though `hasSamecontentOf` method what I think would be nice simplifying via `==` ```javascript function Collection(entries) { this.push.apply(this, entries); } Collection.prototype = Object.setPrototypeOf( { constructor: Collection, hasSameContentOf: function (collection) { return this.every(this._sameContentOf, collection); }, _sameContentOf: function (entry, i) { return entry === this[i]; // or a more generic and unoptimized // return -1 this.indexOf(entry); } }, Array.prototype ); var a = new Collection([1, 2, 3]), b = new Collection([1, 2, 3]), c = new Collection(a) ; alert( a.hasSameContentOf(b) b.hasSameContentOf(c) ); ``` In JS world we are use to compare via === so that when == is used instead we are usually in power user land, I don't see any conceptual shenanigans in doing something like above code. Long story short: `point2Da.x === point2Db.x point2Da.y === point2Db.y` all over the code, if somehow necessary, would probably not look as nice as `pointa == pointb` Being something new not possible in ES5 or ES3, I don't even see side effects or regressions that could affect old code: no oervload of `==` would be present so we are back to the good old known `==` meaning. my 2 cents On Tue, Jan 14, 2014 at 9:06 AM, Kevin Smith zenpars...@gmail.com wrote: In the worst case, when I don't know if I have a string or an URLUtils object, I just ensure that at least one member of the equality operator is stringified—and, most importantly, that it is evident from reading my code that one member is stringified: a.href == url String(whatever) == url Is an equality operator which requires one to remember such details a good, dependable equality operator? Does it really even express a meaningful concept of equality? Attaching more nuance on top of == via overloading seems like it will make things worse, not better. Brendan, can you provide a value class example which includes a user-defined ==? I'd like to see it in context. ___ 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: transpiling ES6 generator functions to ES5: what next?
Hi Ben, Sorry for the very late response. This is quite an interesting work, thanks for sharing! I'm particularly interested in your test suite [1] which is impressive. This is making me realize that generators are fully compilable (efficiently from what I can see) into ES5 and makes me wonder if the current generators specificities are worth it. Very specifically, do we really need Generator.prototype [ @@toStringTag ] === Generator ? From an author point of view, I don't really see in which situation this information could matter. As a comparison, functions generated after the class syntax do not have an @@toStringTag to Class. Generators would just be sugar to write iterators (+ .throw) Le 03/11/2013 21:55, Ben Newman a écrit : * Given that this tool will become obsolete as more and more engines implement ES6 generator functions, how can we maximize its value in the meantime? Are there grey areas in the draft spec that can be illuminated? Should I spend my time implementing (or getting others to implement) await syntax and/or control-flow libraries that leverage generator syntax? You can most certainly experiment with await syntax and share what you've learned. Are there any test cases that you've written and you feel like the expected spec behavior is odd or unintuitive in some aspect? * How would you design a system that selectively delivers transpiled code to ES5-capable browsers and native generator code to ES6-capable browsers, so that end users will benefit immediately when they upgrade to a browser with native support for generators? Since there is no semantic difference between the ES6 and your compiled version, it's unlikely the users will see a difference at all (not even sure the perf is that much different). But if you really want to try there are different options with different downsides. 1) Server-side UA sniffing. You get the User-Agent header, infer which browser it is and decide which version you should be sending. Send the ES5 version when you don't know the UA (safe default) Downsides: * if a browser changes its header, you may be sending the wrong version. This is a problem when you're sending the ES6 version to a non-ES6 browser (which admittedly should be a very rare case) * You need to update the list of ES6 User-Agent strings as new browsers arrive 2) Send a feature-detection JS snippet on the client which will decide which version to load. Downside: * having to wait until this snippet is executed to start code download (or one extra round-trip if code was originally inlined) 3) send compiler to the client-side Downside: * more code Personally, I'd go for sending the ES5 version to everyone. My second choice would be 1), but I guess it depends on the requirements. David [1] https://github.com/facebook/regenerator/blob/master/test/tests.es6.js ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Operator overloading for non-value objects
for correctness sake, I forgot to check `this.every()` after a `this.length === collection.length this.every(...)` On Tue, Jan 14, 2014 at 9:58 AM, Andrea Giammarchi andrea.giammar...@gmail.com wrote: I think there are cases where the intent of `==` can be clear such Point2D or Point3D comparison, as well as generic collections. In this case I am simulating though `hasSamecontentOf` method what I think would be nice simplifying via `==` ```javascript function Collection(entries) { this.push.apply(this, entries); } Collection.prototype = Object.setPrototypeOf( { constructor: Collection, hasSameContentOf: function (collection) { return this.every(this._sameContentOf, collection); }, _sameContentOf: function (entry, i) { return entry === this[i]; // or a more generic and unoptimized // return -1 this.indexOf(entry); } }, Array.prototype ); var a = new Collection([1, 2, 3]), b = new Collection([1, 2, 3]), c = new Collection(a) ; alert( a.hasSameContentOf(b) b.hasSameContentOf(c) ); ``` In JS world we are use to compare via === so that when == is used instead we are usually in power user land, I don't see any conceptual shenanigans in doing something like above code. Long story short: `point2Da.x === point2Db.x point2Da.y === point2Db.y` all over the code, if somehow necessary, would probably not look as nice as `pointa == pointb` Being something new not possible in ES5 or ES3, I don't even see side effects or regressions that could affect old code: no oervload of `==` would be present so we are back to the good old known `==` meaning. my 2 cents On Tue, Jan 14, 2014 at 9:06 AM, Kevin Smith zenpars...@gmail.com wrote: In the worst case, when I don't know if I have a string or an URLUtils object, I just ensure that at least one member of the equality operator is stringified—and, most importantly, that it is evident from reading my code that one member is stringified: a.href == url String(whatever) == url Is an equality operator which requires one to remember such details a good, dependable equality operator? Does it really even express a meaningful concept of equality? Attaching more nuance on top of == via overloading seems like it will make things worse, not better. Brendan, can you provide a value class example which includes a user-defined ==? I'd like to see it in context. ___ 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: Operator overloading for non-value objects
In JS world we are use to compare via === so that when == is used instead we are usually in power user land, I don't see any conceptual shenanigans in doing something like above code. Only power users use == because it has weird conversion semantics that are hard to internalize. == doesn't map to any simple relational concept, certainly not equality: ({}) == [object Object]; // true So if a user is going to overload ==, are they going to maintain those bizarre semantics? If so, then crazy-pants. If not, then it seems like we have introduced a hazard into code that is generic with respect to the types of operands to which == is applied. Sometimes crazy conversion semantics, sometimes sensible equality semantics. I'll stop there, because I don't know the details of the proposal. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Operator overloading for non-value objects
Kevin Smith wrote: Your point about it being too late to salvage == (vs. ===) is good, but perhaps with value objects plus further work to disable implicit conversions, == will make a come-back -- but that's far down the road. Work to disable implicit conversions? Can you clarify? It's a gleam in my eye, at least. Some day we may enable users to choose to get exception, not toString, on myUrl == haha. Details TBD, and not via valueOf/toString hacking (which doesn't quite work). I'm actually quite wary (so far) of allowing the user to override an operator whose abstract meaning is already so abstruse. You've seen the rationale, here it is again: == is overloadable along with and = to cope with unordered values and to enable common safe comparisons, e.g. 0m == 0. != and ! cannot be overloaded, to preserve De Morgan's Laws and other obvious invariants. There is no abstruseness in x == y when typeof-types match. Even when they don't, for numeric types, the relationals and == are loose. We won't change that. Adding value objects should afford new numeric types the same expressiveness that number has, or usability impairments will hamper adoption. If it's ok to test !0 or even 0 == 0 (yes, I know == is not transitive in full), then 0m == 0 or 0n == 0 should be supported too. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: Operator overloading for non-value objects
JavaScript is in a sticky place, it seems. `===` should mean strict equality (modulo `-0`/`+0` and `NaN`, unfortunately), so just like `0 !== 0`, we want `0 !== 0m`. That is, `===` won't be right for comparing numeric types, once we have multiple numeric types. However, `==` already means way-too-sloppy equality: `0 == 0`. Thus, even if we get operator overloading to give us `0 == 0m`, its usefulness is reduced, since we can't trust `==` unless we know both types are compatible (e.g. both numeric, or both immutable URL instances). An operator that is sometimes annoyingly sloppy, and sometimes usefully lenient, is going to be hard to use (power users only). What we're missing is the equality operator most languages have: neither too strict, nor too sloppy. One that gives `(0 op 0m) === true`, but `(0 op 0) === false`. This could be achieved, I suppose, by allowing overriding of `===`. But is it OK for `0 === 0m`? Probably not, right? Especially since `0m` is a value object, and we try to let `===` applied to objects mean reference equality. So we're kind of screwed. We could always [927 it][1], and invent a new operator with the most useful semantics. (The return of `is`? ``? `=dwim=`?) Alongside `==`, `===`, SameValue, and SameValueZero, that'd make 5 notions of equality in ES. Seems bad. I come back to my kind of screwed thesis. [1]: http://xkcd.com/927/ From: Brendan Eich bren...@mozilla.com Sent: Tuesday, January 14, 2014 14:55 To: Kevin Smith Cc: Domenic Denicola; es-discuss Subject: Re: Operator overloading for non-value objects Kevin Smith wrote: Your point about it being too late to salvage == (vs. ===) is good, but perhaps with value objects plus further work to disable implicit conversions, == will make a come-back -- but that's far down the road. Work to disable implicit conversions? Can you clarify? It's a gleam in my eye, at least. Some day we may enable users to choose to get exception, not toString, on myUrl == haha. Details TBD, and not via valueOf/toString hacking (which doesn't quite work). I'm actually quite wary (so far) of allowing the user to override an operator whose abstract meaning is already so abstruse. You've seen the rationale, here it is again: == is overloadable along with and = to cope with unordered values and to enable common safe comparisons, e.g. 0m == 0. != and ! cannot be overloaded, to preserve De Morgan's Laws and other obvious invariants. There is no abstruseness in x == y when typeof-types match. Even when they don't, for numeric types, the relationals and == are loose. We won't change that. Adding value objects should afford new numeric types the same expressiveness that number has, or usability impairments will hamper adoption. If it's ok to test !0 or even 0 == 0 (yes, I know == is not transitive in full), then 0m == 0 or 0n == 0 should be supported too. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Operator overloading for non-value objects
== is overloadable along with and = to cope with unordered values and to enable common safe comparisons, e.g. 0m == 0. What does 0m === 0 mean? ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: Operator overloading for non-value objects
`0m` is literal syntax, for `decimal(0)`. Where `decimal` is a value type factory. http://www.slideshare.net/BrendanEich/web-futures/23 ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Operator overloading for non-value objects
`0m` is literal syntax, for `decimal(0)`. Where `decimal` is a value type factory. Right - I meant what are the semantics of === applied to dissimilar, perhaps numeric, value types. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Operator overloading for non-value objects
Kevin Smith wrote: `0m` is literal syntax, for `decimal(0)`. Where `decimal` is a value type factory. Right - I meant what are the semantics of === applied to dissimilar, perhaps numeric, value types. We worked through this in 2008 when IBM was pushing decimal at ES3.1 (now ES5). We do not want 0m === 0 for many reasons, including the relation typeof x == typeof y x == y = x === y We also didn't want problems of cohorts differing by significance (1.0m vs. 1m, if you can believe it) being equated to 1 (the number). This is one of the reasons I've designed value objects (so far) to allow typeof customization. (The other is because typeof is *useful* in numeric contexts, and making all non-number numerics have typeof-type object is useless, a disservice to users.) There is nothing wrong in my view with well-written == usage. I'm not Crock. I don't say always use ===. While opinions vary, the fact remains that == and = are in the language, are loose, and need to be overloadable for useful value objects, specifically more numeric types. Suggest you pull == out of your mental penalty box and look at it again. It's not a recidivist. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Operator overloading for non-value objects
if you are not sure and you expect == to act like === within objects / types then just use === and leave == for checks behind the typoef as Brendan said. Once again, let power users have the control they'd like to, specifications should not prevent people from shooting their foot when/if they want/need to ;-) it's not a spec matter, still IMO On Tue, Jan 14, 2014 at 11:37 AM, Kevin Smith zenpars...@gmail.com wrote: If power users would like to compare via == when they are aware of operator overload for used classes then I don't see any problem. If you know the operand types already, then there's no problem. But in cases where you don't control the operand types how will you know the semantics that == will provide? What does the following mean? if (maybeCollection1 == maybeCollection2) { ... } Operators overload worked for power users in many other languages and I think if not abused it can be very handy. In general, I agree. But in the specific case of == I'm not sure we have a solid foundation to build upon. How do you meaningfully overload a language element that, arguably, carries no useful meaning? Once again, just my 2 cents Mine too - we need to wait for a proposal before going any further. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Operator overloading for non-value objects
While opinions vary, the fact remains that == and = are in the language, are loose, and need to be overloadable for useful value objects, specifically more numeric types. I agree, that must be a goal of the design. Suggest you pull == out of your mental penalty box and look at it again. It's not a recidivist. Says the one trying to let him out! : ) ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Operator overloading for non-value objects
Kevin Smith wrote: While opinions vary, the fact remains that == and = are in the language, are loose, and need to be overloadable for useful value objects, specifically more numeric types. I agree, that must be a goal of the design. Suggest you pull == out of your mental penalty box and look at it again. It's not a recidivist. Says the one trying to let him out! http://www.hulu.com/watch/12740 *Okay* then! /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Operator overloading for non-value objects
So glad you asked, and you will like the answer: js 0L == 0 typein:2:0 TypeError: no operator function found for == ...and..I..do : ) http://goo.gl/N5txLJ - The strict equality operators, === and !==, cannot be overloaded - They work on frozen-by-definition value objects via a structural recursive strict equality test (beware, NaN !== NaN) - Same-object-reference remains a fast-path optimization Looks pretty solid to me - thanks! ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: Operator overloading for non-value objects
From: es-discuss [mailto:es-discuss-boun...@mozilla.org] On Behalf Of Brendan Eich js 0L == 0 typein:2:0 TypeError: no operator function found for == Hmm, upon seeing this in action, I'm not sure how I feel about `==` throwing. It doesn't normally do that (modulo bad custom `valueOf`/`toString` methods), so I think there will be a lot of code that assumes when it `==`s two values it doesn't need to wrap that expression in `try`/`catch`. `do { try { x == y } catch { false } }`, the new `x == y`? ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Operator overloading for non-value objects
Domenic Denicola wrote: From: es-discuss [mailto:es-discuss-boun...@mozilla.org] On Behalf Of Brendan Eich js 0L == 0 typein:2:0 TypeError: no operator function found for == Hmm, upon seeing this in action, I'm not sure how I feel about `==` throwing. Oh for crying out loud! half a :-) You can't please anyone around here... It doesn't normally do that (modulo bad custom `valueOf`/`toString` methods), so I think there will be a lot of code that assumes when it `==`s two values it doesn't need to wrap that expression in `try`/`catch`. `do { try { x == y } catch { false } }`, the new `x == y`? So what? Exceptions for the insane (intransitive, lossy) == cases are *better* than toString/valueOf. JS is damned if it does, and damned if it doesn't. Anyway, value objects are not dispatching to toString or valueOf when used with arithmetic operators. That's the design. Given == and =, the rest follows. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: Operator overloading for non-value objects
Heh, yes, damned if you do, etc. etc. I was trying to think up a practical example where this would cause problems (e.g. in CSS libraries strings and numbers often mix), but all my cases involved an `==`-using third party library, in which case you'd just pass it `Number(myLong)` instead of `myLong` directly and move on with your life. -Original Message- From: Brendan Eich [mailto:bren...@mozilla.com] Sent: Tuesday, January 14, 2014 21:48 To: Domenic Denicola Cc: Kevin Smith; es-discuss Subject: Re: Operator overloading for non-value objects Domenic Denicola wrote: From: es-discuss [mailto:es-discuss-boun...@mozilla.org] On Behalf Of Brendan Eich js 0L == 0 typein:2:0 TypeError: no operator function found for == Hmm, upon seeing this in action, I'm not sure how I feel about `==` throwing. Oh for crying out loud! half a :-) You can't please anyone around here... It doesn't normally do that (modulo bad custom `valueOf`/`toString` methods), so I think there will be a lot of code that assumes when it `==`s two values it doesn't need to wrap that expression in `try`/`catch`. `do { try { x == y } catch { false } }`, the new `x == y`? So what? Exceptions for the insane (intransitive, lossy) == cases are *better* than toString/valueOf. JS is damned if it does, and damned if it doesn't. Anyway, value objects are not dispatching to toString or valueOf when used with arithmetic operators. That's the design. Given == and =, the rest follows. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Operator overloading for non-value objects
Domenic Denicola wrote: Heh, yes, damned if you do, etc. etc. I was trying to think up a practical example where this would cause problems (e.g. in CSS libraries strings and numbers often mix), but all my cases involved an `==`-using third party library, in which case you'd just pass it `Number(myLong)` instead of `myLong` directly and move on with your life. Wait, number works: js 0L == 0 true js 0L + 1 1L Are you thinking of string? /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Operator overloading for non-value objects
I was thinking of function thirdPartyLib(val) { return val == 0; } thirdPartyLib(myLong); // exception thirdPartyLib(Number(myLong)); // works On Jan 14, 2014, at 22:50, Brendan Eich bren...@mozilla.com wrote: Domenic Denicola wrote: Heh, yes, damned if you do, etc. etc. I was trying to think up a practical example where this would cause problems (e.g. in CSS libraries strings and numbers often mix), but all my cases involved an `==`-using third party library, in which case you'd just pass it `Number(myLong)` instead of `myLong` directly and move on with your life. Wait, number works: js 0L == 0 true js 0L + 1 1L Are you thinking of string? /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Operator overloading for non-value objects
That code deserves what it gets, good and hard. Including exceptions. /be On Jan 14, 2014, at 8:01 PM, Domenic Denicola wrote: I was thinking of function thirdPartyLib(val) { return val =0; } thirdPartyLib(myLong); // exception thirdPartyLib(Number(myLong)); // works On Jan 14, 2014, at 22:50, Brendan Eich wrote: Domenic Denicola wrote: Heh, yes, damned if you do, etc. etc. I was trying to think up a practical example where this would cause problems (e.g. in CSS libraries strings and numbers often mix), but all my cases involved an `=-using third party library, in which case you'd just pass it `Number(myLong)` instead of `myLong` directly and move on with your life. Wait, number works: js 0L =0 true js 0L + 1 1L Are you thinking of string? /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Operator overloading for non-value objects
At risk of derailing the conversation with a tangent... I don't understand the premise. Why is it so important that URLs are mutable? (Other than already being drafted that way.) We're seeing major performance and reliably improvements by going for more immutable types in both our server and client apps. The React library relies heavily on the properties of immutability. In fact, we even want to prevent our developers from using existing mutable APIs that are known to be error prone. Primarily Date which is a terrible mutable API. We would like to see more DOM and ES APIs embrace immutability. In the future we would also like to propose more convenience APIs, performance improvements and possibly syntax for making immutable data (such as persistent data structures) easier to work with. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss