
Clojure Style Guide - jgrodziski
https://github.com/bbatsov/clojure-style-guide
======
danneu

        ;; 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))))

~~~
mullr
(when (seq s) ...) reads to me as "do this as long as I can treat s
sequentially". The following operations on s require it to be seqable, so it's
like a runtime type check. not-empty is less direct, and feels like it's
assuming that s is seqable.

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.

~~~
mkremins
This interpretation is error-prone. (seq 1), for instance, throws an
IllegalArgumentException at runtime. Meanwhile, (seq nil) returns a falsey
value even though in many cases it's possible to transparently pass nil in
place of a collection of any kind.

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...](https://github.com/clojure/core.incubator/blob/master/src/main/clojure/clojure/core/incubator.clj#L83)

------
dj-wonk
I agree that this is a pretty good style guide, in the sense that it captures
a large portion of what Clojure programmers consider to be good style.

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?

~~~
TheMiller
I believe that this convention is borrowed from Common Lisp. I always thought
of it more as a way to highlight importance. Three semicolons for block
comments outside of top-level constructs, which usually explain the purpose or
usage of the following expression (usually a function definition). Two for
comments inline with function body code. And one for trailing comments on a
line, where space is limited and the comment is least important to understand
code structure.

The conventions are even mentioned in the Common Lisp specifications:
[http://www.lispworks.com/documentation/HyperSpec/Body/02_ddb...](http://www.lispworks.com/documentation/HyperSpec/Body/02_ddb.htm)

~~~
lispm
The use of one or more semicolons is older than Common Lisp. Maclisp had it in
the 1970s, but earlier with different semantics - it had semantics for
formatting code. Then it was changed a bit with the use of Emacs.

------
thom
The thing I most scratch my head about in my Clojure code is when to optimise
function arguments for each of thread-first/thread-last/partial etc. Some
patterns are fairly established, like predicate first, coll last, but I'd be
intrigued to hear some more rules of thumb.

------
film42
I'm a bit confused about the _require refer all_ vs _use_. Can someone explain
why _use_ is bad in that context (or in general)?

Link: [https://github.com/bbatsov/clojure-style-guide#prefer-
requir...](https://github.com/bbatsov/clojure-style-guide#prefer-require-over-
use)

UPDATE:

Looks like there's a GH issue thread on the subject:
[https://github.com/bbatsov/clojure-style-
guide/issues/16](https://github.com/bbatsov/clojure-style-guide/issues/16)

~~~
mkremins
Both :use and :require :refer :all slurp symbols into your namespace
unqualified. This behavior can cause confusion when someone reading your code
tries to figure out which symbols are defined where. Most of the time, more
explicit alternatives are preferred:

    
    
      (: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...](https://groups.google.com/forum/#!msg/clojurescript/SzYK08Oduxo/BfFiia0wOO4J)

~~~
film42
I totally agree about requiring :as or :refer to specific functions, but it
still seems like the clojure team prefers naked `use` over `require refer
all`, so should the style guide be changed to allow naked `use` in some
circumstances?

I guess a popular example is `(:use clojure.test)`

~~~
mkremins
Makes sense to me, although I suppose there's probably an argument to be made
in favor of the uniformity that comes with using :require for everything.

(:use clojure.test) is probably a worthy exception – 90% of the time I see
:use in the wild, it's in exactly that context :)

------
csdrane
Seems to me like Clojure is experience a popularity surge on HN lately. I
wonder what's driving this.

Maybe my perception is just biased because I'm currently learning Clojure.

~~~
mateuszf
That's strange, because I also noticed that, and I'm also starting to learn
Clojure.

~~~
fariasvp
Same here

~~~
eruditely
I have also been convinced to start learning clojure. Also on the hn posting
thread, a company called fracture had a relatively interesting job
application, and if the kind of people who write clojure write tongue in cheek
shit like then I want to start learning.

------
islon
`Prefer .. to -> when chaining method calls in Java interop.`

That works if there's only Java calls in your chain. I, for one, prefer to use
the more generic threading macros.

------
dandrews
Much as I loathe self-proclaimed "best practice", I find this style guide
agreeable. I'll quibble with the author's superfluous use of comp/partial as a
documentation aid, and the picayune advice to use single-sentence-spacing in
comments deserves an eyeroll. But for the most part this is all good stuff,
and is worthy of consideration. Pay attention, n00bs.

