Maybe, maybe not - it largely depends on how TypeScript and ES end up converging, and how the efforts for strong typing (like floats, longs, structs, etc.) end up. Also, TypeScript has quite a few warts remaining, including with its type system. For example, there's no way at the moment to properly type check `Function.prototype.bind`, you have to either have variadic generics with up to two arguments or a Turing-complete type system.
But on the other hand, -1 for a new directive, though. They're ugly, and most the community's leaders agree. And I highly doubt we will need them. On Fri, May 20, 2016, 19:34 Kevin Barabash <[email protected]> wrote: > 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 <[email protected]> > 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 <[email protected]> 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 <[email protected] >>> > 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 <[email protected] >>>> > 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 <[email protected]> >>>>> 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 < >>>>>> [email protected]> 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 < >>>>>>> [email protected]> 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 <[email protected]>: >>>>>>>> >>>>>>>>> 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 <[email protected]> >>>>>>>>> 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 < >>>>>>>>>> [email protected]> 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 < >>>>>>>>>>> [email protected]> 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 < >>>>>>>>>>>> [email protected]> 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 <[email protected]> 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 < >>>>>>>>>>>>>> [email protected]> 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 >>>>>>>>>>>>>> > > > <[email protected] >>>>>>>>>>>>>> > > > <mailto:balancetraveller%[email protected]>> >>>>>>>>>>>>>> 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 >>>>>>>>>>>>>> > > > <[email protected] <mailto: >>>>>>>>>>>>>> [email protected]>> 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 >>>>>>>>>>>>>> > > > <[email protected] >>>>>>>>>>>>>> > > > <mailto:[email protected]>> >>>>>>>>>>>>>> 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 >>>>>>>>>>>>>> > > > <[email protected] <mailto: >>>>>>>>>>>>>> [email protected]>> >>>>>>>>>>>>>> > > 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 >>>>>>>>>>>>>> > > > <[email protected] >>>>>>>>>>>>>> > > > <mailto: >>>>>>>>>>>>>> [email protected]>> 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 >>>>>>>>>>>>>> > > > <[email protected] >>>>>>>>>>>>>> > > > <mailto:[email protected]>> >>>>>>>>>>>>>> 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 >>>>>>>>>>>>>> > > > <[email protected] >>>>>>>>>>>>>> > > > <mailto:[email protected]>> >>>>>>>>>>>>>> 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 >>>>>>>>>>>>>> > > > [email protected] >>>>>>>>>>>>>> > > > <mailto:[email protected]> >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> _______________________________________________ >>>>>>>>>>>>>> > > > es-discuss mailing list >>>>>>>>>>>>>> > > > [email protected] <mailto: >>>>>>>>>>>>>> > > [email protected]> >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> _______________________________________________ >>>>>>>>>>>>>> > > > es-discuss mailing list >>>>>>>>>>>>>> > > > [email protected] <mailto: >>>>>>>>>>>>>> [email protected]> >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> _______________________________________________ >>>>>>>>>>>>>> > > > es-discuss mailing list >>>>>>>>>>>>>> > > > [email protected] <mailto: >>>>>>>>>>>>>> [email protected]> >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> > > > _______________________________________________ >>>>>>>>>>>>>> > > > es-discuss mailing list >>>>>>>>>>>>>> > > > [email protected] <mailto: >>>>>>>>>>>>>> [email protected]> >>>>>>>>>>>>>> > > > https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> > > > _______________________________________________ >>>>>>>>>>>>>> > > > es-discuss mailing list >>>>>>>>>>>>>> > > > [email protected] <mailto: >>>>>>>>>>>>>> [email protected]> >>>>>>>>>>>>>> > > > https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> > > > _______________________________________________ >>>>>>>>>>>>>> > > > es-discuss mailing list >>>>>>>>>>>>>> > > > [email protected] >>>>>>>>>>>>>> > > > https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>>>>> > > > >>>>>>>>>>>>>> > > _______________________________________________ >>>>>>>>>>>>>> > > es-discuss mailing list >>>>>>>>>>>>>> > > [email protected] >>>>>>>>>>>>>> > > https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>>>>> > > >>>>>>>>>>>>>> > >>>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> _______________________________________________ >>>>>>>>>>>>> es-discuss mailing list >>>>>>>>>>>>> [email protected] >>>>>>>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>> _______________________________________________ >>>>>>>>>>>> es-discuss mailing list >>>>>>>>>>>> [email protected] >>>>>>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> _______________________________________________ >>>>>>>>>>> es-discuss mailing list >>>>>>>>>>> [email protected] >>>>>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>> >>>>>>>>> _______________________________________________ >>>>>>>>> es-discuss mailing list >>>>>>>>> [email protected] >>>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>> >>>>>>>>> >>>>>>>> >>>>>>> _______________________________________________ >>>>>>> es-discuss mailing list >>>>>>> [email protected] >>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>> >>>>>>> >>>>>> _______________________________________________ >>>>>> es-discuss mailing list >>>>>> [email protected] >>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>> >>>>> >>>> >>>> _______________________________________________ >>>> es-discuss mailing list >>>> [email protected] >>>> https://mail.mozilla.org/listinfo/es-discuss >>>> >>>> >>> >
_______________________________________________ es-discuss mailing list [email protected] https://mail.mozilla.org/listinfo/es-discuss

