Operator overloading

# Joe Walker (17 years ago)

I blogged about a potential danger of operator overloading in JS2: getahead.org/blog/joe/2007/03/22/operator_overloading_in_javascript_2_and_a_potential_monster_csrf_hole.html

Kris Zyp made a very good point about unitary operators which indicates that the risk probably does not exist. I hope he is right.

The real worry here is that the designers of the language will, in one spec, have to out-smart crackers for a long time to come. Once websites start using a feature, it can't be easily removed. In my opinion, this is a good case for a 'belt-and-braces' approach to security.

I also wonder if this technique could be used as a way of stealing other data formats?

Thanks,

Joe.

# Brendan Eich (17 years ago)

you raise a good point about CSRF, but I think it is
misdirected against the operator proposal. Have you had a chance to
read developer.mozilla.org/es4/proposals/operators.html yet?
Note that this is not "operator overloading" in the C++ sense. We are
not add instance method overloading with dispatch based on argument
types as well as the type of the receiver object (the |this| parameter).

See also developer.mozilla.org/es4/proposals normative_grammar.html for how ECMA-357 (E4X) syntax is reserved.

In ES3 + E4X and ES4, / and < either are binary operators, or lexical
delimiters introducing regexps and XML literals respectively. This is
already implemented in JS1.6+ and AS3. But the role of such
characters can't be modified by any static operator method definition
-- it is strictly determined by the grammar. In operator position (in
an operator precedence parser), / and < are dyadic operators. In
operand position, they start distinct lexemes.

Since the only way to define operators is by static class methods,
and you can't extend existing classes with new static methods, the
only hazard is that one can load E4X using a script tag across
origins. This enables CSRF attacks on XML data inside firewalls which
may lack any access control because the intranet designers assumed
the firewall was enough. Such attacks are not possible with
XMLHttpRequest given its current same-origin restricting. This
problem is mitigated somewhat by E4X's basis in XML 1.0, its limited
support in browsers, and its inability to load schemas or DTDs.

This is one good reason (we have others) for not folding E4X into ES4.

# Joe Walker (17 years ago)

Thanks for the reply. I'm certainly no expert on JS2, but your answer does seem like a belt-and-braces approach for now.

Joe.

# João Eiras (16 years ago)

there's a feature in C++ which I like a lot, and I think it would be
interesting to have in es4, which is operator overloading, like

class X{ X& operator+(const X& x); } X a, b, c; c = a+b;

which allows the programmer to define a sum operation between two objects
of type X. The notation I'm using in this e-mail is just for example. C++ allows to define all operators except :: (scope resolution), .
(member) and .* (member through pointer)

To keep things clean, new operators cannot be defined (like in C++),so

class X{ X& operator myop(const X& x); } X a, b, c; c = a myop b;

would be invalid.

Operators should only be defined as members of objects, so one cannot
right a global operator function which picks up two object (alla C++), like function operator+:X(x:X,x:X);

Any global operator function like this one before would be added to the
window, and would be equivalent to do window['operator+']=function(x:X):X{} because the 2nd argument would be ignored.

The following operators should be definable:

  • arithmetic: + - * / % += -= *= /= %= ++ --
  • bitwise: & | ^ >> << >>= <<= ~
  • boolean: || && ! ||= &&=
  • others: typeof () []

All these operators are binary except for |, ~ and typeof , so the left
hand (A) object would be the context object, and the right hand object (B)
would be the argument passed to the operator member in A. For unary
operators, there won't be arguments, and the function would be called upon
its target. operator functions would only be called if the operator is explicitly used
in the source code.

Now consider an example class X{ function operator+:X(x:X); function operator typeof(){ return "function";}; } var a:X := new X; var b:X := new X;

var c:X = a + b; //sucess, operator is defined

a += b; //error, no += operator defined

var c:X = a + 1; //type-error, rhs must be of type X

var tp:String = typeof a;//sucess, typeof operator is ALWAYS defined, by
default it works as specified

alternative notation

