A problem I encountered while writing custom stdlib, is that certain language features expect stdlib to be there.
For example, <=> operator assumes, that std::partial_ordering exists. Kinda lame. In the newer C++ standards, more and more features are unusable without stdlib (or at least std namespace).
At least you have the chance to implement your own std::partial_ordering if necessary; in most languages those kind of features would be built into the compiler.
Haskell solves this nicely: your own operators just shadow the built-in operators. (And you can opt to not import the built-in operators, and only use your own. Just like you can opt not to import printf in C.)
that's not the issue, the problem is the operator is required by the language to return a type from the stdlib, so you have to pull in the stdlib to get that type
In Haskell, when you define your own operators (including those that have the same name as those already defined in the standard library), you can specify your own types.
There's basically no operators defined 'by the language' in Haskell, they are all defined in the standard library.
(Of course, the standard library behaves as-if it defines eg (+) on integers in terms of some intrinsic introduced by the compiler.)
Sometimes standard library types defined in terms of compiler-builtins like `typedef decltype(nullptr) nullptr_t` but that doesn't always make sense. E.g. for operator<=> the only alternative would be for the compiler to define std::partial_ordering internally but what is gained by that?
Well, just the idea that you can use the entire core language without `#include`'ing any headers or depending on any standard-library stuff, is seen as a benefit by some people (in which I include myself). C++ inherited from C a pretty strong distinction between "language" and "library". This distinction is relatively alien to, say, Python or JavaScript, but it's pretty fundamental to C that the compiler knows how to do a bunch of stuff and then the library is built _on top of_ the core language, rather than alongside it holding its hand the whole way.
Your example with partial_ordering is actually one of my longstanding pet issues. It would have been possible (I wrote in https://quuxplusone.github.io/blog/2018/04/15/built-in-libra... ) to define
using strong_ordering = decltype(1 <=> 2);
using partial_ordering = decltype(1. <=> 2.);
But it remains impossible, AFAIK, to define `weak_ordering` from within the core language. Maybe this is where someone will prove me wrong!As of C++14 it's even possible to define the type `initializer_list` using only core-language constructs:
template<class T> T dv();
template<class T> auto ilist() { auto il = { dv<T>(), dv<T>() }; return il; }
template<class T> using initializer_list = decltype(ilist<T>());
(But you aren't allowed to do these things without including <compare> resp. <initializer_list> first, because the Standard says so.) Note that even for C the dependency from compiler to standard library exists in practice because optimizing compilers will treat some standard library functions like memcpy specially by default and either convert calls to them into optimized inlined code, generate calls to them from core language constructs, or otherwise make assumptions about them matching the standard library specification. And beyond that you need compiler support libraries for things like operations missing from the target architecture or stack probes required on some platforms and various other language and/or compiler features.
But for all of these (including the result types of operator<=>) you can define your own version so it's a rather weak dependency.
> C++ inherited from C a pretty strong distinction between "language" and "library".
This is long gone in ANSI/ISO C, as there are language features that require library support, like floating point emulation, followed by threading, memory allocation (tricky without using Assembly), among others.
Which is why freestanding subset exists, or one has to otherwise call into OS APIs as alternative to standard library, like it happens on non-UNIX/POSIX OSes.