@@ -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
@@ -2236,9 +2262,38 @@ throw an exception -- throws an exception of a standard type
22362262`java.lang.UnsupportedOperationException`,
22372263`java.lang.IllegalStateException`, `java.io.IOException`).
22382264
2265+ [source,clojure]
2266+ ----
2267+ ;; good - use ex-info for data-carrying exceptions
2268+ (throw (ex-info "Invalid input" {:value x :reason :negative}))
2269+
2270+ ;; good - use standard Java exception types
2271+ (throw (IllegalArgumentException. "x must be positive"))
2272+
2273+ ;; bad - defining a custom exception type for no reason
2274+ (deftype MyCustomException [msg]
2275+ ...)
2276+ ----
2277+
22392278=== Prefer `with-open` Over `finally` [[prefer-with-open-over-finally]]
22402279
2241- Favor `with-open` over `finally`.
2280+ Favor `with-open` over `finally`. `with-open` guarantees that the
2281+ resource is closed even if an exception is thrown, with less
2282+ boilerplate and no risk of forgetting the cleanup step.
2283+
2284+ [source,clojure]
2285+ ----
2286+ ;; good
2287+ (with-open [rdr (clojure.java.io/reader "file.txt")]
2288+ (slurp rdr))
2289+
2290+ ;; bad - verbose and easy to get wrong
2291+ (let [rdr (clojure.java.io/reader "file.txt")]
2292+ (try
2293+ (slurp rdr)
2294+ (finally
2295+ (.close rdr))))
2296+ ----
22422297
22432298=== Catching Throwables [[catching-throwables]]
22442299
@@ -2753,26 +2808,64 @@ with no note. This usage should be the exception and not the rule.
27532808Use `TODO` to note missing features or functionality that should be
27542809added at a later date.
27552810
2811+ [source,clojure]
2812+ ----
2813+ (defn process-order [order]
2814+ ;; TODO: Add support for discount codes.
2815+ (calculate-total order))
2816+ ----
2817+
27562818==== `FIXME` [[fixme]]
27572819
27582820Use `FIXME` to note broken code that needs to be fixed.
27592821
2822+ [source,clojure]
2823+ ----
2824+ (defn calculate-total [order]
2825+ ;; FIXME: This doesn't account for tax in all regions.
2826+ (reduce + (map :price (:items order))))
2827+ ----
2828+
27602829==== `OPTIMIZE` [[optimize]]
27612830
27622831Use `OPTIMIZE` to note slow or inefficient code that may cause
27632832performance problems.
27642833
2834+ [source,clojure]
2835+ ----
2836+ (defn find-duplicates [coll]
2837+ ;; OPTIMIZE: O(n^2) — consider using a set for large collections.
2838+ (for [x coll y coll :when (and (not (identical? x y)) (= x y))]
2839+ x))
2840+ ----
2841+
27652842==== `HACK` [[hack]]
27662843
27672844Use `HACK` to note "code smells" where questionable coding practices
27682845were used and should be refactored away.
27692846
2847+ [source,clojure]
2848+ ----
2849+ (defn user-name [request]
2850+ ;; HACK: Parsing the token manually until we add proper auth middleware.
2851+ (-> request :headers (get "authorization") (subs 7) decode-token :name))
2852+ ----
2853+
27702854==== `REVIEW` [[review]]
27712855
27722856Use `REVIEW` to note anything that should be looked at to confirm it
27732857is working as intended. For example: `REVIEW: Are we sure this is how the
27742858client does X currently?`
27752859
2860+ [source,clojure]
2861+ ----
2862+ (defn retry [f n]
2863+ ;; REVIEW: Should we add exponential backoff here?
2864+ (loop [i n]
2865+ (or (try (f) (catch Exception _ nil))
2866+ (when (pos? i) (recur (dec i))))))
2867+ ----
2868+
27762869==== Document Custom Annotations [[document-annotations]]
27772870
27782871Use other custom annotation keywords if it feels appropriate, but be
0 commit comments