Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implicitly overloaded operators and sanity restrictions #53

Open
jhmaster2000 opened this issue Feb 7, 2022 · 0 comments
Open

Implicitly overloaded operators and sanity restrictions #53

jhmaster2000 opened this issue Feb 7, 2022 · 0 comments

Comments

@jhmaster2000
Copy link

jhmaster2000 commented Feb 7, 2022

We should attempt to more clearly define overloading on a per-operator basis, such as specifying operators to be implicitly overloaded based on others, which reduces the amount of operator overloading code a developer has to write and helps ensure operator consistency and predictability (one of the main goals of this proposal), aswell as establishing certain sanity restrictions to some operators. I propose the table below as an initial draft of this idea:

OP Kind Overloadability Details
+ Binary Full
- Binary Full
* Binary Full In theory, * and / are mutually implicit through the x / 2 === x * 0.5 mathematical property, but calculating the matching opposite number programatically is not efficient, additionally there would be ambiguity when trying to decide which of the two would be overloadable and which would be implicit, as it would work both ways, therefore it's better and more efficient to just have user's overload both manually.
/ Binary Full Read above.
% Binary Full In theory, % could be implicitly overloaded by having the JS engine repeatedly call the overloaded / operator with the operand until the next operation results in <= 0, but this is likely inefficient, so it's better and simpler to just have a % overload using the operator itself.
** Binary Full Just like % with /, the same goes for this and *, read above.
+ Unary Full
- Unary Full
++ Prefix Implicit operator++prefix(a) is identical to operator+=(a, 1).
-- Prefix Implicit operator--prefix(a) is identical to operator-=(a, 1).
++ Postfix Implicit Same as it's prefix variant, but returns a instead of a + 1.
-- Postfix Implicit Same as it's prefix variant, but returns a instead of a - 1.
== Binary Controlled "Controlled" means this operator is overloadable but must meet certain criteria, or errors will throw when it's used. In this case, this operator should always return a boolean.
< Binary Controlled Same as ==, read above.
> Binary Controlled Same as ==, read above. Additional: Why not implicitly overload > by using ! on the return value of <? For the same ambiguity reason mentioned in * earlier, but also because < and > are not always guaranteed to be opposing values even with the same operands, some examples being 0 < 0 and 0 > 0, where both cases are false, and the cases where NaN is involved, which always evaluate to false no matter what.
<= Binary Implicit Based on the result of operator<(a, b) || operator==(a, b).
>= Binary Implicit Based on the result of operator>(a, b) || operator==(a, b).
~ Unary Full
& Binary Full
^ Binary Full
| Binary Full
<< Binary Full
>> Binary Full No, it's not possible to implicitly overload this from << due to there being no guarantee in the overload output being a primitive number.
>>> Binary Full It's also not possible to imply this from >> for the same reason as above.
[] Getter Limited This operator is marked as "Limited" since it is not fully overloadable, as specified by the current proposal in the README, this is only for integer operands, more specifically valid array indexes (0 to 4294967294).
[]= Setter Limited Same as above.
OP= Setter Implicit This is a wildcard entry for all other assigning operators, which are all implied from their respective operator's return value which is then assigned to the left operand variable.

Extra Notes

  • I would like to point out I disagree with the non-overloadability of some operators defined by the current proposal, namely the ! operator, but I chose to not introduce it here to keep this issue focused on it's main goal vs. going off track with debate over the ! operator, instead I will make a separate issue for it.

  • I acknowledge the restrictions imposed on ==, <, >, <= and >= may be seen badly as they seemingly make what might seem like an obvious great usecase impossible, which is array comparison, such as: [1, 3, 5, -2] >= [2, 3, 4, -1] would result in [false, true, true, false] (one-on-one comparison), but the "must return boolean" requirement for >= would make this impossible. However, what you may not realize is the above is not needed at all in JS, for we have a perfectly suited built-in array method for this already in the language, Array.map(), the above sample would be the same as [1, 3, 5, -2].map((n, i) => n >= [2, 3, 4, -1][i]). Sure it's a little bit longer but it's perfectly doable, especially since the sample using the hypothetical operator overloading wouldn't be possible either way even without restrictions on >='s return type, since this proposal currently specifies no way of applying operators to built-in objects such as Array.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant