tc39 / proposal-operator-overloading

MIT License
619 stars 20 forks source link

The syntax should be scoped to a block instead of a module #40

Open Jack-Works opened 3 years ago

Jack-Works commented 3 years ago

Current:

with operators from Vector;
3 * new Vector([1, 2, 3])                       // ==> new Vector([3, 6, 9])

Proposed:

with operators from Vector {
    3 * new Vector([1, 2, 3])
}

Reason:

It will not work well for bundlers like rollup

https://rollupjs.org/repl/?version=2.38.1&shareable=JTdCJTIybW9kdWxlcyUyMiUzQSU1QiU3QiUyMm5hbWUlMjIlM0ElMjJtYWluLmpzJTIyJTJDJTIyY29kZSUyMiUzQSUyMmltcG9ydCUyMCcuJTJGYW5zd2VyLmpzJyUzQiU1Q25jb25zb2xlLmxvZyhhbnN3ZXIlMjAlMkIlMjAyKSUyMCUyRiUyRiUyMHJ1bnRpbWUlMjBjb3N0JTIwdG9vISUyMChzZWUlMjB0aGUlMjByaWdodCUyMHBhbmVsKSUyMiUyQyUyMmlzRW50cnklMjIlM0F0cnVlJTdEJTJDJTdCJTIybmFtZSUyMiUzQSUyMmFuc3dlci5qcyUyMiUyQyUyMmNvZGUlMjIlM0ElMjIlMkYlMkYlMjAhISEhJTIwd2l0aCUyMG9wZXJhdG9yJTIwZnJvbSUyMFZlY3RvciUyMCEhISElNUNuYSUyMCUyQiUyMGIlMjAlMkYlMkYlMjBydW50aW1lJTIwb3ZlcmhlYWQlMjBvZiUyMG92ZXJsb2FkaW5nJTIyJTJDJTIyaXNFbnRyeSUyMiUzQWZhbHNlJTdEJTVEJTJDJTIyb3B0aW9ucyUyMiUzQSU3QiUyMmZvcm1hdCUyMiUzQSUyMmVzJTIyJTJDJTIybmFtZSUyMiUzQSUyMm15QnVuZGxlJTIyJTJDJTIyYW1kJTIyJTNBJTdCJTIyaWQlMjIlM0ElMjIlMjIlN0QlMkMlMjJnbG9iYWxzJTIyJTNBJTdCJTdEJTdEJTJDJTIyZXhhbXBsZSUyMiUzQW51bGwlN0Q=

ljharb commented 3 years ago

I don’t find bundler flaws a compelling motivation whatsoever, but i do like that it makes the scope where the magic operator applies much more explicit and clear.

littledan commented 3 years ago

The idea of this writeup is that it is scoped to the enclosing block, not the whole module. I agree that this is an important property, including to enable bundling. The README should probably be clarified on this point.

ghost commented 3 years ago

The syntax with x from y { ... } seems similar to the old with statement: with (x) { ... }, could that cause any confusion? Otherwise the block looks better, it limits it to an explicit scope, but what would be so bad about this:

{
    with operators from Vector;

    3 * new Vector([ 1, 2, 3 ]);
}

It's currently block scoped already.

alexrock commented 3 years ago

How would I declare an exported class that uses overloaded operators from another class in an idiomatic way and using blocks?

Example not using blocks:

import { Vector } from './vector'

with operators from Vector

export class Foo {
  bar() {
    3 * new Vector([1, 2, 3])
  }

  // ... more methods using overloaded operators
}
Jack-Works commented 3 years ago

I think now this issue can be resolved by the module fragments proposal even it is module scoped.

jhmaster2000 commented 2 years ago

How would I declare an exported class that uses overloaded operators from another class in an idiomatic way and using blocks?

Example not using blocks:

import { Vector } from './vector'

with operators from Vector

export class Foo {
  bar() {
    3 * new Vector([1, 2, 3])
  }

  // ... more methods using overloaded operators
}

If that class is the only one in the file, you can just use it like that without issues since operators dont get imported automatically through modules.

If you wanted to put other things besides that class in that same file, and those other things for some reason break with Vector operators overloaded, with the current proposal you'd have to use the with operators statement on every method of Foo using them I guess. Perhaps decorators could aid in declaring class-level overload usage like so:

import { Vector } from './vector';

@Operators from Vector;
export class Foo {
  bar() {
    3 * new Vector([1, 2, 3]); // overloaded
  }
  // ... more methods using overloaded operators
}

3 * new Vector([1, 2, 3]); // not overloaded