class X{} X['operator ~'] = function(){};...

Supporting all these operators in the spec can be somewhat awkward. So I
wish for at least the typeof, () and [] operators to be defined. This way one can build custom collections, which have the [] indexing
operator. Defining the () operator would fit the use case of IE and Opera (added for
compatibility) which support the () operator as indexing operator in
NodeLists.

What do you think ?

Thank you for your attention.

# João Eiras (16 years ago)

So Peter Hall gave me the links discussion:operators, proposals:operators

This indeed raises a few issues, mainly with binary operators. I don't see a single reason for the operators not to be inherited. That restriction is simply written in the proposal without any backup reasoning. operators would behave exactly like regular functions. The only difference is how they're invoked.

The only really issue is when commutativeen.wikipedia.org/wiki/Commutative operators are

used, which could lead to ambiguities. I'd propose for operators to be always evaluated from left to right, unless the user specifies some kind of pragma, like a similar to the "use decimal" one for decimal numbers. Then if the operator function is not available in the left most member (or right most according to the pragma), it'd be looked up on the right one. But this should only be done for commutative operators, which are + * ==

About "compositionality", that's not an operator issue, that's an issue generic to the entire language. If I write two completly different unrelated classes I can't mix both using regular member functions.

But I recognize that operators could be more problematic than benefic.

So, there are at least a few operators which implementation would somewhat trivial. Being able to define the "()" (function call), "[]" (indexing) and typeof operators is a must.

2007/12/18, Peter Hall <peter.hall at memorphic.com>:

This has already been proposed and rejected: proposals:operators

And here is some of the rationale for rejecting it: discussion:operators

Peter

On Dec 17, 2007 9:04 PM, João Eiras <joao.eiras at gmail.com> wrote:

Hi all,

there's a feature in C++ which I like a lot, and I think it would be interesting to have in es4, which is operator overloading, like

class X{ X& operator+(const X& x); } X a, b, c; c = a+b;

which allows the programmer to define a sum operation between two

objects

of type X. The notation I'm using in this e-mail is just for example. C++ allows to define all operators except :: (scope resolution), . (member) and .* (member through pointer)

To keep things clean, new operators cannot be defined (like in C++),so

class X{ X& operator myop(const X& x); } X a, b, c; c = a myop b;

would be invalid.

Operators should only be defined as members of objects, so one cannot right a global operator function which picks up two object (alla C++),

like

function operator+:X(x:X,x:X);

Any global operator function like this one before would be added to the window, and would be equivalent to do window['operator+']=function(x:X):X{} because the 2nd argument would be ignored.

The following operators should be definable:

  • arithmetic: + - * / % += -= *= /= %= ++ --
  • bitwise: & | ^ >> << >>= <<= ~
  • boolean: || && ! ||= &&=
  • others: typeof () []

All these operators are binary except for |, ~ and typeof , so the left hand (A) object would be the context object, and the right hand object (B)

would be the argument passed to the operator member in A. For unary operators, there won't be arguments, and the function would be called

upon

its target. operator functions would only be called if the operator is explicitly

used

in the source code.

Now consider an example class X{ function operator+:X(x:X); function operator typeof(){ return "function";}; } var a:X := new X; var b:X := new X;

var c:X = a + b; //sucess, operator is defined

a += b; //error, no += operator defined

var c:X = a + 1; //type-error, rhs must be of type X

var tp:String = typeof a;//sucess, typeof operator is ALWAYS defined,

by

default it works as specified

alternative notation

class X{} X['operator ~'] = function(){};...

