Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 95 additions & 2 deletions README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -960,6 +960,19 @@ acronyms like HTTP, RFC, XML uppercase.)
NOTE: `CapitalCase` is also known as `UpperCamelCase`, `CapitalWords`
and `PascalCase`.

[source,clojure]
----
;; good
(defprotocol Serializable ...)
(defrecord HttpRequest ...)
(deftype XMLParser ...)

;; bad
(defprotocol serializable ...)
(defrecord http-request ...)
(deftype xml_parser ...)
----

=== Predicate Methods [[naming-predicates]]

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

The names of functions/macros that are not safe in STM transactions
should end with an exclamation mark (e.g. `reset!`).
should end with an exclamation mark (e.g. `reset!`). The `!` signals
to callers that the function has side-effects and should not be called
inside a `dosync` block.

[source,clojure]
----
;; good
(defn save-user! [user]
(db/insert! user))

;; bad - side-effecting function without the ! warning
(defn save-user [user]
(db/insert! user))
----

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

Expand Down Expand Up @@ -2236,9 +2262,38 @@ throw an exception -- throws an exception of a standard type
`java.lang.UnsupportedOperationException`,
`java.lang.IllegalStateException`, `java.io.IOException`).

[source,clojure]
----
;; good - use ex-info for data-carrying exceptions
(throw (ex-info "Invalid input" {:value x :reason :negative}))

;; good - use standard Java exception types
(throw (IllegalArgumentException. "x must be positive"))

;; bad - defining a custom exception type for no reason
(deftype MyCustomException [msg]
...)
----

=== Prefer `with-open` Over `finally` [[prefer-with-open-over-finally]]

Favor `with-open` over `finally`.
Favor `with-open` over `finally`. `with-open` guarantees that the
resource is closed even if an exception is thrown, with less
boilerplate and no risk of forgetting the cleanup step.

[source,clojure]
----
;; good
(with-open [rdr (clojure.java.io/reader "file.txt")]
(slurp rdr))

;; bad - verbose and easy to get wrong
(let [rdr (clojure.java.io/reader "file.txt")]
(try
(slurp rdr)
(finally
(.close rdr))))
----

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

Expand Down Expand Up @@ -2753,26 +2808,64 @@ with no note. This usage should be the exception and not the rule.
Use `TODO` to note missing features or functionality that should be
added at a later date.

[source,clojure]
----
(defn process-order [order]
;; TODO: Add support for discount codes.
(calculate-total order))
----

==== `FIXME` [[fixme]]

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

[source,clojure]
----
(defn calculate-total [order]
;; FIXME: This doesn't account for tax in all regions.
(reduce + (map :price (:items order))))
----

==== `OPTIMIZE` [[optimize]]

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

[source,clojure]
----
(defn find-duplicates [coll]
;; OPTIMIZE: O(n^2) — consider using a set for large collections.
(for [x coll y coll :when (and (not (identical? x y)) (= x y))]
x))
----

==== `HACK` [[hack]]

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

[source,clojure]
----
(defn user-name [request]
;; HACK: Parsing the token manually until we add proper auth middleware.
(-> request :headers (get "authorization") (subs 7) decode-token :name))
----

==== `REVIEW` [[review]]

Use `REVIEW` to 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?`

[source,clojure]
----
(defn retry [f n]
;; REVIEW: Should we add exponential backoff here?
(loop [i n]
(or (try (f) (catch Exception _ nil))
(when (pos? i) (recur (dec i))))))
----

==== Document Custom Annotations [[document-annotations]]

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