> For example, the error messages in Elm are just insanely better than in any other language I know. Like, it's not even in the same ballpark. Why doesn't every language have this?
It's a combination of economics (who pays for the work? It could be people scratching an itch, but these people also have to have the privilege of being able to pay their bills somehow), difficulty (it's not a trivial problem space, you need to turn your compiler into one that understands not only its own language but also every potential language people try, and the errors might crop up in unexpected places where the context you need to provide good errors is long gone, so you must change the compiler to a bowl of spaghetti design, so you can access, for example, the type checker during parsing) and inertia (developers are used to building tools for themselves, so they dont spend time on diagnostics because they are already familiar with the inner workings od the tool, then other developers use those tools and because every other tool is like that they don't expect good errors, so no one considers them important enough, and the cycle goes on and on).
But let me be clear on one thing: although there are many things in your language design and compiler implementation that you can do to make things easier on yourself (don't throw anything away related to the causal relationship for why a certain constraint is present!), the work is mostly elbow grease, and spit and polish, little more.