Supporting all these operators in the spec can be somewhat awkward. So I wish for at least the typeof, () and [] operators to be defined. This way one can build custom collections, which have the [] indexing operator. Defining the () operator would fit the use case of IE and Opera (added

for

# Mike Shaver (16 years ago)

On Dec 18, 2007 9:52 AM, João Eiras <joao.eiras at gmail.com> wrote:

Being able to define the "()" (function call), "[]" (indexing) and typeof operators is a must.

At least function call and property access are indeed customizable (via a meta-object protocol rather than operator overloading).

Mike

# Brendan Eich (16 years ago)

On Dec 18, 2007, at 6:52 AM, João Eiras wrote:

So Peter Hall gave me the links discussion:operators, proposals:operators

Once again, out of date documents are misleading folks. We need to
fix this -- apologies. The language overview:

www.ecmascript.org/es4/spec/overview.pdf

and the evolutionary programming tutorial:

www.ecmascript.org/es4/spec/evolutionary-programming-tutorial.pdf

both discuss generic functions, which are how operators can be
defined and overloaded. The wiki page for this proposal is:

proposals:generic_functions

Please read this instead of the operators proposal that it obsoletes.

# Jason Orendorff (14 years ago)

Operator overloading was discussed here before:

Mark Miller's strawman proposal (double dispatch) esdiscuss/2009-January/008535

Christian Plesner Hansen's "symmetric" operator overloading esdiscuss/2009-June/009603

So far discussion has focused on how to dispatch operations, but there is an independent design dimension: exactly what behavior programs should be able to overload. Below I advance some use cases as proposed design goals.

A motivating goal is to support defining numeric types that work in most places where primitive numbers work. So if I write classes for Complex and Decimal, it should be possible for me to arrange that:

Ordinary arithmetic just works, and mixing Complex numbers with primitive
numbers produces a Complex result;

    Decimal("0.2") * Decimal("0.8")   ---> Decimal("0.16")
    5 * Complex(0, 1)   --> Complex(0, 5)

Adding a number to a string invokes toString (ideally it wouldn't require
any code to get this behavior; it would be the default even for types that
overload + in other cases);

    Decimal("0.2") + " m/s"   ---> "0.2 m/s"
    "" + Complex(0, 3)   ---> "0+3i"

The increment/decrement and compound assignment operators just work, if the
underlying operator is overloaded (+ and * in these examples);

    x = Decimal("1"), ++x   ---> Decimal("2")
    Decimal("3")++          ---> ***ReferenceError
    x = Complex(3, 4); x *= Complex(0, 1)   --> Complex(-4, 3)

Comparisons work;

    Decimal("-1.27") <= 0   ---> true
    0 < Decimal("-1.27")   ---> false
    Decimal("-1.27") >= Decimal("-1")   ---> false

Comparisons that don't make sense throw an exception (actually this is
*not* how primitive numbers behave, but it seems like desirable behavior,
and easy enough to support for authors who want it);

    Complex(0, 2) < 2               ---> ***Error
    Complex(0, 2) < Complex(2, 0)   ---> ***Error

Zero values are false, not true;

!Complex(0, 0)   ---> true
Complex(0, 0) ? "t" : "f"   ---> "f"
    if (x) f();   ---> f is called if x is nonzero

User-defined numbers can be == to primitive numbers (but not ===);

Decimal("100") == 100    ---> true
100 == Decimal("100")    ---> true
    Complex(100, 0) == 100   ---> true

Two numbers with the same value and the same type are equal (and I should
not have to e.g. cache the instances and make Complex(5, 3) return the same
object every time).

Complex(5, 3) == Complex(5, 3)   ---> true
Complex(5, 3) === Complex(5, 3)   ---> true
[3, Complex(3, 0)].indexOf(Complex(3, 0))   ---> 1

I expect this bit about === will be contentious, but having indexOf return -1 here would be a real shame, and if there's a hash-map type in ES-next the case gets even stronger. Anyway there seems little use in having === distinguish between objects that nothing else in the language can tell apart.

Beyond numbers, there are other important use cases for operator overloading:

operator[].  Overloading indexing, even just for integer indices, would be
more than welcome. There are some nontrivial design decisions here, because
the language interacts with properties in so many ways:
    obj[i]
    obj[i] = x
    delete obj[i]
    i in obj
    for (i in obj) ...
    Object.getOwnPropertyNames(obj)
    Object.getOwnPropertyDescriptor(obj, i)
    Object.defineProperty(obj, ...)
