Comment #0 by qs.il.paperinik — 2023-07-07T13:48:52Z
For user-defined types, if `a + b` works, it’s because `typeof(a)` has `opBinary` and `a.opBinary!"+"(b)` compiles, or `typeof(b)` has `opBinaryRight` and `b.opBinaryRight!"+"(a)` compiles. (If both are present, it seems `opBinaryRight` is preferred.
If both are built-in types, there are no `opBinary` or `opBinaryRight`, as well as other operators such as `opEquals` and `opCmp`.
It would make meta-programming a lot easier if one wouldn’t have special-case built-in types and those operator (member) functions would Just Work.
For some cases, they could even be defined in object.d as free functions, but it would be ideal if the compiler just pretended that those types had the operator member functions.
Comment #1 by dkorpel — 2023-08-08T10:15:26Z
If I understand correctly, you want the compiler to rewrite `1.opBinary!"+"(2)` to `1 + 2` for meta-programming. Can you give an example where you want to use this, instead of just the + operator?
Comment #2 by qs.il.paperinik — 2023-08-08T10:34:24Z
(In reply to Dennis from comment #1)
> If I understand correctly, you want the compiler to rewrite
> `1.opBinary!"+"(2)` to `1 + 2` for meta-programming. Can you give an example
> where you want to use this, instead of just the + operator?
I don’t want to write `1.opBinary!"+"(2)` directly, there’s clearly not much use for this, but I definitely want to be able to use the `hasMember` trait or something like that. It makes it easier to forward operations as well (currently, you need a mixin). With `opBinary` (and `opUnary`), it’s rather unspecific, but think of `opCall`, `opIndex`, `opEquals` or `opCmp`.
Just imagine how much clearer template code becomes when the question “Does this support comparison?” is exactly identical to “Is there a member `opCmp`?”. Same for `opEquals`. Same for `opCall`.
It’s mostly about consistency and lowering the mental burden. Ideally, built-in types are as un-special as possible. If built-in types behaved like user-defined types, there should be those member functions.
I stumbled into this when attempting to write a trait to find out if a type has partial comparison, i.e. has values that are neither ≤ nor ≥. Ideally, you check the result of `opCmp`, but no, there’s so many built-in types that I’m never really sure I handled all.
Comment #3 by robert.schadek — 2024-12-13T19:30:06Z