Small vs large standard library:
A small standard library with most functionality in independent, community-maintained packages has given us API friction as types, traits (type classes), etc are hard to coordinate across maintainers and separate package release cycles. We ended up with lots of uncomfortable conversions at API boundaries.
Here's a number of examples of problems we currently have:
- Conversions between our 5(!) string types are very common.
- Standard library I/O modules cannot use new, de-facto standard string types (i.e. `Text` and `ByteString`) defined outside it because of dependency cycle.
- Standard library cannot use containers, other than lists, for the same reason.
- No standard traits for containers, like maps and sets, as those are defined outside the standard library. Result is that code is written against one concrete implementation.
- Newtype wrapping to avoid orphan instances. Having traits defined in packages other than the standard library makes it harder to write non-orphan instances.
- It's too difficult to make larger changes as we cannot atomically update all the packages at once. Thus such changes don't happen.
Empirically, languages that have large standard libraries (e.g. Java, Python, Go) seem to do better than their competitors.