and I'm sure I left some out. Worst-case, we add a hook for each of them.
I suspect only integer indices should be supported in the language, but
WebAPI/HTML5 might benefit if ES-next defines some kind of extension point
(short of host objects) that can be used to describe the legacy Web APIs
that do catchall indexing for arbitrary property names.

operator(). SpiderMonkey supports this for host objects of custom classes
implemented in C/C++. Python supports it in the language, and the feature
is widely used, e.g. in classes that model mathematical functions, in
libraries that create wrappers/proxies for objects and their methods, and
occasionally just so that some object quacks like a function (that is, it
can be passed where a function is wanted, e.g. to an API like
addEventListener, without requiring the user to write a lambda every time).

It makes sense to support overloading both `F(x)` and `new F(x)` syntax.
Several built-in functions behave differently depending on which syntax is
used; ES programs might want to do the same.

This use case is less important, but easy enough to support, if it's considered worthwhile:

Mutable types.  Allowing operators to apply to mutable types, and in the
case of operators such as += and ++, allowing them to modify an object in
place, has some uses. C++ supports this, but the reasons it makes sense in
C++ don't really apply to ECMAScript; Python is the only reference-language
I know of that supports it, and it is useful for cases where copying would
be costly, such as:
A *= 2;   // double each element of a matrix
    A += B;   // add two large matrices
Python uses operators for data structures more than ES currently does,
so += is used for extending a list in-place, and |= for adding to a
hash-set.

In addition I'll suggest a few non-goals:

Letting programs define arbitrary sequences of punctuation
characters to be operators (for example, ** or ~= or ->).

Overloading the comma operator.

Separately overloading !x, x&&, x||, x?:, if(x), while(x), etc. (Allowing
types to override ToBoolean should be enough.)

Overloading instanceof or typeof.

Overloading the relational operators to return anything other than a
boolean.

Overloading == and != separately. (A single "equals()" hook should
suffice.)

Overloading < <= > >= separately. (A single "compareTo()" hook should
suffice.)

Oddly enough, almost all of these things I call unnecessary are things several languages do. So clearly this is subject to some discussion to say the least!

It would be possible to write a proposal in near-spec-ready language that addresses this kind of question without assuming anything in particular about the dispatch mechanism (the text would refer to a DispatchOperation abstract operation) or the syntax for defining operator overloads. I'd be willing to attempt that, in the interest of having a concrete proposal on the table. Comments are welcome.

# Jürg Lehni (13 years ago)

The mention of the term made me wonder: Is it wrong to dream of JavaScript with operator overloading?

I have implemented it in Rhino's interpreter mode, and am using it in Scriptographer.org to be able to write much nicer code to deal with 2d vector arithmetics, and the benefits of that have been huge when using the platform for teaching programming to visually thinking students, as it happened over the past two years at the ECAL graphic design department in Lausanne, Switzerland.

E.g.:

var middle = (point1 + point2) / 2; var vector = point2 - point1;

var point = middle + vector.rotate(90);

Instead of:

var middle = point1.add(point2).divide(2); var vector = point2.subtract(point1); var point = middle.add(vector.rotate(90));

etc.

For those curious, here the repository with my Rhino modifications:

lehni/rhino/tree/operator-overloading

Best,

Jürg

# Mike Samuel (13 years ago)

2011/1/10 Jürg Lehni <lists at scratchdisk.com>:

The mention of the term made me wonder: Is it wrong to dream of JavaScript with operator overloading?

esdiscuss/2009-October/010068 discusses it a bit and links to other discussions.

# Mark S. Miller (13 years ago)

There is a current strawman at < strawman:value_proxies>. I like the

direction it is headed.

# thaddee yann tyl (13 years ago)

