Reputation: 577
I'm learning Clojure. I wrote a first-attempt at calculating a Fibonacci number. Here's my code and the subsequent error message. I have NO CLUE what to correct. My question is: WHAT is the error message trying to say?
(defn fibon
(fn [n]
(loop [loops n acc 1N acc2 0N]
(if (<= loops 0)
acc ;; Return the summed F number.
(recur (dec loops) (+ acc acc2) acc)))))
Syntax error macroexpanding clojure.core/defn at (form-init1248982153229513778.clj:1:1). fn - failed: vector? at: [:fn-tail :arity-n :bodies :params] spec: :clojure.core.specs.alpha/param-list (fn [n] (loop [loops n acc 1N acc2 0N] (if (<= loops 0) acc (recur (dec loops) (+ acc acc2) acc)))) failed: vector? at: [:fn-tail :arity-1 :params] spec: :clojure.core.specs.alpha/param-list
In general, could someone please point me to some documentation on Clojure in Cursive so I can decipher these error messages myself, if there is such a beast. Thank you.
Upvotes: 1
Views: 625
Reputation: 7044
The error message you see is a clojure.spec error. It is telling you that your code violates the specification of defn
.
The error message is cryptic but if you unpack the error message you can see that the param-list
clojure.spec failed because (fn [n] (loop ...
is not a vector?
This is trying to tell you that defn
expected to see a vector
after fibon
, not (fn [n] (loop ...
It is not the most intuitive error message.
There is the clojure spec guide but it is targeted to developers of specifications.
There are other clojure projects that provide more intuitive spec error messages. I've used expound at the command line and it provides much nicer error messages, however I don't think you can use expound with cursive, but that might be worth exploring.
When I saw your code, I first looked at what the definiation of the defn
macro is by doing a ctrl-mouse-over on the defn
, or you can look at the online defn documentation. That information along with the spec error let me understand how to interpret the error message.
As for your code, when using defn you don't use (fn
. So your code should look like:
(defn fibon [n]
(loop [loops n acc 1N acc2 0N]
(if (<= loops 0)
acc ;; Return the summed F number.
(recur (dec loops) (+ acc acc2) acc))))
Upvotes: 2
Reputation: 29958
The above answer is good. One suggestion to a question you didn't ask: you may wish to adjust your IDEA settings so it only indents 2 spaces each line, instead of 8 spaces (1 tab char?).
If necessary, uncheck the box "Use tab character". Here is a screenshot:
Then it will look like this:
(defn fibon
[n]
(loop [loops n
acc 1N
acc2 0N]
(if (<= loops 0)
acc ;; Return the summed F number.
(recur (dec loops) (+ acc acc2) acc))))
For the loop
statement, I like to keep each loop variable and its initial value on a separate line. In this way it looks similar to the Clojure let
expression.
Enjoy!
Upvotes: 1