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

Implement operator overriding for == and != #7742

Closed
hungrybluedev opened this issue Dec 31, 2020 · 10 comments
Closed

Implement operator overriding for == and != #7742

hungrybluedev opened this issue Dec 31, 2020 · 10 comments
Assignees
Labels
Feature/Enhancement Request This issue is made to request a feature or an enhancement to an existing one.

Comments

@hungrybluedev
Copy link
Member

Currently, V supports overloading the arithmetic operators for structs. These include +, -, /, and *. There are plans to support < and > as well. However, == and != are generated automatically for the structs. While this is a practical solution that covers several cases, there remain some examples where a custom implementation by the user would be beneficial.

For instance, assume a struct Fraction with members n and d. The compiler is most likely to compare the corresponding elements and call it done. However, the better way to compare two fractions (say f and g) is to cross-multiply the numerators and denominators (like a = f.n * g.d and b = g.n * f.d) and then compare them (a == b).

This problem generally extends to cases where two structs can be equal even if their components are not. It can be argued that the structs in question could be designed better to avoid having differing internals. However, it is not always feasible or possible to do so. There could be several reasons for that, like performance, lazy evaluation, and so on.

@hungrybluedev hungrybluedev added the Feature/Enhancement Request This issue is made to request a feature or an enhancement to an existing one. label Dec 31, 2020
@Delta456
Copy link
Member

Delta456 commented Jan 2, 2021

What do you think about this? @medvednikov

@medvednikov
Copy link
Member

Yes, custom != and == are fine.

@Delta456 Delta456 self-assigned this Jan 2, 2021
@esquerbatua
Copy link
Contributor

@hungrybluedev currently V supports < and > operators too

@esquerbatua
Copy link
Contributor

@Delta456 @medvednikov it's planned to allow override all of the oprators?

@Delta456
Copy link
Member

Delta456 commented Jan 3, 2021

No because the user has to write readable code, we shouldn't be going like how C++ did. 🙂

@hungrybluedev
Copy link
Member Author

hungrybluedev commented Jan 3, 2021

@hungrybluedev currently V supports < and > operators too

Yeah that's because @Delta456 recently added support for it. :)

Once == is in place, we can easily support <= as a combination of < and ==. Same for >=. These should be autogenerated and the user doesn't need to overload these.

@dumblob
Copy link
Contributor

dumblob commented Jan 3, 2021

Once == is in place, we can easily support <= as a combination of < and ==. Same for >=. These should be autogenerated and the user doesn't need to overload these.

Well, that's not generally true as it would harm performance - imagine e.g. comparison of approximate numbers (like any float). There you want to implement < as !>= (and analogically > as !>=) and thus if you implemented >= with the same code as !< is implemented you would actually do some unnecessary double work (out of which basically none would be optimized away by the compiler as floats are hard and compilers try to not touch them for correctness). And if you didn't implement it like this, it would not be correct from the approximate computation theory (and thus you'd get undefined results from the comparison).

@hungrybluedev
Copy link
Member Author

@dumblob Your concerns about floating points are correct. But I believe V already uses an internal epsilon for comparison of floating points. We need to see if that is sufficient.

Also, on Discord, we discussed about reducing needless duplication.

  1. If the user wants only == and !=, then let them overload the equals method, or generate it automatically.
  2. If the user wants all comparison methods, just let them overload a method like compare or compare_to. Do not allow equals. That way, all the operators: ==, !=, <, <=, >, >= can rely on this one function.

The comparison function returns 0 if two structs are equal, a negative integer if the parameter is "larger" or a positive integer if the parameter is "smaller". Just like in the Comparable interface for Java.

@dumblob
Copy link
Contributor

dumblob commented Jan 3, 2021

But I believe V already uses an internal epsilon for comparison of floating points.

It does not 😉 (as is visible from the PR I linked above - #5180 (comment) ). Thus currently any float comparisons in V are undefined. But this topic shouldn't be discussed here (but rather in vlang/vtl#2 or vlang/vtl#2 ).

If the user wants all comparison methods, just let them overload a method like compare or compare_to. Do not allow overloading equals method. That way, all the operators: ==, !=, <, <=, >, >= can rely on this one function.

Hm, that makes sense from the API stand point. The only downside is performance (compare and compare_to will be slightly slower due to their "generality"), but I suppose that's not a big concern if they'll be inlined and later highly optimized by the compiler.

@Delta456
Copy link
Member

Delta456 commented Jan 3, 2021

Implemented in 9033099

@Delta456 Delta456 closed this as completed Jan 3, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature/Enhancement Request This issue is made to request a feature or an enhancement to an existing one.
Projects
None yet
Development

No branches or pull requests

5 participants