Skip to content

Instantly share code, notes, and snippets.

@mikeball
Last active May 26, 2016 18:19
Show Gist options
  • Save mikeball/10cc64fe97c119671918fb2d1d8b4118 to your computer and use it in GitHub Desktop.
Save mikeball/10cc64fe97c119671918fb2d1d8b4118 to your computer and use it in GitHub Desktop.
Avoid nesting if statements using a short circuited threading macro.
(defmacro short->
"Short circuit pipeline/threading operator that shorts on given condition."
[init & steps-and-conditions]
(let [check (-> (take-last 2 steps-and-conditions)
((fn [conditions] (if-not (and (= (count conditions) 2)
(= (first conditions) :on))
(throw (Exception. "Invalid conditions function syntax."))
(second conditions)))))
result (gensym)
step-check (fn [step] `(if (~check ~result) ~result (-> ~result ~step)))
steps (drop-last 2 steps-and-conditions)]
`(let [~result ~init
~@(interleave (repeat result) (map step-check steps))]
~result)))
;; ----------------------------------------
(defn boolean? [b] (instance? Boolean b))
(defn success [position] true)
;; nil means don't move the axis.
(defn check-nil-positions [position]
(if (nil? (:pos position)) true position))
;; Only 0 and 90 are allowed on a switched axis.
(defn check-switched-axis-limits [position]
(if (= (:axis-type position) "switched")
(or (= (:pos position) 0) (= (:pos position) 90))
position))
(defn verify-position [position]
(short-> position
check-nil-positions
check-switched-axis-limits
success
:on boolean?))
(verify-position {:pos nil})
(verify-position {:pos 20})
(verify-position {:pos 20 :axis-type "switched"})
(verify-position {:pos 0 :axis-type "switched"})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment