1

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.

2 Answers 2

2

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))))
Sign up to request clarification or add additional context in comments.

2 Comments

This is great. Three new facts to file: ctrl+click to see syntax definitions, look for the question mark in the error message, and for what follows clojure.core. When you said "It should be a vector," I knew exactly what I had done wrong. Thank you for taking the time to help me. Now I have to pass it forward.
The ? is part of the clojure spec syntax and from the spec documentation, "? - 0 or 1 of a predicate/pattern"
1

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:

enter image description here

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!

1 Comment

This is great too! Thank you. And I like your formatting idea. Clojure is so DENSE it's hard to read. Expanding the params like that makes it a little bit easier.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.