Skip to content

Commit 34e8280

Browse files
committed
Merge pull request bbatsov#15 from ghoseb/master
Add a bunch of tips and some cleanups
2 parents c70e82f + 823004a commit 34e8280

File tree

1 file changed

+104
-23
lines changed

1 file changed

+104
-23
lines changed

README.md

Lines changed: 104 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -64,12 +64,12 @@ You can generate a PDF or an HTML copy of this guide using
6464
;; good
6565
(filter even?
6666
(range 1 10))
67-
67+
6868
;; bad
6969
(filter even?
70-
(range 1 10))
70+
(range 1 10))
7171
```
72-
72+
7373
* Align let bindings and map keywords.
7474

7575
```Clojure
@@ -78,7 +78,7 @@ You can generate a PDF or an HTML copy of this guide using
7878
thing2 "other stuff"]
7979
{:thing1 thing1
8080
:thing2 thing2})
81-
81+
8282
;; bad
8383
(let [thing1 "some stuff"
8484
thing2 "other stuff"]
@@ -121,10 +121,10 @@ You can generate a PDF or an HTML copy of this guide using
121121
```Clojure
122122
;; bad
123123
{:name "Bruce Wayne", :alter-ego "Batman"}
124-
124+
125125
;; good
126126
{:name "Bruce Wayne" :alter-ego "Batman"}
127-
127+
128128
;; good and arguably a bit more readable
129129
{:name "Bruce Wayne"
130130
:alter-ego "Batman"}
@@ -147,7 +147,7 @@ You can generate a PDF or an HTML copy of this guide using
147147

148148
```Clojure
149149
(def x ...)
150-
150+
151151
(def y ...)
152152
```
153153

@@ -164,7 +164,7 @@ You can generate a PDF or an HTML copy of this guide using
164164
[set :as set])
165165
[clojure.java.shell :as sh])
166166
(:use (clojure zip xml))
167-
(:import java.util.Date
167+
(:import java.util.Date
168168
java.text.SimpleDateFormat
169169
(java.util.concurrent Executors
170170
LinkedBlockingQueue)))
@@ -189,12 +189,12 @@ You can generate a PDF or an HTML copy of this guide using
189189
(prn (first s))
190190
(recur (rest s))))
191191

192-
;; bad
192+
;; bad
193193
(defn print-seq [s]
194194
(when-not (empty? s)
195195
(prn (first s))
196196
(recur (rest s))))
197-
```
197+
```
198198

199199
* Use `when` instead of `(if ... (do ...)`.
200200

@@ -203,7 +203,7 @@ You can generate a PDF or an HTML copy of this guide using
203203
(when pred
204204
(foo)
205205
(bar))
206-
206+
207207
;; bad
208208
(if pred
209209
(do
@@ -224,7 +224,7 @@ You can generate a PDF or an HTML copy of this guide using
224224
(if result
225225
(do-something-with result)
226226
(do-something-else)))
227-
```
227+
```
228228

229229
* Use `when-let` instead of `let` + `when`.
230230

@@ -239,15 +239,15 @@ You can generate a PDF or an HTML copy of this guide using
239239
(when result
240240
(do-something-with result)
241241
(do-something-else-with result)))
242-
```
242+
```
243243

244244
* Use `if-not` instead of `(if (not ...) ...)`.
245245

246246
```Clojure
247247
;; good
248248
(if-not (pred)
249249
(foo))
250-
250+
251251
;; bad
252252
(if (not pred)
253253
(foo))
@@ -260,7 +260,7 @@ You can generate a PDF or an HTML copy of this guide using
260260
(when-not pred
261261
(foo)
262262
(bar))
263-
263+
264264
;; bad
265265
(when (not pred)
266266
(foo)
@@ -272,24 +272,24 @@ You can generate a PDF or an HTML copy of this guide using
272272
```Clojure
273273
;; good
274274
(filter even? (range 1 10))
275-
275+
276276
;; bad
277277
(filter #(even? %) (range 1 10))
278278
```
279279

280-
* Favor the use of `complement` versus the use of an anonymous function.
280+
* Favor the use of `complement` versus the use of an anonymous function.
281281

282282
```Clojure
283283
;; good
284284
(filter (complement some-pred?) coll)
285-
285+
286286
;; bad
287287
(filter #(not (some-pred? %)) coll)
288288
```
289289

290290
This rule should obviously be ignored if the complementing predicate
291291
exists in the form of a separate function (e.g. `even?` and `odd?`).
292-
292+
293293
* Leverage `comp` when it would yield simpler code.
294294

295295
```Clojure
@@ -299,17 +299,95 @@ You can generate a PDF or an HTML copy of this guide using
299299
;; better
300300
(map (comp capitalize trim) ["top " " test "])
301301
```
302-
302+
303303
* Leverage `partial` when it would yield simpler code.
304304

305305
```Clojure
306306
;; good
307307
(map #(+ 5 %) (range 1 10))
308-
308+
309309
;; (arguably) better
310310
(map (partial + 5) (range 1 10))
311311
```
312312

313+
* Prefer `..` to `->` when chaining method calls in Java interop.
314+
315+
```Clojure
316+
;; good
317+
(-> (System/getProperties) (.get "os.name"))
318+
319+
;; better
320+
(.. System getProperties (get "os.name"))
321+
```
322+
323+
* Prefer `condp` instead of `cond` when the predicate & expression don't
324+
change.
325+
326+
```Clojure
327+
;; good
328+
(cond
329+
(= x 10) :ten
330+
(= x 20) :twenty
331+
(= x 30) :forty
332+
:else :dunno)
333+
334+
;; much better
335+
(condp = x
336+
10 :ten
337+
20 :twenty
338+
30 :forty
339+
:dunno)
340+
```
341+
342+
* Prefer `case` instead of `cond` or `condp` when test expressions are
343+
compile time constants.
344+
345+
```Clojure
346+
;; good
347+
(cond
348+
(= x 10) :ten
349+
(= x 20) :twenty
350+
(= x 30) :forty
351+
:else :dunno)
352+
353+
;; better
354+
(condp = x
355+
10 :ten
356+
20 :twenty
357+
30 :forty
358+
:dunno)
359+
360+
;; best
361+
(case x
362+
10 :ten
363+
20 :twenty
364+
30 :forty
365+
:dunno)
366+
```
367+
368+
* Use a `set` as a predicate when appropriate.
369+
370+
```Clojure
371+
;; bad
372+
(remove #(= % 0) [0 1 2 3 4 5])
373+
374+
;; good
375+
(remove #{0} [0 1 2 3 4 5])
376+
377+
;; bad
378+
(count (filter #(or (= % \a)
379+
(= % \e)
380+
(= % \i)
381+
(= % \o)
382+
(= % \u))
383+
"mary had a little lamb"))
384+
385+
;; good
386+
(count (filter #{\a \e \i \o \u} "mary had a little lamb"))
387+
```
388+
389+
* Use `(inc x)` & `(dec x)` instead of `(+ x 1)` and `(- x 1)`.
390+
313391
## Naming
314392

315393
> The only real difficulties in programming are cache invalidation and
@@ -324,7 +402,7 @@ You can generate a PDF or an HTML copy of this guide using
324402
(i.e. `even?`).
325403
* The names of functions/macros that are not safe in STM transactions
326404
should end with an exclamation mark. (i.e. `reset!`)
327-
* Use `*earmuffs*` for things intended for rebinding.
405+
* Use `*earmuffs*` for things intended for rebinding (ie. are dynamic).
328406
* Don't use a special notation for constants; everything is assumed a constant
329407
unless specified otherwise.
330408
* Use `_` for destructuring targets and formal arguments names whose
@@ -349,6 +427,9 @@ You can generate a PDF or an HTML copy of this guide using
349427
* Don't write a macro if a function will do.
350428
* Create an example of a macro usage first and the macro afterwards.
351429
* Break complicated macros into smaller functions whenever possible.
430+
* A macro should usually just provide syntactic sugar and the core of
431+
the macro should be a plain function. Doing so will improve
432+
composability.
352433
* Prefer syntax quoted forms over building lists manually.
353434

354435
## Comments
@@ -394,7 +475,7 @@ at all.
394475
;; be related to the BarBazUtil upgrade.
395476
(baz))
396477
```
397-
478+
398479
* In cases where the problem is so obvious that any documentation would
399480
be redundant, annotations may be left at the end of the offending line
400481
with no note. This usage should be the exception and not the rule.

0 commit comments

Comments
 (0)