Why can't we derive struct's?

H. S. Teoh hsteoh at quickfur.ath.cx
Mon Dec 24 21:31:24 UTC 2018

On Mon, Dec 24, 2018 at 11:57:50AM -0800, Walter Bright via Digitalmars-d wrote:
> Or like operator overloading. C++ has much more expansive rules for
> operator overloading. They lead to clever programs, and some people
> swear by them, but are they *better* programs? For example,
> * iostreams
> * regex DSL https://pdfs.semanticscholar.org/e630/5f84bca36251fd5a4ffa5f00e0effc8aaa7d.pdf
> ? I don't buy it. I've never seen an elegant use of the more expansive
> power (even though many insist those two examples are elegant).

Haha, I happen to have the same opinion on the above two examples as you

Iostream's (ab)use of << and >> contrary to their intended meaning is
absolutely atrocious.  The wrong precedence of << and >> (as far as I/O
is concerned) leads to required parentheses where you don't expect them,
with odd results if you forget. And a readability nightmare when you
need to output an integer shifted by some amount (which << is output and
which is bit shift?).  Not to mention the whole hack on top of a patch
on top of a festering bandage concept of I/O manipulators and other such
"clever" ideas that focus on solving the wrong problem.  The whole thing
is a code smell, IMNSHO. Back when I still wrote C++, I avoided iostream
like the plague and stuck with cstdio where possible.  I've had to debug
iostreams-based code before, and it made me cringe every time.

And the regex DSL is just ... wow. It takes operator overloading abuse
to whole new levels never before imagined.  The "regexes" you write with
this mess of a design resemble *nothing* like regexes, and had
absolutely strange precedence rules due to the abuse of operators to
mean things far removed from their usual meanings. And have you seen the
error messages? Whoa. It's the epitome of everything that's wrong with
C++. This kind of code is barely writable and basically unmaintainable.
Two symptoms that point to fundamental problems in the whole design. D's
std.regex.ctRegex, for all of its warts, lets you write things like:

	auto re = ctRegex!`(\w+)@((\w+)(\.(\w+))*)`;

while offering the same (arguably better) benefits. Try to write the
equivalent with that horrible C++ regex library, and it becomes crystal
clear that the D version got it right, warts aside.[1]

[1] (Like seriously, just last week I rewrote one of my programs to
completely avoid std.regex, because the mere act of using a regex adds 5
*seconds* to the total compilation time. And it's not even a complicated
regex to begin with. Though, to be fair, the fact that we're annoyed
over seconds rather than minutes or, God forbid, hours, that would have
been usual fare in complex C++ projects, is a testament to how far ahead
D is in this respect, in spite of said warts.)

I've also worked with C++ libraries that overload the comma operator...
Oh yes, the evil comma operator plus absolutely evil abuse of operator
overloading. Oy.

This kind of every-man-for-himself operator overloading leads to
unmaintainable code where any piece of syntax can mean absolutely
*anything*, because you can overload anything and everything, and you
cannot even remotely begin to guess what a piece of code actually does
just by looking at it.  You might have had a fighting chance if you
could only trace the calls to their call targets, but thanks to the
lovely C++ blend of overload resolution rules, Koenig lookup, SFINAE,
and implicit conversions, you need to be a language lawyer just to
figure that out.

D got it right by restricting the overloading of <, >, ==, etc., to a
couple of consistent functions, instead of C++'s encouraging abuse by
allowing arbitrary, unrelated implementations of < and >, for example,
while discouraging correct use by requiring excessive boilerplate to
overload <, then >, then ==, then !=, then <= and >=, just to be sure
you covered all the bases.

But I suppose we should count our blessings, that the iostream authors
didn't choose to overload < and > for I/O instead of << and >> (which
you absolutely could, if you're bent on writing bad code), so there
remains something to be appreciated here, I guess.</sarcasm>


Skill without imagination is craftsmanship and gives us many useful objects such as wickerwork picnic baskets.  Imagination without skill gives us modern art. -- Tom Stoppard

More information about the Digitalmars-d mailing list