2

In the function bellow, I used cond in the place of case. It took me a long time to single out this function. I am learning clojure, so the error was not obvious to me. When I tried to run the code up to the map function (using the cursive/Intellij debugger), Intellij complained: There is no executable code at core.clj:144. If the clojure compiler knows that, is there an option to get a warning at compiler time? Are there other checks that the compiler (or a lint) can do in my code?

(defn uri-gen [uri fields line]
  (let [remo "[//\\:*?()<>|.%'\"&]"]
    (cond (count fields)
      0 (correct-uri ...)
      1 (let ...)
      (correct-empty
        uri
        (apply str
          (map (fn [it] ...)))))))
dilvan
  • 2,109
  • 2
  • 20
  • 32

2 Answers2

1

Unfortunately, compiler warnings & error messages in Clojure are often terse, nonsensical, or just plain missing.

I'm not sure if it would help in this instance, but you might try the eastwood Clojure lint tool (see others in the Clojure Toolbox). I also make extensive use of Plumatic Schema which has helped me to avoid many simple type errors.

Alan Thompson
  • 29,276
  • 6
  • 41
  • 48
0

It's not really the compiler's problem.

From the compiler's point of view, what you wrote makes perfect sense. You've got an s-expression composed of an s-expression followed by more s-expressions - what's the problem? A Lisp, such as Clojure, has darned little "syntax" for the compiler to "know" about. It does not, for example, have to worry about silly things like operator precedence and "if" and "while" and "until" statements and all the tons of other things that compilers for other languages dither over. It has no knowledge of what cond and case and and and whatever do - it just knows that, because they're the first value in an unquoted form, they must be a function; the compiler can in some sense "find" that function, so it can create the code to call the function; and there's a bunch of other valid expressions following it that need to be passed to the function. (And of course those other expressions may consist of more s-expressions, representing more functions to be called, and down the Lisp-hole we go!). KEWL! It's the function which has to make some sort of sense of the arguments it's passed and do whatever it is that the function is supposed to do. The compiler doesn't know anything about all that - in a very very oversimplified sense, it just reads s-expressions and generates code to call functions.

If you insist on passing case-ish arguments to cond, the compiler doesn't care. It will merrily do what you asked. The fact that cond will (probably) barf all over those arguments is not something for the compiler to deal with - it's the programmer's problem. Lisp/Clojure puts the responsibility for getting it right squarely on the shoulders of the programmer, where it belongs.

Lisp's are a kind of like a super-power for programmer's. In the right hands it's a valuable tool in the service of mankind. In the wrong hands, it's a recipe for disaster. Try not to be Tighten - use your powers wisely. :-)

  • The point of my question is that the compiler DOES know, in this case, that something went wrong. Intellij does inform that there is no executable code for some lines. The compiler decided not to generate code for these source lines. It seems logical to me that it should be possible to get a warning for such thing. – dilvan May 07 '18 at 22:49