Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
(defmacro assert-all
[& pairs]
`(do (when-not ~(first pairs)
(throw (IllegalArgumentException.
(str (first ~'&form) " requires " ~(second pairs) " in " ~'*ns* ":" (:line (meta ~'&form))))))
~(let [more (nnext pairs)]
(when more
(list* `assert-all more)))))
(defmacro when-let*
"Multiple binding version of when-let"
[bindings & body]
(when (seq bindings)
(assert-all
(vector? bindings) "a vector for its binding"
(even? (count bindings)) "exactly even forms in binding vector"))
(if (seq bindings)
`(when-let [~(first bindings) ~(second bindings)]
(when-let* ~(vec (drop 2 bindings)) ~@body))
`(do ~@body)))
;;Example when-let*
(when-let* [a 1
b 2
c (+ a b)]
(println "yeah!")
c)
;;=>yeah!
;;=>3
(when-let* [a 1
b nil
c 3]
(println "damn! b is nil")
a)
;;=>nil
(defmacro if-let*
"Multiple binding version of if-let"
([bindings then]
`(if-let* ~bindings ~then nil))
([bindings then else]
(when (seq bindings)
(assert-all
(vector? bindings) "a vector for its binding"
(even? (count bindings)) "exactly even forms in binding vector"))
(if (seq bindings)
`(if-let [~(first bindings) ~(second bindings)]
(if-let* ~(vec (drop 2 bindings)) ~then ~else)
~(if-not (second bindings) else))
then)))
;;Example if-let*
(if-let* [a 1
b (+ a 1) ]
b)
;;=> 2
(if-let* [a 1
b (+ a 1)
c false] ;;false or nil - does not matter
b
a)
;;=> 1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.