Hacker News new | ask | show | jobs
by WalterBright 875 days ago
> I don't think there is a single worse design decision in C++ or Rust than allowing someone to redefine what + means on some arbitrary type.

This has perplexed us for D. Experience with C++'s iostream's operator overloading meant running away screaming. Another terrible thing is people would code up DSL's using operator overloading, such as a Regex language. The horror there is the source code looks like ordinary C++ arithmetic, but it is actually doing Regexes.

So, how to allow operator overloading for arithmetic, but not for other porpoises?

1. Only allow overloading of arithmetic operators (i.e. no overloading of unary *) and [ ]

2. Only allow < overloadable, instead of < <= > >=. This enforces symmetry.

3. Don't allow overloading of && || ?:

4. A strong Compile Time Function Execution feature which enables DSLs in the form of string literals

5. Develop a culture of operator overloading is for arithmetic

This has worked well.

2 comments

> Another terrible thing is people would code up DSL's using operator overloading, such as a Regex language.

There's nothing wrong with this if your language has proper hygienic macros. Then you can have all of math_expr![ … ], float_expr![ … ] (dangerous! order of operations may affect results), regex_expr![ … ], or even stream_concat_expr![ … ] all using the same operators while meaning completely different things and preserving complete extensibility. They would even be composable since each macro invocation would desugar its own operators and leave those in other contained macros unaltered.

Macros form their own hell, hygienic or not. The reason is inevitably these evolve into one's personal, undocumented, quirky, unmaintainable language.
This sounds great if you’re stuck inside the C-derivative mindset block. I.e. the best you can do.