Operators overriding

# KOLANICH (9 years ago)

Hello. What do you think about overriding operators using proxies? For example function A(r=""){ this.rep=r; return new Proxy(this,{operators:{"+":function(a,b){return new A(a.rep+"+"+b.rep);}}}); } let a=new A("a"), b=new A("b"); let c=a+b; console.log(c.rep);//a+b

# Sander Deryckere (9 years ago)

IMO, operator overloading is important and different enough to warrant a separate syntax.

But the difficulty isn't in defining the operator, but in the ambiguous cases. Like what to do when there are 2 different types, how to make sure certain relations will stay correct, ...

There's a nice presentation from Brendan Eich here: www.slideshare.net/BrendanEich/value-objects2

, Sander

2015-12-18 21:24 GMT+01:00 KOLANICH <kolan_n at mail.ru>:

# KOLANICH (9 years ago)

I dislike this proposal. 1 It is not very good to limit overrideable operators to value classes. 2 It is not very good to have a lot of custom operators, it will break code readability and will allow more efficient obfuscration. 3 I think that most of binary non-assigning operators must return a new object and thats' why they should be not object methods, but the methods taking 2 (or more if chained!) objects and return the result usually of same type. вторник, 22 декабря 2015г., 21:45 +03:00 от Sander Deryckere < sanderd17 at gmail.com> :

# Frankie Bagnardi (9 years ago)

Generally letting proxies do more things is a good thing, but what would be the cost in optimizing JITs? It seems like e.g. making a + b or a | 0 more flexible would also make them slower. Is this incorrect?

# Nicolas B. Pierron (9 years ago)

This is right, currently code such as "asm js" rely on "a | 0" and "+a" to force a type interpretation. Having an override means that we would have to guard explicitly against overridden the operator before entering these sections of code. This will increase the cost of cold calls. If this is a frequent path, then we would have to infer the type as long as possible to remove such guards.

Currently, proxies have more important issues in SpiderMonkey, as they allow to instrument the lookup of properties (which is still in C++) in a side-effectful way.

# Alexander Jones (9 years ago)

Who would have thought using completely un-semantic idioms such as |0 and !! would lead to issues down the line? /s

# Bradley Meck (9 years ago)

Who would think not knowing what a+b could do as a pitfall? /s

I am not a big fan of overloading though, since it presents more mental complexity as they map to functions without looking like function calls.

# /#!/JoePea (9 years ago)

I'm in favor of no overloading for the reason of the mental tax. People could write a program where everything is a mathematical operation (in looks, not necessarily functionality), which could encourage harder-to-read code. I think this.plus(that) is fine for objects. With a proper auto-completing editor, this really isn't that difficult. Plus, there's Sweet.js if you really want it.

# Alexander Jones (9 years ago)

Regarding not knowing what a + b does: you already don't know because it invokes .valueOf. If you already know the operands are typeof "number", you're good to optimise just as much as with operator overloading.

Aside from that, we're back into arguments about the clarity benefits of

  • paren-free function invocation
  • non-member, postfix function call syntax, aka ::

And finally, any discussion about the perceived "mental tax" of operators would be incomplete without a reference to the definition of the + operator in ECMAScript 2016[1]. Ever tried explaining to beginners what the result of [] + {} is, while keeping a straight face?

www.ecma-international.org/ecma-262/6.0/#sec

# /#!/JoePea (9 years ago)

On Mon, Dec 28, 2015 at 10:19 AM, Alexander Jones <alex at weej.com> wrote:

[] + {}

That's an odd use case. I've never used it myself. Straight face not possible. x]

# Coroutines (9 years ago)

On Mon, Dec 28, 2015 at 9:55 AM, Bradley Meck <bradley.meck at gmail.com> wrote:

Who would think not knowing what a+b could do as a pitfall? /s

I am not a big fan of overloading though, since it presents more mental complexity as they map to functions without looking like function calls.

From the Wikipedia page on ecmascript it seemed like operator

overloading was already a for-sure planned feature of ES7, just not fleshed out in a spec. I personally do love operator overloading - I am used to it from Lua and Python and I think it can be quite nice. Especially for making PEG combinator stuff:

term = Any(1) // any 1 character whitespace = Range(CharSet(' \t'), 1, Infinity) // space or tab, repeated 1 or more times indented_term = whitespace + term // will match: ' x'

result = indented_term.parse(' text...')

Okay this is a bad example. But when you're building a grammar description from objects it can be quite fun to make use of operator overloading for a much cleaner description - somewhat like a domain-specific language (DSL) within JS. LPeg in Lua and PyPeg in Python make this rather pleasant.

Anyway, I suspect it won't matter what syntactic features Javascript gains once WebAssembly gets adopted. We already have the fundamentals like inheritance in place so that any language can compile to a WebAssembly AST and run as one would expect.

# /#!/JoePea (9 years ago)

I'm kind of on the fence about it. let result = matrix1.multiply(matrix2) works for graphics, but var result = matrix1 * matrix2 could be nice.

Now that I think about it, I think I'll fall over onto the +1 side of the fence, because one of the things I love about JavaScript is how flexible it is as a language, and this adds to that flexibility that developers have in choosing how they write code.

# Bradley Meck (9 years ago)

type coercion of .valueOf of .toString variety is guaranteed to return a specific type (based upon hints). There is a small surface area to what the total possible outcomes of using + and having coercion could return. Not true in a operator overloading world.

I am not saying that confusions are not present, just that we should not add more. Having one wart does not merit having more.

# Sander Deryckere (9 years ago)

There are so many places where overloading would be useful., even between different data types:

  • adding vectors
  • multiplying vectors with matrices
  • multiplying vectors with numbers
  • multiplying or adding matrices
  • adding (or subtracting) date objects (to get a time difference)

Certainly in the case of working with vectors, you often need long calculations with intermediate results. In those cases, it's also often convenient to use short names (as the names are very local). So while myFirstMatrix.multiply(mySecondMatrix) is acceptable, m1.multiply(m2) isn't so acceptable. it distracts your attention too much to the name "multiply" instead of letting you see the math behind it.

I like JavaScript as a versatile language. It really gives the programmer the responsibility to write good code. Of course you can write bad code with operation overloading, but you can also write bad code now.

, Sander

2015-12-28 19:45 GMT+01:00 /#!/JoePea <joe at trusktr.io>:

# /#!/JoePea (9 years ago)

I just read this interesting article: www.2ality.com/2011/12/fake-operator-overloading.html?m=1

Wow. What iteresting "fake" overloading. Check out the new Point(1, 2) + new Point(3, 4) + new Point(5, 6) example.

# Isiah Meadows (9 years ago)

That's almost implementing its own runtime system just to emulate operator overloading, to be honest.