Skip to content

Instantly share code, notes, and snippets.

@wdhowe
Last active February 3, 2024 21:04
Show Gist options
  • Save wdhowe/17fcd999adfa8bf7b4534e5d6fda7c13 to your computer and use it in GitHub Desktop.
Save wdhowe/17fcd999adfa8bf7b4534e5d6fda7c13 to your computer and use it in GitHub Desktop.
Clojure macro: as-some->
;; This macro is also available in: https://github.com/wdhowe/clj-contrib
(defmacro as-some->
"as->, with the nil checking of some->.
Binds name to expr. When name is not nil, evaluates the first
form in the lexical context of that binding. When that result
is not nil, then binds name to result, repeating for each
successive form."
[expr name & forms]
(let [steps (map (fn [step] `(if (nil? ~name) nil ~step))
forms)]
`(let [~name ~expr
~@(interleave (repeat name) (butlast steps))]
~(if (empty? steps)
name
(last steps)))))
(comment
;; example 1: successfully returns the string.
(def things {:one 1, :two 2})
(as-some-> things mythings
(:one mythings)
(inc mythings)
(str "These " mythings " things and more!"))
;; example 2: terminates early and returns nil due to the :one key not existing
(def things {:two 2})
(as-some-> things mythings
(:one mythings)
(inc mythings)
(str "These " mythings " things and more!")))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment