Last active
August 16, 2021 11:39
-
-
Save tgk/5844091 to your computer and use it in GitHub Desktop.
Some Clojure anti-patterns
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; Anti patterns | |
;; Implicit data manipulation anti-pattern | |
;; | |
;; Having nested calls manipulating data, instead of explicitly stating | |
;; what changes are performed to the data | |
(def h | |
[z] | |
;; ... | |
) | |
(def g [y] | |
;; ... | |
(h (->z y))) | |
(def f [x] | |
;; ... | |
(g (->y x))) | |
;; VS | |
(-> x | |
f | |
g | |
h) | |
;; The benifits are two-fold: we can explicitly read what the sequence | |
;; of data manipulations are, and we can insert log statements easily to | |
;; track the data. Also, the definition order of f, g and h is | |
;; not important. They are made reusable, and decoupled from each other. | |
;; Another point, we can only test f->g->h, g->h and h in the first | |
;; strategy, we can test each of the functions in the other | |
;; Example | |
;; logs -> logs with error 500 -> logs grouped by date -> entry with | |
;; most elements -> key for that entry | |
;; First strategy: | |
(defn filtered-logs | |
[logs] | |
(filter #(= 500 (:error %)) logs)) | |
(defn filtered-and-grouped-by-date-logs | |
[logs] | |
(group-by :date (filtered-logs logs))) | |
(defn day-with-most-500-errors | |
[logs] | |
(key (max-key (comp count second) (filtered-and-grouped-by-date-logs logs)))) | |
;; Second strategy | |
(defn filtered-logs | |
[logs] | |
(filter #(= 500 (:error %)) logs)) | |
(defn filtered-and-grouped-by-date-logs | |
[logs] | |
(group-by :date logs)) ;; now does less | |
(def day-with-most-500-errors | |
[logs] | |
(->> logs | |
filtered-logs | |
grouped-by-date-logs | |
(max-key (comp count second)) | |
key)) | |
;; Related, but more difficult to illustrate: | |
;; Data reconstructive surgery vs. data massage anti-pattern | |
;; | |
;; Information is transformed through different representations aiding | |
;; in a calculation, where each representation is different, introducing | |
;; a new view of the world in each function invocation, thereby making | |
;; it hard to mentally context switch from function to function. It also | |
;; makes it more cumbersome to generate test data. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment