Upload
savio77
View
224
Download
0
Embed Size (px)
7/30/2019 Github Com Bbatsov Clojure Style Guide Readme
1/32
Sign up Sign in
Files Commits Branches
bbatsov / clojure-style-guidePUBLIC
CodeCode NetworkNetwork Pull RequestsPull Requests IssuesIssues GraphsGraphs 11 1313
Read-Only access
A community coding style guide for the Clojure programming language Read more
ZIP SSHSSH Git Read-OnlyGit Read-Only
https://github.com/bbatsov/clojure-style-guide.git
Tags master 1
133 commits
latest commit cc0f61724c
Add an opening quo te
bbatsov authored 12 days ago
CONTRIBUTING.md 5 months ago Added contribution guidelines. [bbatsov]
README.md 12 days ago Add an opening quote [bbatsov]
README.mdREADME.md
Role models are important .
clojure-style-guide /
The Clojure Style Guide
HTTP
4 4 9 32
Search or type a comm andThis repo sitory
PDFmyURL.com
https://github.com/bbatsov/clojure-style-guide#the-clojure-style-guidehttps://github.com/bbatsov/clojure-style-guide#the-clojure-style-guidehttps://github.com/bbatsov/clojure-style-guide#the-clojure-style-guidehttps://github.com/bbatsov/clojure-style-guide#the-clojure-style-guidehttps://github.com/bbatsov/clojure-style-guide#the-clojure-style-guidehttps://github.com/bbatsov/clojure-style-guide#the-clojure-style-guidehttps://github.com/bbatsov/clojure-style-guide#the-clojure-style-guidehttps://github.com/bbatsov/clojure-style-guide#the-clojure-style-guidehttps://github.com/bbatsov/clojure-style-guide/blob/master/CONTRIBUTING.mdhttps://github.com/bbatsov/clojure-style-guide/commit/c32629374b7de9d54f4dbe190874aef4a7ab4d97https://github.com/bbatsovhttps://github.com/bbatsov/clojure-style-guide/pulsehttps://github.com/bbatsov/clojure-style-guide/pulsehttps://github.com/bbatsov/clojure-style-guidehttps://github.com/bbatsov/clojure-style-guide/networkhttps://github.com/bbatsov/clojure-style-guide/pullshttps://github.com/bbatsov/clojure-style-guide/issueshttps://github.com/bbatsov/clojure-style-guide/graphshttps://github.com/bbatsov/clojure-style-guide/graphshttps://github.com/bbatsov/clojure-style-guide/graphshttps://github.com/https://github.com/https://github.com/https://github.com/https://github.com/bbatsov/clojure-style-guidehttps://github.com/bbatsov/clojure-style-guidehttps://github.com/bbatsov/clojure-style-guide/blob/master/CONTRIBUTING.mdhttp://pdfmyurl.com/?otsrc=watermark&otclc=0.01http://pdfmyurl.com/?otsrc=watermark&otclc=0.01https://github.com/bbatsov/clojure-style-guide#the-clojure-style-guidehttps://github.com/bbatsovhttps://github.com/bbatsov/clojure-style-guide/commit/cc0f61724c1c6d25f8b000b3f23a3a870d129933https://github.com/bbatsov/clojure-style-guide/blob/master/README.mdhttps://github.com/bbatsovhttps://github.com/bbatsov/clojure-style-guide/commit/c32629374b7de9d54f4dbe190874aef4a7ab4d97https://github.com/bbatsov/clojure-style-guide/blob/master/CONTRIBUTING.mdhttps://github.com/bbatsovhttps://github.com/bbatsov/clojure-style-guide/commit/cc0f61724c1c6d25f8b000b3f23a3a870d129933https://github.com/bbatsov/clojure-style-guide/commit/cc0f61724c1c6d25f8b000b3f23a3a870d129933https://github.com/bbatsov/clojure-style-guidehttps://github.com/bbatsov/clojure-style-guide/commits/masterhttps://github.com/bbatsov/clojure-style-guide/brancheshttps://github.com/bbatsov/clojure-style-guide/commits/masterhttps://github.com/bbatsov/clojure-style-guidehttps://github.com/bbatsov/clojure-style-guide/tagshttp://git//github.com/bbatsov/clojure-style-guide.githttps://github.com/bbatsov/[email protected]:bbatsov/clojure-style-guide.githttps://github.com/bbatsov/clojure-style-guide.githttps://github.com/bbatsov/clojure-style-guide/archive/master.ziphttps://github.com/bbatsov/clojure-style-guide#readmehttps://github.com/bbatsov/clojure-style-guide/graphshttps://github.com/bbatsov/clojure-style-guide/issueshttps://github.com/bbatsov/clojure-style-guide/pullshttps://github.com/bbatsov/clojure-style-guide/networkhttps://github.com/bbatsov/clojure-style-guidehttps://github.com/bbatsov/clojure-style-guide/pulsehttps://github.com/bbatsov/clojure-style-guidehttps://github.com/bbatsovhttps://github.com/bbatsov/clojure-style-guide/networkhttps://github.com/login?return_to=%2Fbbatsov%2Fclojure-style-guidehttps://github.com/bbatsov/clojure-style-guide/stargazershttps://github.com/login?return_to=%2Fbbatsov%2Fclojure-style-guidehttps://github.com/search/advancedhttps://github.com/bloghttp://enterprise.github.com/https://github.com/featureshttps://github.com/explorehttps://github.com/login?return_to=%2Fbbatsov%2Fclojure-style-guidehttps://github.com/signuphttps://github.com/7/30/2019 Github Com Bbatsov Clojure Style Guide Readme
2/32
-- Officer Alex J. Murphy / RoboCop
This Clojure style guide recommends best practices so that real-world Clojure programmers can write code t hat can be
maintained by ot her real-world Clojure programmers. A style guide that reflect s real-world usage get s used, and a style
guide t hat holds to an ideal that has been rejected by t he people it is supposed t o help risks not get t ing used at a ll no
matt er how good it is.
The guide is separated into several sections of related rules. I've tried t o add t he rationale behind t he rules (if it's omitt ed
I've assumed that is pret t y obvious).
I didn't come up with all t he rules out of nowhere - t hey are mostly based on my extensive career as a prof essional
sof tware engineer, feedback and suggestions f rom members of the Clojure community, and various highly regarded
Clojure programming resources, such as "Clojure Programming" and "The Joy of Clojure".
The guide is still a work in progress - some sections are missing, others are incomplete, some rules are lacking examples,
some rules don't have examples t hat illustrat e t hem clearly enough. In due t ime these issues will be addressed - just keepthem in mind for now.
You can generate a PDF or an HTML copy of this guide using Transmuter.
Source Code Layout & OrganizationSyntax
Naming
Collections
Mutation
Strings
Exceptions
Table of Contents
PDFmyURL.com
http://pdfmyurl.com/?otsrc=watermark&otclc=0.01http://pdfmyurl.com/?otsrc=watermark&otclc=0.01https://github.com/bbatsov/clojure-style-guide#exceptionshttps://github.com/bbatsov/clojure-style-guide#stringshttps://github.com/bbatsov/clojure-style-guide#mutationhttps://github.com/bbatsov/clojure-style-guide#collectionshttps://github.com/bbatsov/clojure-style-guide#naminghttps://github.com/bbatsov/clojure-style-guide#syntaxhttps://github.com/bbatsov/clojure-style-guide#source-code-layout--organizationhttps://github.com/bbatsov/clojure-style-guide#table-of-contentshttps://github.com/TechnoGate/transmuterhttp://joyofclojure.com/http://www.clojurebook.com/7/30/2019 Github Com Bbatsov Clojure Style Guide Readme
3/32
Macros
Comments
Comment Annot at ions
Existential
Tooling
Nearly everybody is convinced t hat every st yle but their own is ugly and unreadable. Leave out t he "but their own" and
they're probably right...
-- Jerry Cof f in (on indentat ion)
Use t wo spaces per indentat ion level. No hard t abs.
;; good
(when something
(something-else))
;; bad - four spaces
(when something
(something-else))
Align vert ically f unct ion argument s.
;; good
(filter even?
(range 110))
;; bad
(filter even?
(range 110))
Source Code Layout & Organization
PDFmyURL.com
http://pdfmyurl.com/?otsrc=watermark&otclc=0.01http://pdfmyurl.com/?otsrc=watermark&otclc=0.01https://github.com/bbatsov/clojure-style-guide#source-code-layout--organizationhttps://github.com/bbatsov/clojure-style-guide#toolinghttps://github.com/bbatsov/clojure-style-guide#existentialhttps://github.com/bbatsov/clojure-style-guide#comment-annotationshttps://github.com/bbatsov/clojure-style-guide#commentshttps://github.com/bbatsov/clojure-style-guide#macros7/30/2019 Github Com Bbatsov Clojure Style Guide Readme
4/32
Align let bindings and map keywords.
;; good
(let [thing1"some stuff"
thing2"other stuff"]
{:thing1thing1
:thing2thing2})
;; bad
(let [thing1"some stuff"
thing2"other stuff"]
{:thing1thing1
:thing2thing2})
Opt ionally omit t he new line bet ween the f unction name and argument vector fo r defn when there is no docst ring.
;; good(defn foo
[x]
(barx))
;; good
(defn foo [x]
(barx))
;; bad
(defn foo[x] (barx))
Opt ionally omit t he new line bet ween the argument vect or and a short f unct ion body.
;; good
(defn foo [x]
(barx))
PDFmyURL.com
http://pdfmyurl.com/?otsrc=watermark&otclc=0.01http://pdfmyurl.com/?otsrc=watermark&otclc=0.017/30/2019 Github Com Bbatsov Clojure Style Guide Readme
5/32
;; good for a small function body
(defn foo [x] (barx))
;; good for multi-arity functions
(defn foo
([x] (barx))
([xy]
(if (predicate?x)
(barx)
(bazx))))
;; bad
(defn foo
[x] (if (predicate?x)
(barx)
(bazx)))
Indent each line of multi-line docstrings.
;; good
(defn foo
"Hello there. This is
a multi-line docstring."
[]
(bar))
;; bad
(defn foo
"Hello there. This is
a multi-line docstring."
[]
(bar))
Use Unix-style line endings. (*BSD/Solaris/Linux/OSX users are covered by default, Windows users have to be extra
PDFmyURL.com
http://pdfmyurl.com/?otsrc=watermark&otclc=0.01http://pdfmyurl.com/?otsrc=watermark&otclc=0.017/30/2019 Github Com Bbatsov Clojure Style Guide Readme
6/32
careful.)
If you're using Git you might want t o add t he following configurat ion sett ing t o protect your project f rom Windows
line endings creeping in:
$ git config --global core.autocrlf true
If any text precedes an opening bracket( ( , { and [ ) or f ollows a closing bracket ( ) , } and ] ), separate that
text from t hat bracket with a space. Conversely, leave no space af ter an opening bracket and before fo llowing text ,
or after preceding text and before a closing bracket.
;; good
(foo (barbaz) quux)
;; bad
(foo(barbaz)quux)
(foo ( barbaz ) quux)
Don't use commas bet ween the elements of sequential collection literals.
;; good
[123]
(123)
;; bad
[1, 2, 3]
(1, 2, 3)
Consider enhancing the readability of map literals via judicious use of commas and line breaks.
;; good
{:name"Bruce Wayne":alter-ego"Batman"}
PDFmyURL.com
http://pdfmyurl.com/?otsrc=watermark&otclc=0.01http://pdfmyurl.com/?otsrc=watermark&otclc=0.017/30/2019 Github Com Bbatsov Clojure Style Guide Readme
7/32
;; good and arguably a bit more readable
{:name"Bruce Wayne"
:alter-ego"Batman"}
;; good and arguably more compact
{:name"Bruce Wayne", :alter-ego"Batman"}
Place all trailing parentheses on a single line.
;; good
(when something
(something-else))
;; bad
(when something
(something-else)
)
Use empt y lines between t op-level forms.
;; good
(def x...)
(defn foo...)
;; bad
(def x...)
(defn foo...)
An except ion to t he rule is the grouping of relat ed def s t ogether.
;; good
(def min-rows10)
(def max-rows20)
(def min-cols15)
PDFmyURL.com
http://pdfmyurl.com/?otsrc=watermark&otclc=0.01http://pdfmyurl.com/?otsrc=watermark&otclc=0.017/30/2019 Github Com Bbatsov Clojure Style Guide Readme
8/32
(def max-cols30)
Do not place blank lines in the middle of a f unct ion or macro def inition. An except ion can be made to indicate grouping
of pairwise constructs as found in e.g. let and cond .
Where feasible, avoid making lines longer than 80 characters.
Avoid t railing whitespace.
Use one f ile per namespace .
Start every namespace with a comprehensive ns f orm, comprised of import s, require s, refer s and use s.
(ns examples.ns
(:refer-clojure:exclude [next replace remove])
(:require (clojure [string:asstring]
[set :asset])
[clojure.java.shell:assh])
(:use (clojurezipxml))
(:importjava.util.Date
java.text.SimpleDateFormat
(java.util.concurrentExecutors
LinkedBlockingQueue)))
Avoid single-segment namespaces.
;; good(ns example.ns)
;; bad
(ns example)
Avoid the use o f overly long namespaces(i.e. with more than 5 segments).
PDFmyURL.com
http://pdfmyurl.com/?otsrc=watermark&otclc=0.01http://pdfmyurl.com/?otsrc=watermark&otclc=0.017/30/2019 Github Com Bbatsov Clojure Style Guide Readme
9/32
Avoid funct ions longer than 10 LOC (lines of code). Ideally, most funct ions will be short er t han 5 LOC.
Avoid parameter list s with more than three or four posit ional parameters.
Avoid the use o f namespace- manipulat ing funct ions like require and refer . They are entirely unnecessary outside
of a REPL environment.
Use declare to enable forward references.
Prefer higher-order functions like map t o loop/recur .
Prefer f unction pre and post conditions to checks inside a f unction's body.
;; good(defn foo [x]
{:pre [(pos? x)]}
(barx))
;; bad
(defn foo [x]
(if (pos? x)
(barx)
(throw (IllegalArgumentException"x must be a positive number!")))
Don't def ine vars inside f unct ions.
;; very bad
(defn foo []
(def x5)
...)
Syntax
PDFmyURL.com
http://pdfmyurl.com/?otsrc=watermark&otclc=0.01http://pdfmyurl.com/?otsrc=watermark&otclc=0.01https://github.com/bbatsov/clojure-style-guide#syntax7/30/2019 Github Com Bbatsov Clojure Style Guide Readme
10/32
Don't shadow clojure.core names with local bindings.
;; bad - you're forced to used clojure.core/map fully qualified inside
(defn foo [map]
...)
Use seq as a t erminat ing condition to t est whether a sequence is empt y (this technique is sometimes called nil
punning).
;; 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))))
Use when instead of (if ... (do ...) .
;; good
(when pred
(foo)
(bar))
;; bad
(if pred
(do
(foo)
(bar)))
PDFmyURL.com
http://pdfmyurl.com/?otsrc=watermark&otclc=0.01http://pdfmyurl.com/?otsrc=watermark&otclc=0.017/30/2019 Github Com Bbatsov Clojure Style Guide Readme
11/32
Use if-let instead of let + if .
;; good
(if-let [result (foox)]
(something-withresult)
(something-else))
;; bad
(let [result (foox)]
(if result
(something-withresult)
(something-else)))
Use when-let instead of let + when .
;; good
(when-let [result (foox)]
(do-something-withresult)(do-something-more-withresult))
;; bad
(let [result (foox)]
(when result
(do-something-withresult)
(do-something-more-withresult)))
Use if-not instead of (if (not ...) ...) .
;; good
(if-not (pred)
(foo))
;; bad
(if (not pred)
(foo))
PDFmyURL.com
http://pdfmyurl.com/?otsrc=watermark&otclc=0.01http://pdfmyurl.com/?otsrc=watermark&otclc=0.017/30/2019 Github Com Bbatsov Clojure Style Guide Readme
12/32
Use when-not instead of (when (not ...) ...) .
;; good
(when-not pred
(foo)
(bar))
;; bad
(when (not pred)
(foo)
(bar))
Use when-not instead of (if-not ... (do ...) .
;; good
(when-not pred
(foo)(bar))
;; bad
(if-not pred
(do
(foo)
(bar)))
Use not= instead of (not (= ...)) .
;; good
(not= foobar)
;; bad
(not (= foobar))
Prefer % over %1 in function literals with only one parameter.
PDFmyURL.com
http://pdfmyurl.com/?otsrc=watermark&otclc=0.01http://pdfmyurl.com/?otsrc=watermark&otclc=0.017/30/2019 Github Com Bbatsov Clojure Style Guide Readme
13/32
;; good
#(Math/round%)
;; bad
#(Math/round%1)
Prefer %1 over % in function literals with more t han one parameter.
;; good
#(Math/pow%1%2)
;; bad
#(Math/pow%%2)
Don't wrap funct ions in anonymous funct ions when you don't need t o.
;; good
(filter even? (range 110))
;; bad
(filter #(even?%) (range 110))
Don't use function literals if the f unct ion body will consist of more t han one f orm.
;; good
(fn [x]
(println x)
(* x2))
;; bad (you need an explicit do form)
#(do (println %)
(* %2))
PDFmyURL.com
http://pdfmyurl.com/?otsrc=watermark&otclc=0.01http://pdfmyurl.com/?otsrc=watermark&otclc=0.017/30/2019 Github Com Bbatsov Clojure Style Guide Readme
14/32
Favor the use of complement versus the use of an anonymous f unct ion.
;; good
(filter (complement some-pred?) coll)
;; bad
(filter #(not (some-pred?%)) coll)
This rule should obviously be ignored if t he complementing predicate exists in the f orm of a separat e f unct ion (e.g.
even? and odd? ).
Leverage comp when it would yield simpler code.
;; Assuming `(:require [clojure.string :as str])`...
;; good
(map #(str/capitalize (str/trim%)) ["top "" test "])
;; better
(map (comp str/capitalizestr/trim) ["top "" test "])
Leverage partial when it would yield simpler code.
;; good
(map #(+ 5%) (range 110))
;; (arguably) better(map (partial + 5) (range 110))
Prefer the use of the threading macros -> (thread-first) and ->> (thread-last) to heavy form nesting.
;; good
(-> [123]
reverse
PDFmyURL.com
http://pdfmyurl.com/?otsrc=watermark&otclc=0.01http://pdfmyurl.com/?otsrc=watermark&otclc=0.017/30/2019 Github Com Bbatsov Clojure Style Guide Readme
15/32
(conj 4)
prn)
;; not as good
(prn (conj (reverse [123])
4))
;; good
(->>(range 110)(filter even?)
(map (partial * 2)))
;; not as good
(map (partial * 2)
(filter even? (range 110)))
Prefer .. t o -> when chaining method calls in Java interop.
;; good
(-> (System/getProperties) (.get"os.name"))
;; better
(.. SystemgetProperties (get "os.name"))
Use :else as the catch-all test expression in cond and condp .
;; good
(cond(< n0) "negative"
(> n0) "positive"
:else"zero"))
;; bad
(cond
(< n0) "negative"
PDFmyURL.com
http://pdfmyurl.com/?otsrc=watermark&otclc=0.01http://pdfmyurl.com/?otsrc=watermark&otclc=0.017/30/2019 Github Com Bbatsov Clojure Style Guide Readme
16/32
(> n0) "positive"
true"zero"))
Prefer condp instead of cond when the predicate & expression don't change.
;; good
(cond
(= x10) :ten(= x20) :twenty
(= x30) :forty
:else:dunno)
;; much better
(condp= x
10:ten
20:twenty
30:forty
:dunno)
Prefer case instead of cond or condp when test expressions are compile-t ime constants.
;; good
(cond
(= x10) :ten
(= x20) :twenty
(= x30) :forty
:else:dunno)
;; better
(condp= x
10:ten
20:twenty
30:forty
:dunno)
PDFmyURL.com
http://pdfmyurl.com/?otsrc=watermark&otclc=0.01http://pdfmyurl.com/?otsrc=watermark&otclc=0.017/30/2019 Github Com Bbatsov Clojure Style Guide Readme
17/32
;; best
(casex
10:ten
20:twenty
30:forty
:dunno)
Use short f orms in cond and related. If not possible give visual hints f or t he pairwise grouping with comments o r
empt y lines.
;; good
(cond
(test1) (action1)
(test2) (action2)
:else (default-action))
;; ok-ish
(cond;; test case 1
(test1)
(long-function-name-which-requires-a-new-line
(complicated-sub-form
(-> 'which-spans
multiple-lines)))
(test2)
(another-very-long-function-name
(yet-another-sub-form(-> 'which-spans
multiple-lines)))
:else
(the-fall-through-default-case
(which-also-spans'multiple
'lines)))
PDFmyURL.com
http://pdfmyurl.com/?otsrc=watermark&otclc=0.01http://pdfmyurl.com/?otsrc=watermark&otclc=0.017/30/2019 Github Com Bbatsov Clojure Style Guide Readme
18/32
Use a set as a predicate when appropriat e.
;; good
(remove #{0} [012345])
;; bad
(remove #(= %0) [012345])
;; good
(count (filter #{\a\e\i\o\u} "mary had a little lamb"))
;; bad
(count (filter #(or (= %\a)
(= %\e)
(= %\i)
(= %\o)
(= %\u))
"mary had a little lamb"))
Use (inc x) & (dec x) instead of (+ x 1) and (- x 1) .
Use (pos? x) , (neg? x) & (zero? x) instead of (> x 0) , (< x 0) & (= x 0) .
Use the sugared Java interop f orms.
;;; object creation
;; good
(java.util.ArrayList.100)
;; bad
(new java.util.ArrayList100)
;;; static method invocation
;; good
(Math/pow210)
PDFmyURL.com
http://pdfmyurl.com/?otsrc=watermark&otclc=0.01http://pdfmyurl.com/?otsrc=watermark&otclc=0.017/30/2019 Github Com Bbatsov Clojure Style Guide Readme
19/32
;; bad
(. Mathpow210)
;;; instance method invocation
;; good
(.substring"hello"13)
;; bad(. "hello"substring13)
;;; static field access
;; good
Integer/MAX_VALUE
;; bad
(. IntegerMAX_VALUE)
;;; instance field access;; good
(.someFieldsome-object)
;; bad
(. some-objectsome-field)
Use the compact metadata notation for metadata that contains only slots whose keys are keywords and whose value
is boolean true .
;; good
(def ^:privatea5)
;; bad
(def ^{:privatetrue} a5)
Denote private parts of your code.
PDFmyURL.com
http://pdfmyurl.com/?otsrc=watermark&otclc=0.01http://pdfmyurl.com/?otsrc=watermark&otclc=0.017/30/2019 Github Com Bbatsov Clojure Style Guide Readme
20/32
;; good
(defn- private-fun [] ...)
(def ^:privateprivate-var...)
;; bad
(defn private-fun [] ...) ; not private at all
(defn ^:privateprivate-fun [] ...) ; overly verbose
(def private-var...) ; not private at all
Be careful regarding what exactly do you at tach met adata to.
;; we attach the metadata to the var referenced by `a`
(def ^:privatea {})
(meta a) ;=> nil
(meta #'a) ;=> {:private true}
;; we attach the metadata to the empty hash-map value
(def a^:private {})
(meta a) ;=> {:private true}
(meta #'a) ;=> nil
The only real difficulties in programming are cache invalidation and naming things.
-- Phil Karlton
When naming namespaces favor t he fo llowing t wo schemas:
project.module
Naming
PDFmyURL.com
http://pdfmyurl.com/?otsrc=watermark&otclc=0.01http://pdfmyurl.com/?otsrc=watermark&otclc=0.01https://github.com/bbatsov/clojure-style-guide#naming7/30/2019 Github Com Bbatsov Clojure Style Guide Readme
21/32
organization.project.module
Use lisp-case in composite namespace segments(e.g. bruce.project-euler )
Use lisp-case fo r function and variable names.
;; good
(def some-var...)
(defn some-fun...)
;; bad
(def someVar...)
(defn somefun...)
(def some_fun...)
Use CamelCase for protocols, records, structs, and types. (Keep acronyms like HTTP, RFC, XML uppercase.)
The names o f predicate met hods (methods that return a boolean value) should end in a quest ion mark. (i.e. even? ).
;; good
(defn palindrome?...)
;; bad
(defn palindrome-p...) ; Common Lisp style
(defn is-palindrome...) ; Java style
The names o f functions/macros that are not saf e in STM transactions should end with an exclamat ion mark. (i.e.
reset! )
Use -> instead of to in the names of conversion functions.
;; good
(defn f->c...)
;; not so good
PDFmyURL.com
http://pdfmyurl.com/?otsrc=watermark&otclc=0.01http://pdfmyurl.com/?otsrc=watermark&otclc=0.017/30/2019 Github Com Bbatsov Clojure Style Guide Readme
22/32
(defn f-to-c...)
Use *earmuffs* for things intended for rebinding (ie. are dynamic).
;; good
(def ^:dynamic*a*10)
;; bad
(def ^:dynamica10)
Don't use a special not at ion for constant s; everything is assumed a constant unless specified ot herwise.
Use _ fo r dest ructuring t argets and fo rmal arguments names whose value will be ignored by the code at hand.
;; good
(let [[ab_c] [1234]]
(println abc))
(dotimes [_3]
(println "Hello!"))
;; bad
(let [[abcd] [1234]]
(println abd))
(dotimes [i3]
(println "Hello!"))
Follow clojure.core 's example f or idiomatic names like pred and coll .
in functions:
f , g , h - function input
n - integer input usually a size
index - integer index
PDFmyURL.com
http://pdfmyurl.com/?otsrc=watermark&otclc=0.01http://pdfmyurl.com/?otsrc=watermark&otclc=0.017/30/2019 Github Com Bbatsov Clojure Style Guide Readme
23/32
x , y - numbers
s - string input
coll - a collection
pred - a predicat e closure
& more - va riadic input
in macros:
expr - an expression
body - a macro body
binding - a macro binding vect or
It is better to have 100 functions operate on one data structure than to have 10 functions operate on 10 data
structures.
-- Alan J. Perlis
Avoid the use o f lists f or generic da ta st orage (unless a list is exact ly what you need).
Prefer t he use of keywords for hash keys.
;; good
{:name"Bruce":age30}
;; bad
{"name""Bruce""age"30}
Prefer t he use of the lit eral collect ion syntax where applicable. However, when def ining set s, only use lit eral syntax
when the values are compile-time constants.
Collections
PDFmyURL.com
http://pdfmyurl.com/?otsrc=watermark&otclc=0.01http://pdfmyurl.com/?otsrc=watermark&otclc=0.01https://github.com/bbatsov/clojure-style-guide#collections7/30/2019 Github Com Bbatsov Clojure Style Guide Readme
24/32
;; good
[123]
#{123}
(hash-set (func1) (func2)) ; values determined at runtime
;; bad
(vector 123)
(hash-set 123)
#{(func1) (func2)} ; will throw runtime exception if (func1) = (func2)
Avoid accessing collec t ion members by index whenever possible.
Prefer t he use of keywords as f unct ions f or retrieving values from maps, where app licable.
(def m {:name"Bruce":age30})
;; good
(:namem)
;; more verbose than necessary
(get m:name)
;; bad - susceptible to NullPointerException
(m:name)
Leverage t he fact that most collections are functions of their elements.
;; good(filter #{\a\e\o\i\u} "this is a test")
;; bad - too ugly to share
Leverage the fact that keywords can be used as functions of a collection.
((juxt:a:b) {:a"ala":b"bala"})
PDFmyURL.com
http://pdfmyurl.com/?otsrc=watermark&otclc=0.01http://pdfmyurl.com/?otsrc=watermark&otclc=0.017/30/2019 Github Com Bbatsov Clojure Style Guide Readme
25/32
Avoid the use o f t ransient collect ions, excep t for performance-crit ical po rt ions of the code.
Avoid the use o f Java collect ions.
Avoid the use o f Java arrays, excep t for interop scenarios and performance-crit ical code dealing heav ily with primit ive
types.
Consider wrapping a ll I/O calls with t he io! macro t o avoid nast y surprises if you accidentally end up calling such
code in a transact ion.
Avoid the use o f ref-set whenever possible.
(def r (ref 0))
;; good
(dosync (alter r+ 5))
;; bad
(dosync (ref-set r5))
Try to keep the size of t ransactions (the amount of work encapsulat ed in them) as small as possible.
Avoid having bot h short - and long- running t ransact ions interac t ing with the same Ref .
Mutation
Refs
AgentsPDFmyURL.com
http://pdfmyurl.com/?otsrc=watermark&otclc=0.01http://pdfmyurl.com/?otsrc=watermark&otclc=0.01https://github.com/bbatsov/clojure-style-guide#agentshttps://github.com/bbatsov/clojure-style-guide#refshttps://github.com/bbatsov/clojure-style-guide#mutation7/30/2019 Github Com Bbatsov Clojure Style Guide Readme
26/32
Use send only f or act ions t hat a re CPU bound and don't block on I/O or other t hreads.
Use send-off f or actions that might block, sleep, or otherwise tie up the thread.
Avoid at om updates inside STM transact ions.
Try to use swap! rather than reset! , where possible.
(def a (atom0))
;; good
(swap!a+ 5)
;; not as good
(reset!a5)
Prefer st ring manipulation functions f rom clojure.string over Java interop or rolling your own.
;; good
(clojure.string/upper-case"bruce")
;; bad
(.toUpperCase"bruce")
Atoms
Strings
ExceptionsPDFmyURL.com
http://pdfmyurl.com/?otsrc=watermark&otclc=0.01http://pdfmyurl.com/?otsrc=watermark&otclc=0.01https://github.com/bbatsov/clojure-style-guide#exceptionshttps://github.com/bbatsov/clojure-style-guide#stringshttps://github.com/bbatsov/clojure-style-guide#atoms7/30/2019 Github Com Bbatsov Clojure Style Guide Readme
27/32
Reuse existing except ion types. Idiomatic Clojure code, when it does t hrow an exception, throws an exception of a
standard type (e.g. java.lang.IllegalArgumentException , java.lang.UnsupportedOperationException ,
java.lang.IllegalStateException , java.io.IOException ).
Favor with-open over finally .
Don't write a macro if a f unct ion will do.
Create an example of a macro usage first and the macro afterwards.
Break complicat ed macros into smaller f unct ions whenever possible.
A macro should usually just provide synt act ic sugar and t he core of the macro should be a plain funct ion. Doing so will
improve composabilit y.
Prefer syntax-quot ed f orms over building lists manually.
Good code is its own best documentat ion. As you're about t o add a comment , ask yourself, "How can I improve the
code so t hat t his comment isn't needed?" Improve the code and then document it t o make it even clearer.
-- Steve McConnell
Endeavor to make your code as se lf-documenting as possible.
Write heading comments with at least f our semicolons.
Write t op-level comments with t hree semicolons.
Write comments on a particular fragment of code bef ore that f ragment and aligned with it , using two semicolons.
Macros
Comments
PDFmyURL.com
http://pdfmyurl.com/?otsrc=watermark&otclc=0.01http://pdfmyurl.com/?otsrc=watermark&otclc=0.01https://github.com/bbatsov/clojure-style-guide#commentshttps://github.com/bbatsov/clojure-style-guide#macros7/30/2019 Github Com Bbatsov Clojure Style Guide Readme
28/32
Write margin comments with one semicolon.
Always have at leas t one space bet ween the semicolon and t he t ext that follows it .
;;;; Frob Grovel
;;; This section of code has some important implications:
;;; 1. Foo.;;; 2. Bar.
;;; 3. Baz.
(defn fnord [zarquon]
;; If zob, then veeblefitz.
(quuxzot
mumble ; Zibblefrotz.
frotz))
Comments longer than a word begin with a capita l let ter and use punctuat ion. Separate sentences with one space.
Avoid superf luous comment s.
;; bad
(inc counter) ; increments counter by one
Keep existing comments up-t o-dat e. An outda ted comment is worse than no comment at all.
Prefer t he use of the #_ reader macro over a regular comment when you need t o comment out a particular form.
;; good
(+ foo#_(barx) delta)
;; bad
(+ foo
;; (bar x)
PDFmyURL.com
http://pdfmyurl.com/?otsrc=watermark&otclc=0.01http://pdfmyurl.com/?otsrc=watermark&otclc=0.01http://en.wikipedia.org/wiki/Sentence_spacing7/30/2019 Github Com Bbatsov Clojure Style Guide Readme
29/32
delta)
Good code is like a good joke - it needs no explanation.
-- Russ Olsen
Avoid writ ing comment s t o explain bad code. Ref act or t he code to make it self -explanat ory. ("Do, or do not . There is
no t ry." --Yoda)
Annot at ions should usually be writt en on t he line immediat ely above t he relevant code.
The annota t ion keyword is followed by a colon and a space, then a note describing the problem.
If mult iple lines are required to describe the problem, subsequent lines should be indented as much as t he f irst one.
Tag the annot at ion with your init ials and a da te so its relevance can be easily verified.
(defn some-fun
[]
;; FIXME: This has crashed occasionally since v1.2.3. It may
;; be related to the BarBazUtil upgrade. (xz 13-1-31)
(baz))
In cases where t he problem is so obvious that any documentat ion would be redundant, annot at ions may be lef t at the
end of the off ending line with no note . This usage should be the except ion and not t he rule.
(defn bar
[]
(sleep100)) ; OPTIMIZE
Use TODO to note missing feat ures or functionality that should be added at a later dat e.
Use FIXME to note broken code that needs to be f ixed.
Comment Annotations
PDFmyURL.com
http://pdfmyurl.com/?otsrc=watermark&otclc=0.01http://pdfmyurl.com/?otsrc=watermark&otclc=0.01https://github.com/bbatsov/clojure-style-guide#comment-annotations7/30/2019 Github Com Bbatsov Clojure Style Guide Readme
30/32
Use OPTIMIZE to note slow or inefficient code that may cause performance problems.
Use HACK t o note "code smells" where questionable coding pract ices were used and should be ref act ored away.
Use REVIEW t o note anything that should be looked at to confirm it is working as intended. For example:
REVIEW: Are we sure this is how the client does X currently?
Use ot her custom annotat ion keywords if it f eels appropriate, but be sure to document them in your project 's README
or similar.
Code in a f unct ional way, avoiding mut at ion when that makes sense.
Be consistent. In an ideal world, be consistent with these guidelines.
Use common sense.
There are some tools created by t he Clojure community t hat m ight aid you in your endeavor to write idiomat ic Clojure
code.
Slamhound is a tool that will automat ically generat e proper ns declarations from your exist ing code.
kibit is a static code analyzer for Clojure which uses core.logic to search for patterns of code for which there might
exist a more idiomat ic function or macro.
Existential
Tooling
PDFmyURL.com
http://pdfmyurl.com/?otsrc=watermark&otclc=0.01http://pdfmyurl.com/?otsrc=watermark&otclc=0.01https://github.com/bbatsov/clojure-style-guide#contributinghttps://github.com/clojure/core.logichttps://github.com/jonase/kibithttps://github.com/technomancy/slamhoundhttps://github.com/bbatsov/clojure-style-guide#toolinghttps://github.com/bbatsov/clojure-style-guide#existential7/30/2019 Github Com Bbatsov Clojure Style Guide Readme
31/32
Nothing writ t en in this guide is set in stone. It 's my desire t o work toget her with everyone inte rested in Clojure coding st yle,
so t hat we could ultimately creat e a resource t hat will be benef icial to the entire Clojure community.
Feel free t o open t icket s or send pull requests with improvements. Thanks in advance for your help!
This work is licensed under a Creative Commons Att ribution 3.0 Unported License
A communit y-d riven st yle guide is of litt le use t o a community t hat doesn't know about its existence. Tweet about the
guide, share it with your friends and colleagues. Every comment , suggestion or opinion we get makes the guide just a litt le
bit bet te r. And we want t o have the best possible guide, don't we?
Cheers,
Bozhidar
Contributing
License
Spread the Word
PDFmyURL.com
http://pdfmyurl.com/?otsrc=watermark&otclc=0.01http://pdfmyurl.com/?otsrc=watermark&otclc=0.01https://twitter.com/bbatsovhttps://github.com/bbatsov/clojure-style-guide#spread-the-wordhttp://creativecommons.org/licenses/by/3.0/deed.en_UShttps://a248.e.akamai.net/camo.github.com/ea7febd364f01e7b3f46f6fb86712fe05925bfbf/687474703a2f2f692e6372656174697665636f6d6d6f6e732e6f72672f6c2f62792f332e302f38387833312e706e67https://github.com/bbatsov/clojure-style-guide#license7/30/2019 Github Com Bbatsov Clojure Style Guide Readme
32/32
GitHubGitHub
Abou t usAbout us
BlogBlog
Contact & supportContact & support
GitHub EnterpriseGitHub Enterprise
Site statusSite status
ApplicationsApplications
GitHub for MacGitHub for Mac
GitHub for WindowsGitHub for Windows
GitHub for EclipseGitHub for Eclipse
GitHub mobile appsGitHub mobile apps
ServicesServices
Gauges: Web analyticsGauges: Web analytics
Speaker Deck: PresentationsSpeaker Deck: Presentations
Gist: Code snippetsGist: Code snippets
Job boardJob board
DocumentationDocumentation
GitHub HelpGitHub Help
Developer APIDeveloper API
GitHub Flavored MarkdownGitHub Flavored Markdown
GitHub PagesGitHub Pages
MoreMore
TrainingTraining
Students & teachersStudents & teachers
The ShopThe Shop
Plans & pricingPlans & pricing
The OctodexThe Octodex
20 13 20 13
GitHubGitHub
, Inc. All rights reserved., Inc. All rights reserved.
Terms of ServiceTerms of Service
PrivacyPrivacy
SecuritySecurity
http://pdfmyurl.com/?otsrc=watermark&otclc=0.01http://pdfmyurl.com/?otsrc=watermark&otclc=0.01https://github.com/securityhttps://github.com/site/privacyhttps://github.com/site/termshttp://octodex.github.com/https://github.com/planshttp://shop.github.com/https://github.com/eduhttp://training.github.com/http://pages.github.com/http://github.github.com/github-flavored-markdown/http://developer.github.com/http://help.github.com/http://jobs.github.com/https://gist.github.com/http://speakerdeck.com/http://get.gaug.es/http://mobile.github.com/http://eclipse.github.com/http://windows.github.com/http://mac.github.com/http://status.github.com/http://enterprise.github.com/https://github.com/contacthttps://github.com/bloghttps://github.com/about