It's unfortunately part of the learning curve.
Being a beginner with clojure myself, I was put off by some of the more arcane error messages.<p>But compared to 'undefined is not a function' it's about 10 times better ;)
Glad to see this being improved.<p>Don't get discouraged by this. Even if you never plan to use Clojure in a project, dive in and take a good long gulp from the functional tea of enlightenment. It will make you a better programmer.<p>My advice for people complaining about docs:
<a href="http://clojuredocs.org/" rel="nofollow">http://clojuredocs.org/</a>
is much much nicer.<p>The standard docs are very very terse and you'll need to learn the typical abbreviations and idioms.
Clojure is just so coupled with the host language. Which isn't a bad thing, since it helps make interop effortless, but does make it difficult to appreciate as a standalone language.<p>I first tried to learn Clojure before I knew anything about Java and things like error messages made it really difficult to get started.<p>Coming back after having written Java professionally for a year, things like random Java exceptions showing up or long stack traces suddenly became a lot more tractable, although still not "beautiful".
Alex Miller wrote a few days ago on this very topic: <a href="https://clojureverse.org/t/improving-error-messages-in-clojure-as-a-library/1765/27" rel="nofollow">https://clojureverse.org/t/improving-error-messages-in-cloju...</a>
That implementation for "keyword" is simply horrible. If it's correct that most errors caused by bad input to functions come not from verification but from an arbitrary place in code where a type-specific operation is applied is correct, that's more horrible. This deeply discourages me from touching Clojure ever.
The overall conclusion is correct, most error messages happen by accident, but a lot the examples look like expected behavior to me. Maybe because Ive been using Clojure for too long, or maybe because its the expected trade-off when using a dynamically typed language. You get more fluidity at the cost of type checks - The way to mitigate this downside is adding checks of your own. Clojure has supported this since way back when using pre/post conditions.<p>Example:<p><pre><code> core> (defn mydiv [n d] {:pre [(pos? d)]} (/ n d))
#'mydiv
core> (mydiv 10 2)
5
core> (mydiv 10 0)
AssertionError Assert failed: (pos? d) core/mydiv
</code></pre>
As opposed to the standard<p><pre><code> core> (/ 10 0)
ArithmeticException Divide by zero
clojure.lang.Numbers.divide (Numbers.java:158)
</code></pre>
Chasing down Numbers.java will take time, but with a pre-condition you get the exact name of the function and the test which failed.
> The worst sin of stack traces is that the most important information is printed first, then followed by less and less important information, usually a few screenfuls of it.<p>No. It’s at the top of the web browser window. At the top of the unit test out window in the IDE and so on. Flipping stack traces to help console reading would be a mistake. Should be made optional in that case.
> But if the official spec doesn’t restrict get, Spec will let people redefine the spec for get for themselves.<p>> They can choose whatever subset of the type they want.<p>Total clojure-spec noob question: is this type scoped somehow, or does using your own type mean chasing down bugs in libraries that assume a looser version?
Yeah Clojure's error messages pushed me to Common Lisp (although I am still quite a neophyte in both).<p>I haven't tried it, but maybe Sayid[0] would be of help to Clojurians?<p>[0]: <a href="http://bpiel.github.io/sayid/" rel="nofollow">http://bpiel.github.io/sayid/</a>
> It is more useful to think of error messages as non-existent than to think of them as bad.<p>If this is true, my respect for Clojure just completely dropped.<p>Error messages are a crucial part of a language and they are instrumental to the robustness of the programs it helps create.<p>The fact they have been so severely neglected by the Clojure teams makes me think the authors of the language don't really understand modern large scale programming.
Very good talk by Bozhidar Batzov at PartialConf 2017 that covers this point as well.<p>Clojure, The Bad Parts<p><a href="https://www.youtube.com/watch?v=1YCkOo5Y4Oo" rel="nofollow">https://www.youtube.com/watch?v=1YCkOo5Y4Oo</a>
I think most of the reason for not having all these runtime checks in core is performance.<p>Though I guess if there was an easy way to turn them off for production it would maybe be okay.