H. S. Teoh
Posted in reply to Paulo Pinto
| On Wed, Nov 30, 2022 at 12:13:52PM +0000, Paulo Pinto via Digitalmars-d wrote:
> On Wednesday, 30 November 2022 at 01:09:03 UTC, H. S. Teoh wrote:
[...]
> > And to elaborate a little, for those people who groan at "yet another library type": a common objection is that a library type has poorer error messages. Well, it's just the same thing in different clothes: if a library type can't have good error messages, why is that? Because the language cannot express certain things, or can't do it well, so the library author's hands are tied. Giving up and pushing the type into the language is merely avoiding the problem (now the compiler writer has to solve the same problems, only in the compiler -- the amount of effort required is equivalent). What actually addresses the problem is: fix the language so that the library author *can* provide good error messages.
> >
> > Because this isn't just about adding sumtype or whatever other magic type, this is about making it possible for *any* user type to provide the same level of functionality as built-in types. It's about empowering the library writer so that he can replicate the power of a built-in type, integrated so well into the language that it feels like native type. This includes containers that behave like built-in arrays, ARC'd types that behave like pointers, etc.. Solve this at the core, and it will enable progress on many other fronts. Fail at this, and you're doomed to putting out individual fires one by one, ala whack-a-mole. Today it's sumtypes, tomorrow it's ARC types, the next day it's head-immutable, it will never end.
[...]
> We already have C++ for that, beware of having wishes coming true.
Yes and no. C++ does let you customize all sorts of things (including dangerous things like unary `operator&`, `operator,`, and other such things that *really* mess with program syntax), but it does so in an unclean, non-orthogonal way that gives you 1 way to solve your problem plus 10 other ways of shooting your foot.
Take for example overloading the comparison operators. Instead of D's much saner approach of having a single opCmp that ensures consistency between <, <=, >=, >, C++ lets you overload each of those operators separately. As a result, library code has tons of boilerplate (you need
>=4 operator overload functions instead of just a single opCmp), is
fragile (the compiler does not help you maintain consistency between operator<, operator<=, operator>=, and operator>=), and wide open for abuse (I can, for example, write operator< to be an input operator and operator> to format your hard disk).
In the meantime, nothing lets user code dictate how a custom type / function should behave in the face of Koenig lookup + SFINAE, a nasty combination where in order to understand which overload just got called, you have to understand the entire codebase (an impossible task in a large project).
IOW, C++ lets you customize everything, yes, but it does so in the least optimal, most fragile, unorthogonal, and unmaintainable way.
What D needs is hooks into core semantics in the pattern of opEquals/opCmp, not in the pattern of C++'s operator==, operator!=, operator<, operator<=, ad nauseum. This requires careful thought and design, not just blindly going "oh user code wants to overload the comma operator? sure, just add operator,() and you're all set!" or "oh user code wants to override const? sure, why not introduce operator const() to the language". The user should be empowered, yes, but with a properly-designed tool, not a lit bundle of dynamite with which to blow himself up.
T
--
If it breaks, you get to keep both pieces. -- Software disclaimer notice
|