Skip to content

Commit 07bc1c9

Browse files
authored
Merge pull request #271 from bbatsov/add-remaining-section-examples
Add examples and rationale to Exceptions, Naming, and Annotations
2 parents a4fdbac + 8ce2352 commit 07bc1c9

File tree

1 file changed

+95
-2
lines changed

1 file changed

+95
-2
lines changed

README.adoc

Lines changed: 95 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -960,6 +960,19 @@ acronyms like HTTP, RFC, XML uppercase.)
960960
NOTE: `CapitalCase` is also known as `UpperCamelCase`, `CapitalWords`
961961
and `PascalCase`.
962962

963+
[source,clojure]
964+
----
965+
;; good
966+
(defprotocol Serializable ...)
967+
(defrecord HttpRequest ...)
968+
(deftype XMLParser ...)
969+
970+
;; bad
971+
(defprotocol serializable ...)
972+
(defrecord http-request ...)
973+
(deftype xml_parser ...)
974+
----
975+
963976
=== Predicate Methods [[naming-predicates]]
964977

965978
The names of predicate methods (methods that return a boolean value)
@@ -979,7 +992,20 @@ should end in a question mark
979992
=== Unsafe Functions [[naming-unsafe-functions]]
980993

981994
The names of functions/macros that are not safe in STM transactions
982-
should end with an exclamation mark (e.g. `reset!`).
995+
should end with an exclamation mark (e.g. `reset!`). The `!` signals
996+
to callers that the function has side-effects and should not be called
997+
inside a `dosync` block.
998+
999+
[source,clojure]
1000+
----
1001+
;; good
1002+
(defn save-user! [user]
1003+
(db/insert! user))
1004+
1005+
;; bad - side-effecting function without the ! warning
1006+
(defn save-user [user]
1007+
(db/insert! user))
1008+
----
9831009

9841010
=== Conversion Functions [[naming-conversion-functions]]
9851011

@@ -2409,9 +2435,38 @@ throw an exception -- throws an exception of a standard type
24092435
`java.lang.UnsupportedOperationException`,
24102436
`java.lang.IllegalStateException`, `java.io.IOException`).
24112437

2438+
[source,clojure]
2439+
----
2440+
;; good - use ex-info for data-carrying exceptions
2441+
(throw (ex-info "Invalid input" {:value x :reason :negative}))
2442+
2443+
;; good - use standard Java exception types
2444+
(throw (IllegalArgumentException. "x must be positive"))
2445+
2446+
;; bad - defining a custom exception type for no reason
2447+
(deftype MyCustomException [msg]
2448+
...)
2449+
----
2450+
24122451
=== Prefer `with-open` Over `finally` [[prefer-with-open-over-finally]]
24132452

2414-
Favor `with-open` over `finally`.
2453+
Favor `with-open` over `finally`. `with-open` guarantees that the
2454+
resource is closed even if an exception is thrown, with less
2455+
boilerplate and no risk of forgetting the cleanup step.
2456+
2457+
[source,clojure]
2458+
----
2459+
;; good
2460+
(with-open [rdr (clojure.java.io/reader "file.txt")]
2461+
(slurp rdr))
2462+
2463+
;; bad - verbose and easy to get wrong
2464+
(let [rdr (clojure.java.io/reader "file.txt")]
2465+
(try
2466+
(slurp rdr)
2467+
(finally
2468+
(.close rdr))))
2469+
----
24152470

24162471
=== Catching Throwables [[catching-throwables]]
24172472

@@ -3033,26 +3088,64 @@ with no note. This usage should be the exception and not the rule.
30333088
Use `TODO` to note missing features or functionality that should be
30343089
added at a later date.
30353090

3091+
[source,clojure]
3092+
----
3093+
(defn process-order [order]
3094+
;; TODO: Add support for discount codes.
3095+
(calculate-total order))
3096+
----
3097+
30363098
==== `FIXME` [[fixme]]
30373099

30383100
Use `FIXME` to note broken code that needs to be fixed.
30393101

3102+
[source,clojure]
3103+
----
3104+
(defn calculate-total [order]
3105+
;; FIXME: This doesn't account for tax in all regions.
3106+
(reduce + (map :price (:items order))))
3107+
----
3108+
30403109
==== `OPTIMIZE` [[optimize]]
30413110

30423111
Use `OPTIMIZE` to note slow or inefficient code that may cause
30433112
performance problems.
30443113

3114+
[source,clojure]
3115+
----
3116+
(defn find-duplicates [coll]
3117+
;; OPTIMIZE: O(n^2) — consider using a set for large collections.
3118+
(for [x coll y coll :when (and (not (identical? x y)) (= x y))]
3119+
x))
3120+
----
3121+
30453122
==== `HACK` [[hack]]
30463123

30473124
Use `HACK` to note "code smells" where questionable coding practices
30483125
were used and should be refactored away.
30493126

3127+
[source,clojure]
3128+
----
3129+
(defn user-name [request]
3130+
;; HACK: Parsing the token manually until we add proper auth middleware.
3131+
(-> request :headers (get "authorization") (subs 7) decode-token :name))
3132+
----
3133+
30503134
==== `REVIEW` [[review]]
30513135

30523136
Use `REVIEW` to note anything that should be looked at to confirm it
30533137
is working as intended. For example: `REVIEW: Are we sure this is how the
30543138
client does X currently?`
30553139

3140+
[source,clojure]
3141+
----
3142+
(defn retry [f n]
3143+
;; REVIEW: Should we add exponential backoff here?
3144+
(loop [i n]
3145+
(or (try (f) (catch Exception _ nil))
3146+
(when (pos? i) (recur (dec i))))))
3147+
----
3148+
30563149
==== Document Custom Annotations [[document-annotations]]
30573150

30583151
Use other custom annotation keywords if it feels appropriate, but be

0 commit comments

Comments
 (0)