That said, clojure remains my favorite language despite this flaw, and I can't wait to spend more time in it. It's beautifully designed. The design communicates well how to use it well, and it's only when you're abusing the language (or making mistakes) that you run into this kind of stuff. Not an excuse really, I'm just excited that errors are going to get somewhat taken care of by incorporating spec into the core.
Not really. My experience has been that most of the time the docstrings leave a lot of guesswork to be done when deciding what to pass to a function and how to pass it through, which causes errors and time lost because there's no other authority on a functions I/O (Common Lisp has a spec, for example). This behaviour has spread to the community too. So in Clojure one passes "things" around and Clojure will do "stuff" to those "things" until either one or both the "stuff" or the "things" break, in which case you either get nothing or somethings that's big but worth nothing. TBH it's been quite some time since I tried to do sth. w/ Clojure so my impressions could be outdated, but the article suggests otherwise.
But its not. And if you take the time, like 30 days, to learn Clojure to intermediate proficiency levels, these issues disapear.
Its hard for me to convince you of this, because its definitly asking for a leap of faith. But think of it like starting Kick Boxing. At first, your knuckles hurt, your chin hurts, but spend 30 days at it, and you just adapt and those pain points disapear. All of a sudden, you feel great, stronger, faster, more agile. That was my experience with Clojure. And ya, just like Kick Boxing, once in a while, your knuckle might hurt again, or your chin, but unlike in the beginning, its very rare, and goes away really quickly.
EDIT: To add more concrete weight to my argument. Here's some of the things I believe contributes to making those issues disapear. The consistency and simplicity of the syntax. Most docstrings call the same things with the same names, and have a similar writing style. The REPL driven development means you can quickly explore and self learn how a function behaves. The immutable data structures avoid a lot of mistakes and simplify a lot of logic. The higher level loops and branching do a similar thing. The easy composability of data transforms become second nature. The functional first style makes writing tests easy. You always end up with little code, so there's just less that can go wrong. And I think most importantly, the Clojure source is easy to read and very accessible, so its often a better documentation then any docstring could be.
I find that the more I live in the REPL, the less frequent these errors are.
The author points out a stray "@" symbol in his code throwing a confusing message about Futures. Well futures are a pretty first class language feature, so that would be pretty easy for figure out. Their complaint should be more about the sugary syntax of derefing using "@" than the bad error message.
Clojure could use better stack traces, but I don't think throwing out a otherwise very elegant language is merited.
WRT keyword, I think that's a bug, not a nuance. This is the doc:
> Returns a Keyword with the given namespace and name. Do not use : in the keyword strings, it will be added automatically.
Nowhere does it say it returns sth. else than a keyword. Following is the doc for "intern" from Emacs Lisp, which does a similar job and signals "wrong-type-argument" with improper input:
---
intern is a built-in function in ‘C source code’.
(intern STRING &optional OBARRAY)
Return the canonical symbol whose name is STRING. If there is none, one is created by this function and returned. A second optional argument specifies the obarray to use; it defaults to the value of ‘obarray’.
---
So it does what it says or fails otherwise. This sort of error handling and streamlined, nice debugging is the best part of interactive programming; otherwise it's just Java with a lot of parentheses.
Handling non-standard arguments in intuitive ways can be useful indeed, but not so if they are accidental, possibly working due only to implementation details, and undocumented.