Implement Operator overloading in TypeScript...

Topics: General
Oct 3, 2012 at 10:20 AM

It would be a great addition.

Fantasy example:

class Decimal
{
    static operator add(Decimal d1, Decimal d2) : Decimal
   {
             ....
   }
   
   static operator mul(Decimal d1, Decimal d2) : Decimal
   {
             ....
   }

}

var d1 = new Decimal('123.45');
var d2 = new Decimal('678.90');
var d3 = new Decimal('789.90');

var result = (d1 + d2) * d3;


//would render:


var result = (d1.add(d2)).mul(d3);

    }

}

Coordinator
Oct 4, 2012 at 8:35 PM

Thanks for feedback.  We likely won't do this because in TypeScript because we use types to check syntactic properties and not to give additional semantic information. 

For example, when you do an overload of a function, you give the function multiple types.  This helps the type checker know proper return types and catch you sending incorrect arguments.  When that code is compiled, those types disappear and leave the original function.   Likewise, we don't insert JavaScript when you add a cast to your code. 

Oct 5, 2012 at 9:31 AM

Is this very hard to implement in  actual design of TypeScript ?

I think it will make the language very powerfull and open way for beautiful abstractions....

 

Anyway, would be nice to have a standarized way to instrument the ast after parsing and type checking. where developers would add experimental feature, like operator overloading...

Are there any plans for this kind of extensibility?

Thanks

Coordinator
Oct 5, 2012 at 6:07 PM

I'm not sure it's possible to implement. 

Because TypeScript works directly with JavaScript, it keeps an "open system" view of how source compiles - meaning, it can't assume anything about how other code will work.  If JavaScript doesn't allow you to alter how '+' works between two objects, there's no way to maintain that the operator you've overloaded will behave correctly.  In TypeScript, there's a similar problem where we wouldn't be able to catch everywhere the operator is used to perform transformation when the type becomes unknown (or 'any'). 

Oct 5, 2012 at 11:44 PM

This should be the responsability of the programmer: to use proper type annotations...

Nov 12, 2012 at 7:34 PM

I agree with the desire supporting operator overloading. Calculations with financial, multicurrency data for example require - if readability is a requirement - overloading of the standard operators. And TypeScript in my opinion is about readability.

Nov 12, 2012 at 8:31 PM
Edited Nov 12, 2012 at 8:32 PM

I implemented convention based operators in Typescript, it's relatively easy. See below.

I think if the authors of typescript decide to implement it, it will be implemented in a snap.

Though i have the impression that somehow they are not yet fully clear about what to do next.

 

 

class Decimal 
{
    constructor ()
    {
    }

    public static opAdd_number(d1: Decimal, n: number): Decimal {
        ...
    }

    public static opAdd(d1: Decimal, d2: Decimal): Decimal
    {
        ...
    }   
    
    public static opSub(d1: Decimal, d2: Decimal): Decimal
    {
       ...
    }     

    public static opMul(d1: Decimal, d2: Decimal): Decimal
    {
        ...
    } 

    public static opDiv(d1: Decimal, d2: Decimal): Decimal
    {
        ...
    } 

    public static opDiv_n_d(n: number, d2: Decimal): Decimal
    {
        ...
    } 
}
            
//So you may write
var d1 = new Decimal();
var d2 = new Decimal();
var x = 1 + 2;
var d3 = d1*(d1 + d2) - d2/d1 + 2/d1;

//which get compiled to:
var d1 = new Decimal();
var d2 = new Decimal();
var x = 1 + 2;
var d3 = Decimal.opAdd(Decimal.opSub(Decimal.opMul(d1,(Decimal.opAdd(d1,d2))),Decimal.opDiv(d2,d1)),Decimal.opDiv_n_d(2,d1));


Nov 13, 2012 at 8:22 AM

I don't quite understand the arguments contra operator overloading above. Your example in code might need a mapping in the function-header from the real operator to the function (+ maps to opAdd), otherwise the compiler doesn't know how to translate the operators, but how difficult is that? I do understand plain JavaScript has no knowledge of types and that TypeScript has that knowledge - when variables are well defined - only at compile-time. Nonetheless why not offering that possibility to users of TypeScript that mind well typed variables?

Nov 13, 2012 at 8:27 AM

I have the impression that implementing some kind of C# like attributes in typescript will offer the possibility to extend the compiler and map in this case the operators.

Coordinator
Nov 13, 2012 at 4:28 PM

The general rule of thumb is that types are erasable, meaning that we should be able to erase all the types from a TypeScript file and then compile that and get the same result.  This is incidentally why function overloading overloads only on the declaration/type side and not on the actual function definition.

There are a couple of reasons to follow the rule of thumb: we're closer to the original JavaScript semantically, we're more mechanical in our translation, we inject less code that you didn't write, etc.

Just as ursuletzu suggests, it's possible to set up a straightforward translation when the type information is known.  In many static languages, this is no problem as the types are almost always known, or we can do runtime checks when they aren't.  TypeScript, though, has to be able to play well with JavaScript, and we don't have any way of passing to that JavaScript a way of saying "when you see '+' call opAdd". 


Nov 13, 2012 at 11:37 PM
The more I see discussions like this around here, the more I think there needs to be some more general communication from the TypeScript team explaining and reinforcing the goals of the project. In particular, people seem to have trouble with the basic idea that classes created in and compiled from TypeScript should be consumable from JavaScript code, which is where confusion like this thread arises.
Just a couple of blog posts from authoritative sources would help.
Cheers,
Mark
Sent from Surface Mail
From: jonturner
Sent: ‎13‎ ‎November‎ ‎2012 ‎16‎:‎28
To: mark@markrendle.net
Subject: Re: Implement Operator overloading in TypeScript... [typescript:397848]

From: jonturner

The general rule of thumb is that types are erasable, meaning that we should be able to erase all the types from a TypeScript file and then compile that and get the same result. This is incidentally why function overloading overloads only on the declaration/type side and not on the actual function definition.

There are a couple of reasons to follow the rule of thumb: we're closer to the original JavaScript semantically, we're more mechanical in our translation, we inject less code that you didn't write, etc.

Just as ursuletzu suggests, it's possible to set up a straightforward translation when the type information is known. In many static languages, this is no problem as the types are almost always known, or we can do runtime checks when they aren't. TypeScript, though, has to be able to play well with JavaScript, and we don't have any way of passing to that JavaScript a way of saying "when you see '+' call opAdd".


Nov 19, 2012 at 10:18 AM
Edited Nov 19, 2012 at 10:19 AM
ursuletzu wrote:

I implemented convention based operators in Typescript, it's relatively easy. See below.

But how TypeScript understands it must compile '+' to 'opAdd'? When I tried your example, I got an error: "Operator '+' cannot be applied to types 'Decimal' and 'Decimal'"

Nov 19, 2012 at 10:54 PM
Edited Nov 19, 2012 at 10:54 PM

I implemented operator overloading in my personal fork of the project.

Nov 20, 2012 at 10:31 AM
ursuletzu wrote:

I implemented operator overloading in my personal fork of the project.

Any chance you need beta testers for this fork? :))))