I see no reason to name the "floordiv" trap that way. Python has a good reason: they have more than one division operator (/ and //). The reason for it is that, at the beginning, the division operator behaved just like that of C: 1/2 gave 0, not 0.5. But Javascript already give the more accurate value, so there is no need for two operators.

I therefore suggest naming this trap "div".

# Erik Corry (13 years ago)

2011/1/10 thaddee yann tyl <thaddee.tyl at gmail.com>:

I see no reason to name the "floordiv" trap that way. Python has a

Agreed.

On a slightly more high level note it seems like there is a very large number of complex proposals being poured into Harmony. If they are all implemented the language will become unwieldy and complex both for users and implementers. Is there a sense in which we have a 'complexity budget' or does the committee feel we can add all proposals to the language?

On the concrete proposal I note that the strawman claims this can be used to implement bignums, but it seems to me there is no way to implement storage of arbitrary size so that would appear to be impossible. Am I missing something.

Another question: As I read the proposal, the dispatch is on the left hand side of binary operators. Does the proposal have a way for a+b to work where a is an old-fashioned number and b is a complex?

# François REMY (13 years ago)

?Well, you could implement BigNums with this proposal. You just need to make the assumption the browser use int32 to store integer numbers smaller than the max limit. Then, you build up an array that represent the big number, where arr[0] is its part from 0 to 2^32-1, arr[1] its part (=the bytes) from 2^31 to 2^64-1, and the like. You could also rely on something more subtile and less hazardous if you prefer.

Regarding the a+bi problem, I may have a solution : I propose the following methods : a.canAdd(b), return true if a.add(b) can succeed.

The default a.canAdd(b) method would check if "b" can be converted into the type of "a" using b.convertTo(a.constructor) or a.constructor.convertFrom(b). The default Function.prototype.canConvertFrom(b) would return true only if "b" is of type (or inherits from type) "this". In this case, the Complex class should implements some conversion logic to implement [[Number -- (widening) -> Complex]] and [[Complex --
(narrowing) -> Number]].

a = 1; b = new Complex(0,1); // b = i := sqrt(-1) a+b; ---> a.canAdd(b) ---> b.canConvertTo(Number) : no (because it has a complex part != 0) ---> Number.canConvertFrom(b) : no (because UA don't have this

implemented) ---> no (a+b is not evaluted as a.addRight(b)) ---> b.canAdd(a) ---> a.canConvertTo(Complex) : no (because UA don't have this

implemented) ---> Complex.canConvertFrom(a) : yes (because it's implemented by the

user) ---> yes ----> a+b is evaluated as b.addLeft(a);

When a.canAdd(b) && b.canAdd(a) AND a.operatorPriority==b.operatorPriority, a.addRight(b) is called.

I suggest to use some special syntax for those additions, and not use a true property called "add", because it can mess up many already-written code.

