4 ms·
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
by gkya 8y ago
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.
- jonstaab 8y agoI think that impulse is correct. As a clojure-lover, the state of error handling, and particularly Rich Hickey's decision to neglect it for so long and not code defensively, makes me a little sick. 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.
- gkya 8y ago> it's only when you're abusing the language (or making mistakes) that you run into this kind of stuff. 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.
- didibus 8y agoYes, its true the docstrings are terse. And its true that Clojure follows a pattern of garbage in, garbage out. And if the rest of Clojure was designed like Java or Python, it would be a huge problem. 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.
- james-mcelwain 8y agoAs someone who has (mostly) struggled through, I'd (mostly) agree. I find that when I am running into errors it is almost always because (a). I am moving too quickly and have misplaced something simple like my parens (which parinfer would probably solve) or (b). am not leaning enough on the REPL and am spending too much time before re-evaluating code. I find that the more I live in the REPL, the less frequent these errors are.
- gleenn 8y agoI think if you're in the staticly typed camp then Clojure isn't for you either way. While the keyword thing is reasonably bad, it's not the type of error I almost ever make (I'm definitely far from a perfect coder). I think your reaction is a little strong though, for a good reason. I think Clojure has many of these little nuances where strange parameters result in non exceptions, but I'm often surprised how useful they can be, and I think some are quite intentional. For instance, the map and merge functions can take nil collections as params and they have pretty useful properties. Usually if you see some weird stack trace it's typically easier than the author suggests to deduce type problems. 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.
- gkya 8y agoI don't use staticaly typed languages (nowadays I'm trying Dart though, for Flutter). My main languages are Elisp, Perl, Python and Ruby. And some Posix shell. I'm a fan of Lisp. 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.