@@ -960,6 +960,19 @@ acronyms like HTTP, RFC, XML uppercase.)
960960NOTE: `CapitalCase` is also known as `UpperCamelCase`, `CapitalWords`
961961and `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
965978The 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
981994The 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.
30333088Use `TODO` to note missing features or functionality that should be
30343089added 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
30383100Use `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
30423111Use `OPTIMIZE` to note slow or inefficient code that may cause
30433112performance 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
30473124Use `HACK` to note "code smells" where questionable coding practices
30483125were 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
30523136Use `REVIEW` to note anything that should be looked at to confirm it
30533137is working as intended. For example: `REVIEW: Are we sure this is how the
30543138client 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
30583151Use other custom annotation keywords if it feels appropriate, but be
0 commit comments