What about Complex.prototype = { operator add: function(b) { b=Complex.convertFrom(b); return new Complex(this.a+b.a, this.b+b.b); }, operator canConvertFrom: function(b) { return b.constructor==Complex||typeof(b)=="number"; }, .... // as no operators for addLeft/addRight are defined, addLeft and addRight are mapped to "add" (commutativity is implied). // as no operator for multiply is defined, default Object.prototype.[operator]multiply apply, which lead to an error if used with non-Number objects. } and Object.defineOperator/Object.getOperatorDescriptor/... ?

BTW, as it may cause huge difficulties for UAs, I propose to have the operators of String, Number, Date (& others) marked as read-only.

, François

-----Message d'origine---

# Mark S. Miller (13 years ago)

On Mon, Jan 10, 2011 at 2:12 AM, Erik Corry <erik.corry at gmail.com> wrote:

2011/1/10 thaddee yann tyl <thaddee.tyl at gmail.com>:

I see no reason to name the "floordiv" trap that way. Python has a

Agreed.

On a slightly more high level note it seems like there is a very large number of complex proposals being poured into Harmony. If they are all implemented the language will become unwieldy and complex both for users and implementers. Is there a sense in which we have a 'complexity budget' or does the committee feel we can add all proposals to the language?

I'm glad you raise this.

I have never heard anyone on the committee even hint that we should add all proposed features to the language. Different members of the committee have different complexity budgets, both in magnitude, but more importantly, in how we weight complexity: Kernel semantics? Overall user semantics? Implementation? Ease of use for novices that don't quite have any accurate semantic model? Ease of reasoning about programs, either informally, formally, or by automated tools?

I think all of us would agree that all of these are important. But each of us would bring tremendously different weightings to these issues. However, since the committee works by consensus, not majority, hopefully the end result will more closely approximate the intersection of our various budgets than the union.

# Brendan Eich (13 years ago)

Mark's reply is good. Another point: we incubate strawman proposals for indefinite future editions, we do not prematurely cut because something doesn't fit in ES6. So the strawmay count does not indicate language complexity in the next edition.

Also, bean-counting lots of little API wins of the kind crock has written up recently is not enlightening. Ideally library authors would do all that and any standardization would be de-jure recognition of de-facto standards (Array extras are the best example, Function bind and getters and setters mutatis mutandis).

The big ticket items IMHO remain modules, proxies, and scope wins (no global scope, let).

In light of the incubation argument and big-ticket items, I don't think value proxies break our complexity budget but they are very new. They're unlikely to get into ES6. Let's keep discussing here and working on the wiki as interest and time allow, and not try to kick them out for some false economy.

# Mike Shaver (13 years ago)

On Mon, Jan 10, 2011 at 10:55 AM, Brendan Eich <brendan at mozilla.com> wrote:

In light of the incubation argument and big-ticket items, I don't think value proxies break our complexity budget but they are very new. They're unlikely to get into ES6. Let's keep discussing here and working on the wiki as interest and time allow, and not try to kick them out for some false economy.

I'd also add, from my perspective helping direct Mozilla's efforts on the JS engine, that having more implementations doing experimental work to get experience with specific features (including how they can be made high-performance, and how they compose with key stack cohorts like the DOM) would be a huge help, and I think could dramatically improve the resulting quality of the spec. Erik: can the V8 team help in this way?

Mike

# Jim Deville (13 years ago)

Another idea would be to mimic Ruby's coerce protocol (www.engineyard.com/blog/2010/ruby-tips-numeric-classes). Essentially, inside of the definition of op(other), if you know how to operate on a given object, you do it. Otherwise, you call other.coerce(this), which returns a tuple of objects (ret) that can be operated on. Then you can do ret[0].op(ret[1]). If the coercion can't be done, coerce can throw and the operator can continue with normal failure patterns.

# Peter van der Zee (13 years ago)

Rather than overloading existing operators, might it be an idea to introduce a new generic "programmable" operator? It's just a thought. In all fairness it doesn't feel quite like js to me, but the desire to handle/define operators seems to be present. Maybe the @ sign would be fitting for this. It's already used in the spec to explain compound assignments. And it's big enough such that you won't easily mistake it for something else.

var r = x @ y;

Now, of course people will want to program multiple operators. So maybe something like

x @name@ y

would be better suited, where name may be pretty much anything except the at sign itself.

The programmable operator would probably be a binary function.

function @+@(x,y){ return x+y; } or function @+@{ return x+y; } (if/since it'd always be binary)

But one might think of constructs where you can define unary prefix/postfix operators.

Again, I'm not convinced this is the way to go myself, just throwing it out here. The whole proxy overloading thing just seems to "hide" what's actually going on and overly complicate things. In production, that's gonna haunt you some day.

# Fyodorov "Bga" Alexander (13 years ago)

Peter van der Zee пишет:

Rather than overloading existing operators, might it be an idea to introduce a new generic "programmable" operator? It's just a thought. In all fairness it doesn't feel quite like js to me, but the desire to handle/define operators seems to be present. Maybe the @ sign would be fitting for this. It's already used in the spec to explain compound assignments. And it's big enough such that you won't easily mistake it for something else.

var r = x @ y;

Now, of course people will want to program multiple operators. So maybe something like

x @name@ y

would be better suited, where name may be pretty much anything except the at sign itself.

The programmable operator would probably be a binary function.

function @+@(x,y){ return x+y; } or function @+@{ return x+y; } (if/since it'd always be binary)

But one might think of constructs where you can define unary prefix/postfix operators.

Again, I'm not convinced this is the way to go myself, just throwing it out here. The whole proxy overloading thing just seems to "hide" what's actually going on and overly complicate things. In production, that's gonna haunt you some day.

  • peter


es-discuss mailing list es-discuss at mozilla.org, mail.mozilla.org/listinfo/es-discuss

Look at Haskell :P

# Douglas Crockford (13 years ago)

On 11:59 AM, Fyodorov "Bga" Alexander wrote:

Peter van der Zee пишет: maybe something like x @name@ y Again, I'm not convinced this is the way to go myself, just throwing it out here. The whole proxy overloading thing just seems to "hide" what's actually going on and overly complicate things. In production, that's gonna haunt you some day.

This is not the place to be depositing random ideas or half-baked gems. This is a standards effort, maintaining what has become one of the world's most important programming languages. ECMA TC39 needs to be extremely cautious in its improvements and refinements.

So by all means, do the experiment. Implement your idea, and test it as broadly as you can. If it proves to have merit, then please bring it back and we may consider it for inclusion in a future edition.

A standards body should the last place you go to with new ideas, not the first.

I agree with your concern about unexpected behavior and the other symptoms of excessive complexity. We must be cautious here as well.

# Cormac Flanagan (13 years ago)

On Sun, Jan 9, 2011 at 11:51 PM, thaddee yann tyl <thaddee.tyl at gmail.com> wrote:

I see no reason to name the "floordiv" trap that way. Python has a good reason: they have more than one division operator (/ and //). The reason for it is that, at the beginning, the division operator behaved just like that of C: 1/2 gave 0, not 0.5. But Javascript already give the more accurate value, so there is no need for two operators.

I therefore suggest naming this trap "div".

Good point, thanks. I've incorporated this suggestion.

# Cormac Flanagan (13 years ago)

On Mon, Jan 10, 2011 at 2:12 AM, Erik Corry <erik.corry at gmail.com> wrote:

On the concrete proposal I note that the strawman claims this can be used to implement bignums, but it seems to me there is no way to implement storage of arbitrary size so that would appear to be impossible.  Am I missing something.

The operator handler could, for example, contain an array of JS ints to represent a bignum.

Another question:  As I read the proposal, the dispatch is on the left hand side of binary operators.  Does the proposal have a way for a+b to work where a is an old-fashioned number and b is a complex?

Yes. In this case where a is an old-fashioned number and b is a complex, the radd trap of b is invoked, passing argument a. I've updated the strawman to clarify.

# Cormac Flanagan (13 years ago)

On Sun, Jan 9, 2011 at 12:41 PM, Jürg Lehni <lists at scratchdisk.com> wrote:

The mention of the term made me wonder: Is it wrong to dream of JavaScript with operator overloading?

Hi Jürg,

There is strawman proposal along these lines that should fulfill your use cases. See

strawman:value_proxies

# Erik Corry (13 years ago)

2011/1/19 Cormac Flanagan <cormac at cs.ucsc.edu>:

On Mon, Jan 10, 2011 at 2:12 AM, Erik Corry <erik.corry at gmail.com> wrote:

On the concrete proposal I note that the strawman claims this can be used to implement bignums, but it seems to me there is no way to implement storage of arbitrary size so that would appear to be impossible.  Am I missing something.

The operator handler could, for example, contain an array of JS ints to represent a bignum.

Can different bignums have arrays of different sizes?

Another question:  As I read the proposal, the dispatch is on the left hand side of binary operators.  Does the proposal have a way for a+b to work where a is an old-fashioned number and b is a complex?

Yes. In this case where a is an old-fashioned number and b is a complex, the radd trap of b is invoked, passing argument a.  I've updated the strawman to clarify.

How about if the left hand side is a complex number and the right hand side is a decimal fp number?