upvote
Andrew talks about it because it introduces hidden control flow where you're expecting simple operators. In Zig anything that deals with control flow is a keyword (including short circuiting and, which is `and` instead of `&&`).

I'd argue though that the real disadvantage to having overloadable arithmetic is that you're limited to one implementation. This is actually my biggest beef with Rust, namely traits/type classes. It locks you into a single implementation when you may want to do something different based on the context. Zig pushes the dispatch decision to the callsite, not a trait subsystem (see how Zig implements hash mays for example). So I'd personally prefer to use a DSL, since it lets me specify what type of dispatch to use.

reply
Overloadable operators are not an instance of hidden control flow. Overloadable operators represent a user-defined function call, and thus can't influence control flow any more than a regular function. And if regular functions can't do anything weird to control flow (e.g. if your language already lacks exceptions (or even weirder things like Ruby-style procs)), then overloadable operators can't either.

> It locks you into a single implementation when you may want to do something different based on the context.

If you want differing behavior in a certain context, and if you don't want to use a different method to make the differing behavior explicit (e.g. the `wrapping_add` methods that Rust provides on numeric types), then you can use a different type for that context, e.g. the `std::num::Wrapping` type that Rust provides.

reply
> Overloadable operators are not an instance of hidden control flow.

In general perhaps not, but in Zig it definitely does. Zig considers calling a function to change control flow, because it's no longer just an operator but something that can cause side effects, includinh mutating in place. Perhaps control flow isn't the right term, maybe non-trivial would be better?

With regard to wrappers, I personally find them ugly since 1. They bring in indirection, and I have a personal vendetta against unnecessary indirection, 2. Wrapping doesn't compose well and is a pain to shephard between representations, 3. It's harder to make a function generic across different representations, and 4. Wrappers often don't re-export everything available to their underlying value.

reply