Good point. In my original post I mentioned introducing a `"use overloading"` directive. We could throw when trying to use this directive with the `"use asm"` directive.
We can definitely wait on this. Definitely looking forward to static typing. Is https://github.com/sirisian/ecmascript-types the proposal to be following? On Thu, May 19, 2016 at 12:35 PM, Isiah Meadows <isiahmead...@gmail.com> wrote: > That is a valid concern. As good as having this feature might sound, could > this discussion be revisited after static types are addressed and we see > how WebAssembly pans out? The reason I ask the latter is because of the > above concern about asm.js, which WebAssembly aims to replace in an IMHO > far superior way. Depending on the uptake of WebAssembly a few years down > the road, it may later become practical to break forward compatibility in > that way due to lack of usage. It's not a common use case, though, to send > an object of unknown type to an asm.js function, and replacing native > methods fails validation, so the risk isn't as high as it might seem. > > On Thu, May 19, 2016, 12:36 John Lenz <concavel...@gmail.com> wrote: > >> I have some concerns. With the short circuiting operators: >> >> Commutative operators, +, *, &&, ||, &, |, ^, automatically flip >> the order of operands when their types are different. >> >> && and || can not "flip" and routing them through a method is not >> compatible with short-circuiting. >> >> Generally, there are a lot of things that can go wrong in interop with >> existing code: unlike some other languages in JavaScript operators are >> often used to coerse to a know type: "+value" to a number, "x|0" to an >> 32-bit integer, etc. These kinds of guarantees are what "asm.js" is based >> on, for example, and having to wait until type feedback is available to >> perform its optimizations is likely to be a non-starter. >> >> >> >> >> >> >> >> On Tue, May 17, 2016 at 10:30 PM, Kevin Barabash <kev...@khanacademy.org> >> wrote: >> >>> > I'm thinking, instead, static methods should be used. It would be >>> more versatile. >>> >>> I like the idea of passing both operands as arguments (mainly from an >>> aesthetics/symmetry point of view), but I can't think of case where it >>> would be more versatile than instance methods seeing as at least one >>> argument has to be `this`. Could you give an example of when this would be >>> more versatile? >>> >>> Since the new syntax is describing what each type should be, maybe we >>> could leverage existing type syntax from Flow/TypeScript. >>> >>> ```js >>> class Vec2 { >>> constructor(x, y) { >>> this.x = x >>> this.y = y >>> } >>> >>> operator+ (x: Vec2, y: Vec2) { >>> return new this(x.x + y.x, x.y + y.y) >>> } >>> >>> operator+ (x: Vec2, y: number) { >>> return new this(x.x + y, x.y + y) >>> } >>> >>> operator+= (x: Vec2, y: Vec2) { >>> x.x += y.x >>> x.y += y.y >>> } >>> >>> operator+= (x: Vec2, y: number) { >>> x.x += y >>> x.y += y >>> } >>> >>> // #number += this -> x = x + this >>> >>> operator- (x: Vec2) { >>> return new this(-x.x, -x.y) >>> } >>> >>> // etc... >>> } >>> >>> class Vec3 { >>> // ... >>> operator+ (x: Vec3, y: Vec2) { >>> return new this(x.x + y.x, x.y + y.y, x.z) >>> } >>> // etc... >>> } >>> ``` >>> >>> >>> >>> On Mon, May 16, 2016 at 12:33 PM, Isiah Meadows <isiahmead...@gmail.com> >>> wrote: >>> >>>> If both have the operator, the left side would be used (I thought I >>>> said that, but I may have not). I'm thinking, instead, static methods >>>> should be used. It would be more versatile. >>>> >>>> ```js >>>> class Vec2 { >>>> constructor(x, y) { >>>> this.x = x >>>> this.y = y >>>> } >>>> >>>> // `this` and `Vec2` are interchangeable >>>> operator this + this(x, y) { >>>> return new this(x.x + y.x, x.y + y.y) >>>> } >>>> >>>> operator this + #number(x, y) { >>>> return new this(x.x + y, x.y + y) >>>> } >>>> >>>> operator this += this(x, y) { >>>> x.x += y.x >>>> x.y += y.y >>>> } >>>> >>>> operator this += #number(x, y) { >>>> x.x += y >>>> x.y += y >>>> } >>>> >>>> // #number += this -> x = x + this >>>> >>>> operator -this(x) { >>>> return new this(-x.x, -x.y) >>>> } >>>> >>>> // etc... >>>> } >>>> >>>> class Vec3 { >>>> // ... >>>> operator this + Vec2(x, y) { >>>> return new this(x.x + y.x, x.y + y.y, x.z) >>>> } >>>> // etc... >>>> } >>>> ``` >>>> >>>> A few notes on this: >>>> >>>> 1. If an operator doesn't reference `this` or the containing class at >>>> least once, an early error is thrown. >>>> 2. To reference a primitive, you use the hash symbol + the typeof >>>> value. The valid ones include `#string`, `#boolean`, `#number`, `#symbol`, >>>> `#object`, `#function`, and `#undefined`. If value types with custom >>>> `typeof` values are introduced, you have to reference the type directly. >>>> 3. All type references must be either `this`, identifiers, or member >>>> expressions that do not reference `this`. It is an early error otherwise. >>>> Member expressions are evaluated at class definition time as well, so that >>>> can produce visible side effects if a proxy is referenced or a getter is >>>> called. >>>> 4. The operators are checked via `instanceof`. This means, for those >>>> that define operators, the behavior can become visible to previous code if >>>> the other type specified has a static `Symbol.hasInstance` method. >>>> >>>> The reason I provided the `this` alias is for anonymous classes, so you >>>> can create anonymous objects. It's also helpful in case you have a longer >>>> class name (possibly by convention) that you now don't have to type out. >>>> >>>> >>>> On Thu, May 12, 2016, 01:17 Kevin Barabash <kev...@khanacademy.org> >>>> wrote: >>>> >>>>> @Isiah: Great points. One potential edge case though: >>>>> >>>>> ```js >>>>> class A { >>>>> operator+ (other) { } >>>>> } >>>>> >>>>> class B { >>>>> operator+ (other) { } >>>>> } >>>>> >>>>> const a = new A(); >>>>> const b = new B(); >>>>> const c = a + b; >>>>> ``` >>>>> >>>>> In the case where both the left and right side have `[[OpPlus]]` do we >>>>> prefer the left side? >>>>> >>>>> > But, do we really need operator overloading? A method can be used >>>>> instead, I think. >>>>> >>>>> @Dawid: Suppose I create a class to represent complex numbers that >>>>> looks like this: >>>>> >>>>> ```js >>>>> class Complex { >>>>> constructor(re, im) { >>>>> Object.assign({ }, { re, im }); >>>>> } >>>>> add(other) { >>>>> return new Complex(this.re + other.re, this.im + other.im); >>>>> } >>>>> ... >>>>> } >>>>> ``` >>>>> >>>>> I might want to create instance of `Complex` with plain old numbers or >>>>> I might want to use `BigNumber` instances. >>>>> Without operator overloading this means that I would have add methods >>>>> to `Number.prototype` or wrap each number >>>>> in an object with methods. Neither of which are particular appealing. >>>>> >>>>> >>>>> >>>>> On Wed, May 11, 2016 at 1:28 AM, Isiah Meadows <isiahmead...@gmail.com >>>>> > wrote: >>>>> >>>>>> That's the current state of things. I think the main issue at hand is >>>>>> ergonomics. Haskell, the MLs, and Swift solved it by allowing inline >>>>>> functions and operators as functions (that wouldn't work in a dynamic >>>>>> language). Scala solved it by magic methods for unary operations and the >>>>>> fact nearly every character is a valid identifier for binary ones (JS >>>>>> can't >>>>>> use that because of back compat issues). Lua, Ruby, Python, and Kotlin >>>>>> solved it by using magic methods. C++ solved it with the `operator` >>>>>> keyword. >>>>>> >>>>>> On Wed, May 11, 2016, 03:26 Dawid Szlachta < >>>>>> dawidmj.szlac...@gmail.com> wrote: >>>>>> >>>>>>> But, do we really need operator overloading? A method can be used >>>>>>> instead, I think. >>>>>>> >>>>>>> 2016-05-11 8:53 GMT+02:00 Isiah Meadows <isiahmead...@gmail.com>: >>>>>>> >>>>>>>> Efficiency and optimization. If you're stupid enough to want to >>>>>>>> violate those priorities in a public API, it's your own fault. But if >>>>>>>> you >>>>>>>> want to optimize updating a collection (i.e. zero allocation update >>>>>>>> for a >>>>>>>> persistent map) or increment a vector by another without having to >>>>>>>> create >>>>>>>> an intermediate vector, you'll want to implement the assignment >>>>>>>> operator as >>>>>>>> well as the standard math operator. >>>>>>>> >>>>>>>> On Wed, May 11, 2016, 02:46 Jordan Harband <ljh...@gmail.com> >>>>>>>> wrote: >>>>>>>> >>>>>>>>> Why would you ever want to violate the algebraic properties of >>>>>>>>> operators, such that `a += b` wasn't exactly equivalent to `a = a + >>>>>>>>> b`, `a >>>>>>>>> *= b` not equivalent to `a = a * b`, etc? I'm quite confident that any >>>>>>>>> proposal that allowed for that would get tons of pushback. >>>>>>>>> >>>>>>>>> On Tue, May 10, 2016 at 11:26 PM, Isiah Meadows < >>>>>>>>> isiahmead...@gmail.com> wrote: >>>>>>>>> >>>>>>>>>> 1. Yes, they would be inherited, but not on the prototype itself >>>>>>>>>> (it would technically be parasitic). It would be modeled with >>>>>>>>>> internal >>>>>>>>>> slots, so that the properties are themselves immutable and >>>>>>>>>> transparent, so >>>>>>>>>> the only way to inherit would be via the class syntax or >>>>>>>>>> `Reflect.construct`. Engines could model this similarly to prototypes >>>>>>>>>> internally, while still appearing to conform to spec, since there's >>>>>>>>>> no >>>>>>>>>> other way to access the function without explicit reference via a >>>>>>>>>> decorator. And if it's not decorated, you can transparently fast >>>>>>>>>> path the >>>>>>>>>> calls automatically and optimize the function at compile time for >>>>>>>>>> exactly >>>>>>>>>> the number of arguments (any different is a syntax error, like with >>>>>>>>>> getters >>>>>>>>>> and setters). >>>>>>>>>> >>>>>>>>>> 2. I'm intentionally trying to avoid any semantics that would >>>>>>>>>> rely on adding more values to the global scope. First, it's harder to >>>>>>>>>> optimize a `hasOwnProperty` check. Second, when you allow properties >>>>>>>>>> to be >>>>>>>>>> dynamically added, you make it impossible to lower `foo + bar` to a >>>>>>>>>> single >>>>>>>>>> instruction if they're both numbers, because someone can change the >>>>>>>>>> Number >>>>>>>>>> prototype to have one of the operators on it, and now, the >>>>>>>>>> assumption, >>>>>>>>>> previously prevalent, is now invalid. Third, we shouldn't need to >>>>>>>>>> add 15+ >>>>>>>>>> new symbols to accommodate a simple operation. >>>>>>>>>> >>>>>>>>>> 3. If it's pure syntax, you won't have the edge cases of `x += y` >>>>>>>>>> having to desugar to `x = x[Symbol.assignPlus](y)` and so on. You >>>>>>>>>> just look >>>>>>>>>> for an `[[OpAssignPlus]]` on `x`, and if it exists, call it as >>>>>>>>>> `x.[[OpAssignPlus]](y)`. >>>>>>>>>> Else, you check for `[[OpPlus]]`, and set `x` to `x.[[OpPlus]](y)`. >>>>>>>>>> If >>>>>>>>>> neither exists, you fall back to the old algorithm. This can be >>>>>>>>>> easily >>>>>>>>>> optimized by the fact engines only need to check this if the value >>>>>>>>>> is an >>>>>>>>>> object. Numbers and strings don't have this slot. >>>>>>>>>> >>>>>>>>>> Note: If the right side has an operator defined, but the left >>>>>>>>>> side doesn't, and if the operator checked for isn't an assignment >>>>>>>>>> one, the >>>>>>>>>> right side's operator is checked and called. Or basically, beyond >>>>>>>>>> assignment, the mere existence of a slot takes precedence over no >>>>>>>>>> slot, to >>>>>>>>>> make transitivity easier with primitives. To clarify, in the below >>>>>>>>>> case: >>>>>>>>>> >>>>>>>>>> ```js >>>>>>>>>> class C { >>>>>>>>>> constructor(x) { this.x = x } >>>>>>>>>> operator +(x) { >>>>>>>>>> if (x instanceof C) { >>>>>>>>>> return this + x.x * 2 >>>>>>>>>> } >>>>>>>>>> return this.x + x >>>>>>>>>> } >>>>>>>>>> } >>>>>>>>>> >>>>>>>>>> assert(new C(1) + 1 === 1 +1) >>>>>>>>>> assert(1 + new C(1) === 1 + 1) >>>>>>>>>> assert(new C(1) + new C(2) === 1 + 2*2) >>>>>>>>>> assert(new C(2) + new C(1) === 2 + 1*2) >>>>>>>>>> ``` >>>>>>>>>> >>>>>>>>>> On Wed, May 11, 2016, 01:27 Kevin Barabash < >>>>>>>>>> kev...@khanacademy.org> wrote: >>>>>>>>>> >>>>>>>>>>> > I would prefer syntax + internal slots, since you'll know at >>>>>>>>>>> creation time whether the object has overloaded >>>>>>>>>>> > operators. It's much simpler for the engine to figure out, and >>>>>>>>>>> it's more performant because you only need to >>>>>>>>>>> > check one thing instead of worrying about inheritance, own >>>>>>>>>>> properties, etc. >>>>>>>>>>> >>>>>>>>>>> Will operators defined on a class work with instances of a >>>>>>>>>>> subclass? >>>>>>>>>>> >>>>>>>>>>> > Could += be a special case? i.e., >>>>>>>>>>> >>>>>>>>>>> For sure. We could define `Symbol.assignPlus`, >>>>>>>>>>> `Symbol.assignTimes`, etc. with `u += v;` desugaring to `u = >>>>>>>>>>> u[Symbol.assignPlus](v)`. The reason why we can't do something do >>>>>>>>>>> `u[Symbol.assignPlus](v)` is that there's no way to define a method >>>>>>>>>>> on >>>>>>>>>>> Number, String, etc. that would reassign their value. >>>>>>>>>>> >>>>>>>>>>> > it appears to me that overloading an operator multiple times >>>>>>>>>>> (e. g. unary/binary plus operator) might become >>>>>>>>>>> > painful, assuming that the semantics follow the same variadic >>>>>>>>>>> approach that regular functions do. >>>>>>>>>>> >>>>>>>>>>> Another pain point is handling cases where you want one class to >>>>>>>>>>> interoperate with another. In one of the example above methods are >>>>>>>>>>> defined >>>>>>>>>>> that allow `Point`s and `Number`s to be added to each other. In >>>>>>>>>>> order to >>>>>>>>>>> maintain the commutativity of `+` we need to define `operator+` / >>>>>>>>>>> `[Symbol.add]` methods on both `Point` and `Number`. One potential >>>>>>>>>>> solution to this problem is create `Symbol.plusRight`, >>>>>>>>>>> `Symbol.timesRight` >>>>>>>>>>> for all of the commutative/symmetric operators. >>>>>>>>>>> >>>>>>>>>>> I feel like this ends up making things more complex because >>>>>>>>>>> there are more methods to implement and the methods have to be more >>>>>>>>>>> complex >>>>>>>>>>> b/c they have to do type checking when overloaded. >>>>>>>>>>> >>>>>>>>>>> Maybe `operator+` could work like the `@operator` decorator by >>>>>>>>>>> calling `Function.defineOperator` behind the scenes. In this >>>>>>>>>>> situation, >>>>>>>>>>> instead of methods being added to classes, the `Function` object has >>>>>>>>>>> well-defined methods that look up the correct function to call >>>>>>>>>>> based on the >>>>>>>>>>> argument types. `u + v` desugars to `Function[Symbol.plus](u, v)`. >>>>>>>>>>> This >>>>>>>>>>> is definitely slower than internal slots, but if we're doing >>>>>>>>>>> runtime type >>>>>>>>>>> checking in the method we may as well have it be automatic. My >>>>>>>>>>> hope is to >>>>>>>>>>> eventually use static typing (flow b/c I'm using babel) to remove >>>>>>>>>>> the >>>>>>>>>>> lookup cost. >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> On Tue, May 10, 2016 at 7:07 PM, Isiah Meadows < >>>>>>>>>>> isiahmead...@gmail.com> wrote: >>>>>>>>>>> >>>>>>>>>>>> You're correct in that the operator doesn't do any type >>>>>>>>>>>> checking (it dispatches from its first argument, but that's just >>>>>>>>>>>> traditional OO). >>>>>>>>>>>> >>>>>>>>>>>> On Tue, May 10, 2016, 20:28 kdex <k...@kdex.de> wrote: >>>>>>>>>>>> >>>>>>>>>>>>> @Isiah: Comparing your syntax proposal to >>>>>>>>>>>>> `Function.defineOperator`, it appears to me that >>>>>>>>>>>>> overloading an operator multiple times (e. g. unary/binary >>>>>>>>>>>>> plus operator) might become painful, >>>>>>>>>>>>> assuming that the semantics follow the same variadic approach >>>>>>>>>>>>> that regular functions do. >>>>>>>>>>>>> >>>>>>>>>>>>> That is, of course, unless you intend to handle all operator >>>>>>>>>>>>> overloads in a single `operator +(...args) {}` >>>>>>>>>>>>> definition. But then again, something like >>>>>>>>>>>>> `Function.defineOperator` seems cleaner and suggests implicit >>>>>>>>>>>>> (optional?) type checks with its second argument. >>>>>>>>>>>>> >>>>>>>>>>>>> On Dienstag, 10. Mai 2016 15:25:32 CEST Isiah Meadows wrote: >>>>>>>>>>>>> > Here's my thought, if we go with syntax. >>>>>>>>>>>>> > >>>>>>>>>>>>> > ```js >>>>>>>>>>>>> > class Point { >>>>>>>>>>>>> > // constructor, etc. >>>>>>>>>>>>> > >>>>>>>>>>>>> > operator +(other) { >>>>>>>>>>>>> > assert(other instanceof Point) >>>>>>>>>>>>> > return new Point( >>>>>>>>>>>>> > this.x + other.x, >>>>>>>>>>>>> > this.y + other.y) >>>>>>>>>>>>> > } >>>>>>>>>>>>> > >>>>>>>>>>>>> > operator +=(other) { >>>>>>>>>>>>> > assert(other instanceof Point) >>>>>>>>>>>>> > this.x += other.x >>>>>>>>>>>>> > this.y += other.y >>>>>>>>>>>>> > } >>>>>>>>>>>>> > } >>>>>>>>>>>>> > ``` >>>>>>>>>>>>> > >>>>>>>>>>>>> > On Tue, May 10, 2016, 11:16 Brian Barnes <gga...@charter.net> >>>>>>>>>>>>> wrote: >>>>>>>>>>>>> > >>>>>>>>>>>>> > > A note on this from somebody who's entire existence seems >>>>>>>>>>>>> dedicated to >>>>>>>>>>>>> > > stopping as much stuff as possible from getting GC'd, the >>>>>>>>>>>>> example below: >>>>>>>>>>>>> > > >>>>>>>>>>>>> > > >const u = new Point(5, 10); >>>>>>>>>>>>> > > >const v = new Point(1, -2); >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > >const w = u + v; // desugars to u[Symbol.add](v) >>>>>>>>>>>>> > > >console.log(w); // { x: 6, y: 8 }; >>>>>>>>>>>>> > > >>>>>>>>>>>>> > > Could += be a special case? i.e., >>>>>>>>>>>>> > > >>>>>>>>>>>>> > > u+=v; >>>>>>>>>>>>> > > >>>>>>>>>>>>> > > would call: >>>>>>>>>>>>> > > >>>>>>>>>>>>> > > Class Point { ... other stuff ... >>>>>>>>>>>>> > > [whatever the syntax is](pt) >>>>>>>>>>>>> > > { >>>>>>>>>>>>> > > this.x+=pt.x; >>>>>>>>>>>>> > > this.y+=pt.y; >>>>>>>>>>>>> > > } >>>>>>>>>>>>> > > } >>>>>>>>>>>>> > > >>>>>>>>>>>>> > > instead of desugaring to: >>>>>>>>>>>>> > > >>>>>>>>>>>>> > > u=u+v; // which would cause the creation of an >>>>>>>>>>>>> object and >>>>>>>>>>>>> > > // leave the other to be collected >>>>>>>>>>>>> > > >>>>>>>>>>>>> > > For all I know, += might be doing such anyway in some >>>>>>>>>>>>> engines, but for >>>>>>>>>>>>> > > my stuff which is a lot of 3D math that could be a >>>>>>>>>>>>> performance killer. >>>>>>>>>>>>> > > It would be nice to be able to just add points and such, >>>>>>>>>>>>> as long as the >>>>>>>>>>>>> > > overhead is negligible. >>>>>>>>>>>>> > > >>>>>>>>>>>>> > > [>] Brian >>>>>>>>>>>>> > > >>>>>>>>>>>>> > > On 5/10/2016 10:52 AM, Isiah Meadows wrote: >>>>>>>>>>>>> > > > I would prefer syntax + internal slots, since you'll >>>>>>>>>>>>> know at creation >>>>>>>>>>>>> > > > time whether the object has overloaded operators. It's >>>>>>>>>>>>> much simpler for >>>>>>>>>>>>> > > > the engine to figure out, and it's more performant >>>>>>>>>>>>> because you only need >>>>>>>>>>>>> > > > to check one thing instead of worrying about >>>>>>>>>>>>> inheritance, own >>>>>>>>>>>>> > > > properties, etc. >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > Also, it would be IMHO easier to read than a symbol (the >>>>>>>>>>>>> computed >>>>>>>>>>>>> > > > property syntax is ugly IMO). Using a different concept >>>>>>>>>>>>> than symbols >>>>>>>>>>>>> > > > would also fit better with value types whenever any of >>>>>>>>>>>>> those proposals >>>>>>>>>>>>> > > > make it into the language (either the struct or special >>>>>>>>>>>>> syntax). >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > On Tue, May 10, 2016, 04:03 G. Kay Lee >>>>>>>>>>>>> > > > <balancetraveller+es-disc...@gmail.com >>>>>>>>>>>>> > > > <mailto:balancetraveller%2bes-disc...@gmail.com>> wrote: >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > Yes, I think exposing operators through well-known >>>>>>>>>>>>> symbols is an >>>>>>>>>>>>> > > > interesting idea worthy of more exploration because >>>>>>>>>>>>> it's precisely >>>>>>>>>>>>> > > > the purpose of well-known symbols to expose and >>>>>>>>>>>>> allow manipulation >>>>>>>>>>>>> > > > to previously inaccessible internal language >>>>>>>>>>>>> behaviors. >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > On Tue, May 10, 2016 at 1:59 PM, Kevin Barabash >>>>>>>>>>>>> > > > <kev...@khanacademy.org <mailto: >>>>>>>>>>>>> kev...@khanacademy.org>> wrote: >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > > And remember that decorators are essentially >>>>>>>>>>>>> just a syntax to >>>>>>>>>>>>> > > > apply functions to objects/classes at design >>>>>>>>>>>>> time, so what >>>>>>>>>>>>> > > > you're proposing is essentially some new global >>>>>>>>>>>>> function, which >>>>>>>>>>>>> > > > is going against the current trend and effort to >>>>>>>>>>>>> better >>>>>>>>>>>>> > > > modularize/namespace all these utility >>>>>>>>>>>>> functions/methods. >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > That's a really good point. >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > > It has been mentioned and discussed in >>>>>>>>>>>>> numerous places over the >>>>>>>>>>>>> > > > years, you can find more info on this with some >>>>>>>>>>>>> casual googling. >>>>>>>>>>>>> > > > For example: >>>>>>>>>>>>> https://news.ycombinator.com/item?id=2983420 >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > Thanks for the link. I played around with >>>>>>>>>>>>> sweet.js a bit over >>>>>>>>>>>>> > > > the weekend. Using macros should work if we >>>>>>>>>>>>> went with Python >>>>>>>>>>>>> > > > style operator overloading. Instead of defining >>>>>>>>>>>>> methods like >>>>>>>>>>>>> > > > _ADD_, _SUB_ etc. we could create some >>>>>>>>>>>>> well-known symbols, maybe >>>>>>>>>>>>> > > > Symbol.plus, Symbol.times, etc. >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > ``` >>>>>>>>>>>>> > > > class Point { >>>>>>>>>>>>> > > > constructor(x, y) { >>>>>>>>>>>>> > > > Object.assign(this, {x, y}); >>>>>>>>>>>>> > > > } >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > [Symbol.add](other) { >>>>>>>>>>>>> > > > return new Point(this.x + other.x, this.y + >>>>>>>>>>>>> other.y); >>>>>>>>>>>>> > > > } >>>>>>>>>>>>> > > > } >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > const u = new Point(5, 10); >>>>>>>>>>>>> > > > const v = new Point(1, -2); >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > const w = u + v; // desugars to u[Symbol.add](v) >>>>>>>>>>>>> > > > console.log(w); // { x: 6, y: 8 }; >>>>>>>>>>>>> > > > ``` >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > This would require default implementations to be >>>>>>>>>>>>> defined on >>>>>>>>>>>>> > > > Object.prototype for Symbol.plus, Symbol.times, >>>>>>>>>>>>> etc. >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > On Sun, May 8, 2016 at 10:38 PM, G. Kay Lee >>>>>>>>>>>>> > > > <balancetraveller+es-disc...@gmail.com >>>>>>>>>>>>> > > > <mailto:balancetraveller+es-disc...@gmail.com>> >>>>>>>>>>>>> wrote: >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > > Why not? The standard defines well-known >>>>>>>>>>>>> symbols. Maybe >>>>>>>>>>>>> > > `@operator` could be a well known decorator (assuming >>>>>>>>>>>>> decorators get >>>>>>>>>>>>> > > approved). >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > Well... you make something into the standard >>>>>>>>>>>>> with proposals, >>>>>>>>>>>>> > > > not why-nots, so in order to make that >>>>>>>>>>>>> happen you need to >>>>>>>>>>>>> > > > draft another proposal for well-known >>>>>>>>>>>>> decorators. And >>>>>>>>>>>>> > > > remember that decorators are essentially >>>>>>>>>>>>> just a syntax to >>>>>>>>>>>>> > > > apply functions to objects/classes at design >>>>>>>>>>>>> time, so what >>>>>>>>>>>>> > > > you're proposing is essentially some new >>>>>>>>>>>>> global function, >>>>>>>>>>>>> > > > which is going against the current trend and >>>>>>>>>>>>> effort to >>>>>>>>>>>>> > > > better modularize/namespace all these utility >>>>>>>>>>>>> > > > functions/methods. And maybe a new mechanism >>>>>>>>>>>>> could be >>>>>>>>>>>>> > > > drafted for these new well-known decorators, >>>>>>>>>>>>> so that we can >>>>>>>>>>>>> > > > hide these new functions somewhere... but by >>>>>>>>>>>>> now I hope it's >>>>>>>>>>>>> > > > becoming clear that it's introducing way too >>>>>>>>>>>>> much new >>>>>>>>>>>>> > > > surface area for the language in exchange >>>>>>>>>>>>> for one small >>>>>>>>>>>>> > > feature. >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > > I haven't seen any proposals for macros, >>>>>>>>>>>>> could you post a >>>>>>>>>>>>> > > link? >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > It has been mentioned and discussed in >>>>>>>>>>>>> numerous places over >>>>>>>>>>>>> > > > the years, you can find more info on this >>>>>>>>>>>>> with some casual >>>>>>>>>>>>> > > > googling. For example: >>>>>>>>>>>>> > > > https://news.ycombinator.com/item?id=2983420 >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > On Sun, May 8, 2016 at 2:51 PM, Kevin >>>>>>>>>>>>> Barabash >>>>>>>>>>>>> > > > <kev...@khanacademy.org <mailto: >>>>>>>>>>>>> kev...@khanacademy.org>> >>>>>>>>>>>>> > > wrote: >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > I should update the demo code to show >>>>>>>>>>>>> the `@operator` >>>>>>>>>>>>> > > > decorator in addition to >>>>>>>>>>>>> `Function.defineOperator`. >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > Initially I started out with just the >>>>>>>>>>>>> `@operator` >>>>>>>>>>>>> > > > decorator, but that meant that each >>>>>>>>>>>>> class would have to >>>>>>>>>>>>> > > > have knowledge of each of the classes it >>>>>>>>>>>>> might want to >>>>>>>>>>>>> > > > interact with before hand. Having a >>>>>>>>>>>>> separate >>>>>>>>>>>>> > > > `defineOperator` function avoids this >>>>>>>>>>>>> situation. >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > It means that prototype style classes >>>>>>>>>>>>> must be converted >>>>>>>>>>>>> > > > to the new class syntax before operator >>>>>>>>>>>>> overloading >>>>>>>>>>>>> > > > could be used. Lastly, there may be >>>>>>>>>>>>> some cases where it >>>>>>>>>>>>> > > > makes sense to overload operators with >>>>>>>>>>>>> existing 3rd >>>>>>>>>>>>> > > > party code or built-in classes, e.g. >>>>>>>>>>>>> adding set >>>>>>>>>>>>> > > > operations to Set using operator >>>>>>>>>>>>> overloading. >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > > It's also apparent that the `@operator >>>>>>>>>>>>> decorator` part >>>>>>>>>>>>> > > > of the proposal is an effort trying to >>>>>>>>>>>>> address this >>>>>>>>>>>>> > > > issue, but it really is not the >>>>>>>>>>>>> responsibility of the >>>>>>>>>>>>> > > > standard to try to define such a thing. >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > Why not? The standard defines >>>>>>>>>>>>> well-known symbols. >>>>>>>>>>>>> > > > Maybe `@operator` could be a well known >>>>>>>>>>>>> decorator >>>>>>>>>>>>> > > > (assuming decorators get approved). >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > Slide 15 >>>>>>>>>>>>> > > > from >>>>>>>>>>>>> http://www.slideshare.net/BrendanEich/js-resp shows >>>>>>>>>>>>> > > > syntax for defining operators in value >>>>>>>>>>>>> types which could >>>>>>>>>>>>> > > > be adapted as follows for regular >>>>>>>>>>>>> classes: >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > ``` >>>>>>>>>>>>> > > > class Point { >>>>>>>>>>>>> > > > constructor(x, y) { >>>>>>>>>>>>> > > > this.x = +x; >>>>>>>>>>>>> > > > this.y = +y; >>>>>>>>>>>>> > > > } >>>>>>>>>>>>> > > > Point + Number (a, b) { >>>>>>>>>>>>> > > > return new Point(a.x + b, a.y + >>>>>>>>>>>>> b); >>>>>>>>>>>>> > > > } >>>>>>>>>>>>> > > > Number + Point (a, b) { >>>>>>>>>>>>> > > > return new Point(a + b.x, a + >>>>>>>>>>>>> b.y); >>>>>>>>>>>>> > > > } >>>>>>>>>>>>> > > > Point + Point (a, b) { >>>>>>>>>>>>> > > > return new Point(a.x + b.x, a.y + >>>>>>>>>>>>> b.y); >>>>>>>>>>>>> > > > } >>>>>>>>>>>>> > > > } >>>>>>>>>>>>> > > > ``` >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > Having to define `+` twice for `Point + >>>>>>>>>>>>> Number` and >>>>>>>>>>>>> > > > `Number + Point` seems like busy work, >>>>>>>>>>>>> but maybe it's >>>>>>>>>>>>> > > > better to be explicit. What are you >>>>>>>>>>>>> thoughts about this >>>>>>>>>>>>> > > > syntax? >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > > Another thing is that, IMHO, currently >>>>>>>>>>>>> there are too >>>>>>>>>>>>> > > > much quirks/conventions in the proposal >>>>>>>>>>>>> that feel >>>>>>>>>>>>> > > > non-evident and non-flexible which is >>>>>>>>>>>>> destined to trip >>>>>>>>>>>>> > > > people over from time to time. It would >>>>>>>>>>>>> be great to make >>>>>>>>>>>>> > > > a proposal that's simple and don't >>>>>>>>>>>>> include too much >>>>>>>>>>>>> > > > assumptions. >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > Could you elaborator what >>>>>>>>>>>>> quirks/conventions might trip >>>>>>>>>>>>> > > > people up? >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > > Finally, I'm not sure about the >>>>>>>>>>>>> current status of >>>>>>>>>>>>> > > > macros, but last I heard of it, they say >>>>>>>>>>>>> it's going to >>>>>>>>>>>>> > > > make its way into the standard pretty >>>>>>>>>>>>> soon (TM), and >>>>>>>>>>>>> > > > macros can do much of the things >>>>>>>>>>>>> overloading could, and >>>>>>>>>>>>> > > > much more. >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > I haven't seen any proposals for macros, >>>>>>>>>>>>> could you post >>>>>>>>>>>>> > > > a link? >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > On Sat, May 7, 2016 at 9:55 PM, G. Kay >>>>>>>>>>>>> Lee >>>>>>>>>>>>> > > > <balancetraveller+es-disc...@gmail.com >>>>>>>>>>>>> > > > <mailto: >>>>>>>>>>>>> balancetraveller+es-disc...@gmail.com>> wrote: >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > I'd say it's way too early to ask >>>>>>>>>>>>> for a champion on >>>>>>>>>>>>> > > > this because just a quick skimming >>>>>>>>>>>>> revealed a lot of >>>>>>>>>>>>> > > > places that didn't add up. For >>>>>>>>>>>>> example, the proposal >>>>>>>>>>>>> > > > suggested that overloading is >>>>>>>>>>>>> primarily targeted at >>>>>>>>>>>>> > > > making it easier to work with >>>>>>>>>>>>> user-defined classes, >>>>>>>>>>>>> > > > but curiously a >>>>>>>>>>>>> `Function.defineOperator()` method >>>>>>>>>>>>> > > > is proposed instead of some syntax >>>>>>>>>>>>> that feels more >>>>>>>>>>>>> > > > tightly integrated with the class >>>>>>>>>>>>> definition syntax. >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > ``` >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > class Point { >>>>>>>>>>>>> > > > constructor(x, y) { >>>>>>>>>>>>> > > > Object.assign(this, { x, y >>>>>>>>>>>>> }); >>>>>>>>>>>>> > > > } >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > toString() { >>>>>>>>>>>>> > > > return `(${this.x}, >>>>>>>>>>>>> ${this.y})`; >>>>>>>>>>>>> > > > } >>>>>>>>>>>>> > > > } >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > Function.defineOperator('+', [Point, >>>>>>>>>>>>> Point], (a, b) >>>>>>>>>>>>> > > => new Point(a.x + b.x, a.y + b.y)); >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > ``` >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > The demo code made this flaw evident >>>>>>>>>>>>> - it looks like >>>>>>>>>>>>> > > > a giant step backward to define an >>>>>>>>>>>>> instance method >>>>>>>>>>>>> > > > like this, don't you agree? >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > It's also apparent that the >>>>>>>>>>>>> `@operator decorator` >>>>>>>>>>>>> > > > part of the proposal is an effort >>>>>>>>>>>>> trying to address >>>>>>>>>>>>> > > > this issue, but it really is not the >>>>>>>>>>>>> responsibility >>>>>>>>>>>>> > > > of the standard to try to define >>>>>>>>>>>>> such a thing. >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > What I'd suggest is that perhaps you >>>>>>>>>>>>> should rethink >>>>>>>>>>>>> > > > your proposed syntax and redesign it >>>>>>>>>>>>> to become an >>>>>>>>>>>>> > > > extension of the ES6 class >>>>>>>>>>>>> definition syntax. >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > Another thing is that, IMHO, >>>>>>>>>>>>> currently there are too >>>>>>>>>>>>> > > > much quirks/conventions in the >>>>>>>>>>>>> proposal that feel >>>>>>>>>>>>> > > > non-evident and non-flexible which >>>>>>>>>>>>> is destined to >>>>>>>>>>>>> > > > trip people over from time to time. >>>>>>>>>>>>> It would be >>>>>>>>>>>>> > > > great to make a proposal that's >>>>>>>>>>>>> simple and don't >>>>>>>>>>>>> > > > include too much assumptions. >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > Finally, I'm not sure about the >>>>>>>>>>>>> current status of >>>>>>>>>>>>> > > > macros, but last I heard of it, they >>>>>>>>>>>>> say it's going >>>>>>>>>>>>> > > > to make its way into the standard >>>>>>>>>>>>> pretty soon (TM), >>>>>>>>>>>>> > > > and macros can do much of the things >>>>>>>>>>>>> overloading >>>>>>>>>>>>> > > > could, and much more. >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > On Sun, May 8, 2016 at 8:51 AM, >>>>>>>>>>>>> Kevin Barabash >>>>>>>>>>>>> > > > <kev...@khanacademy.org >>>>>>>>>>>>> > > > <mailto:kev...@khanacademy.org>> >>>>>>>>>>>>> wrote: >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > I forgot to mention in my last >>>>>>>>>>>>> email that I'm >>>>>>>>>>>>> > > > looking for a champion for this >>>>>>>>>>>>> proposal. >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > On Sat, May 7, 2016 at 5:24 PM, >>>>>>>>>>>>> Kevin Barabash >>>>>>>>>>>>> > > > <kev...@khanacademy.org >>>>>>>>>>>>> > > > <mailto:kev...@khanacademy.org>> >>>>>>>>>>>>> wrote: >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > Hi everyone, >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > I've been working on >>>>>>>>>>>>> implementing operator >>>>>>>>>>>>> > > > overloading and would like >>>>>>>>>>>>> to submit a >>>>>>>>>>>>> > > proposal. >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > I think operator overloading >>>>>>>>>>>>> would be a >>>>>>>>>>>>> > > > useful addition to the >>>>>>>>>>>>> language. In >>>>>>>>>>>>> > > > particular I think it would >>>>>>>>>>>>> be useful for >>>>>>>>>>>>> > > > defining operations on >>>>>>>>>>>>> common mathematical >>>>>>>>>>>>> > > > object types such as complex >>>>>>>>>>>>> numbers, >>>>>>>>>>>>> > > > vectors, matrices, and sets. >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > I've create a working >>>>>>>>>>>>> prototype that >>>>>>>>>>>>> > > > consists of: >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > * babel plugin that >>>>>>>>>>>>> rewrites operators as >>>>>>>>>>>>> > > > function calls >>>>>>>>>>>>> > > > * a polyfill which defines >>>>>>>>>>>>> these functions >>>>>>>>>>>>> > > > and which call the >>>>>>>>>>>>> correct >>>>>>>>>>>>> > > > argument-specific >>>>>>>>>>>>> function based on the >>>>>>>>>>>>> > > > arguments' prototypes >>>>>>>>>>>>> > > > * Function.defineOperator >>>>>>>>>>>>> which can be >>>>>>>>>>>>> > > > used to define which >>>>>>>>>>>>> function an >>>>>>>>>>>>> > > > operator should use for >>>>>>>>>>>>> the specified >>>>>>>>>>>>> > > types >>>>>>>>>>>>> > > > * "use overloading" >>>>>>>>>>>>> directive which allows >>>>>>>>>>>>> > > > users to opt-in >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > More details can be found >>>>>>>>>>>>> > > > at >>>>>>>>>>>>> > > https://github.com/kevinbarabash/operator-overloading. >>>>>>>>>>>>> > > > The babel plugin can be found >>>>>>>>>>>>> > > > at >>>>>>>>>>>>> > > >>>>>>>>>>>>> https://github.com/kevinbarabash/babel-plugin-operator-overloading >>>>>>>>>>>>> . >>>>>>>>>>>>> > > > I also have a demo project at >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > https://github.com/kevinbarabash/operator-overloading-demo >>>>>>>>>>>>> . >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > The design was inspired by >>>>>>>>>>>>> some of the >>>>>>>>>>>>> > > > slides from >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > http://www.slideshare.net/BrendanEich/js-resp. >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > – Kevin >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > >>>>>>>>>>>>> _______________________________________________ >>>>>>>>>>>>> > > > 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 <mailto: >>>>>>>>>>>>> > > es-discuss@mozilla.org> >>>>>>>>>>>>> > > > >>>>>>>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > >>>>>>>>>>>>> _______________________________________________ >>>>>>>>>>>>> > > > 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 <mailto: >>>>>>>>>>>>> es-discuss@mozilla.org> >>>>>>>>>>>>> > > > https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > > _______________________________________________ >>>>>>>>>>>>> > > > 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 <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 >>>>>>>>>>>>> > > > >>>>>>>>>>>>> > > _______________________________________________ >>>>>>>>>>>>> > > es-discuss mailing list >>>>>>>>>>>>> > > es-discuss@mozilla.org >>>>>>>>>>>>> > > https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>>>> > > >>>>>>>>>>>>> > >>>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> _______________________________________________ >>>>>>>>>>>> es-discuss mailing list >>>>>>>>>>>> es-discuss@mozilla.org >>>>>>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>> _______________________________________________ >>>>>>>>>>> es-discuss mailing list >>>>>>>>>>> es-discuss@mozilla.org >>>>>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>> >>>>>>>>>> >>>>>>>>>> _______________________________________________ >>>>>>>>>> es-discuss mailing list >>>>>>>>>> es-discuss@mozilla.org >>>>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>> >>>>>>>>>> >>>>>>>>> >>>>>>>> _______________________________________________ >>>>>>>> es-discuss mailing list >>>>>>>> es-discuss@mozilla.org >>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>> >>>>>>>> >>>>>>> >>>>>> _______________________________________________ >>>>>> es-discuss mailing list >>>>>> es-discuss@mozilla.org >>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>> >>>>>> >>>>> _______________________________________________ >>>>> es-discuss mailing list >>>>> es-discuss@mozilla.org >>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>> >>>> >>> >>> _______________________________________________ >>> es-discuss mailing list >>> es-discuss@mozilla.org >>> https://mail.mozilla.org/listinfo/es-discuss >>> >>> >>
_______________________________________________ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss