-
-
Notifications
You must be signed in to change notification settings - Fork 3k
Description
This proposal is on the surface similar to previous proposals of operator overloading (see #427 and #871). But I think there's a case to be made for a related proposal
This is also related to proposals like complex numbers and vector operations in the standard library (see #947)
Proposal
There should be a syntax for defining operators and the name of the function that implements them (in the cases where the operator is not implemented by a single instruction). This syntax could/should only be permissible in the standard library.
Example:
operator (a / b) __udivdi3(a: u64, b: u64) u64 { ... }
operator (a + b) addVec3(a: Vec3, b: Vec3) Vec3 { ... }
An operator should ideally be verified by the compiler to have no side-effects (see #520) of any kind. Possibly there should be other even stricter requirements (no non-inline calls?)
Rationale
(Not in order of importance)
-
Niceness - I've always found it nice when operators are defined in the standard library (see Julia and Nim). It makes the language/compiler feel less magic, and you document which operators are present and which types they are defined for in a way that's guaranteed to be correct and up to date.
-
Explicit over implicit and magic - Which operators have implementation in the compiler_rt library (and the mapping from operator to function name) feels awfully magic. I think all this is closely tied to LLVM? If this could be handled more explicitly in the standard library, it could make it easier when porting to other platforms, implementing other backends than LLVM, etc.
-
Easier to add operators on other types - There's good arguments against operator overloading in general, but if we can add operators to the standard library, we could more easily add operators on complex numbers and vectors. Only supporting it for your standard ints and floats is pretty arbitrary from a computer architecture standpoint after all. Not really a good reason for it other than "C did it".
-
More future-proof. Both GCC and Clang/LLVM has support for vector extensions to C. This says a lot about the desire for vector operations in C, but because it can't be added in a standardised way, we've ended up with ugly extensions.
-
Easier to better support various CPU and DSP architectures.
Discussion
The only reason I could see why this proposal would be negative is that people might be confused that operator definitions exist, but are only allowed in the standard library. I think that's a small price to pay.
If Zig only allows operator on a certain set of types, it should have a clear philosophy behind it. Why only ints and floats? Because they are implemented by machine instructions? But some architectures don't have instructions for float types, and some have them for vector and complex types. I think Zig should implement them in all cases where there exists a (non-obscure) architecture that implements them.
As an aside: It'd be kind of cool if the compiler could take some Zig source code and translate all the operators into explicit function calls and write out the resulting code. It'd also be cool if the standard library defined assembly for an operator even if it's just a single instruction. That would make it nice for people who are just starting to learn about assembly and processor architecture, even if the code is ignored by the compiler. You could also imagine a super-simple compiler backend (like TCC for C) that actually used those definitions. Such a backend could make it easier to get started on new and custom architectures maybe?