Clojure Style Guide
github.com
github.com
;; good
(defn print-seq [s]
(when (seq s)
(prn (first s))
(recur (rest s))))
;; bad
(defn print-seq [s]
(when-not (empty? s)
(prn (first s))
(recur (rest s))))
Why use `seq` instead of `not-empty`? (defn print-seq [s]
(when (not-empty s)
(prn (first s))
(recur (rest s))))Of course, not-empty is implemented with (when (seq)), so there's no REAL difference. At the end of the day, (when (seq)) is what people use.
Essentially, seq already assumes that its argument is seqable. Don't use it to test an argument of unknown type for seqability; prefer something like the seqable? function from core.incubator [1], or a different core function like coll? or sequential? where the semantics of one of these will do.
[1] https://github.com/clojure/core.incubator/blob/master/src/ma...
if lst:
# do something with lst
is preferred to if len(lst) > 0:
# do something with lst
in Python. It becomes more obvious when you use descriptive names: if customers:
# do something with customers if X ==> if there exists some X if x is not None:
In Python, [] (empty list) and {} (empty dict) are == False but are not None. They exist, and their types are List and Dict rather than NoneType, but they are "falsey" because they are empty. (not-empty coll)
is the same as (when (seq coll) coll)A few words about semicolons for comments. Lots of Clojure code uses ; and ;; and ;;; to indicate levels of comment nesting. I get that multiple semicolons are intended to indicate hierarchy / sections / nesting. Some editors use it for auto-indentation. (However, I don't think editors really need multiple semicolons to do a good job of indentation; mine does fine without.)
Personally, I find one semicolon to be enough to indicate a comment at any level. Context tells the rest. So I am not on-board with multiple semicolons. One, it looks ugly to me. Two, using more than one seems unnecessary -- and unnecessary things are good to avoid unless they add value.
Who else agrees? Is there something I'm missing?
The conventions are even mentioned in the Common Lisp specifications: http://www.lispworks.com/documentation/HyperSpec/Body/02_ddb...
[1] https://github.com/gdeer81/marginalia [2] http://gdeer81.github.io/marginalia/
Link: https://github.com/bbatsov/clojure-style-guide#prefer-requir...
UPDATE:
Looks like there's a GH issue thread on the subject: https://github.com/bbatsov/clojure-style-guide/issues/16
(:require [foo :as f])
gives the required namespace a short alias with which symbols defined in that namespace can be qualified, while (:require [foo :refer [bar baz quux]])
explicitly provides a set of symbols to import unqualified.Generally speaking, :require :refer :all is also considered non-idiomatic. In fact, ClojureScript has explicitly avoided supporting both :require :refer :all and naked :use [1]. Backwards compatibility seems to be the only reason either is still supported by Clojure on the JVM.
[1] https://groups.google.com/forum/#!msg/clojurescript/SzYK08Od...
I guess a popular example is `(:use clojure.test)`
(:use clojure.test) is probably a worthy exception – 90% of the time I see :use in the wild, it's in exactly that context :)
Maybe my perception is just biased because I'm currently learning Clojure.
In the last four month-long periods, beginning with April 9 to May 9 and ending with July 9 to August 9, the number of “Clojure” stories were [36, 41, 32, 41]. So the 41 stories of the most recent month is more than the previous month, but the same as the month before that.
That works if there's only Java calls in your chain. I, for one, prefer to use the more generic threading macros.