-
-
Save paxan/80352dbb47788da8dc1e to your computer and use it in GitHub Desktop.
try-let
This file contains 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
``` | |
> (try-let [x (/ 5 1) y (/ 5 2)] [x y]) | |
[5 5/2] | |
> (try-let [x (/ 5 1) y (/ 5 0)] [x y]) | |
#<ArithmeticException java.lang.ArithmeticException: Divide by zero> | |
``` |
This file contains 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
;; ComputationFailed protocol idea was inspired by: https://brehaut.net/blog/2011/error_monads | |
(defprotocol ComputationFailed | |
(has-failed? [self])) | |
(extend-protocol ComputationFailed | |
Object (has-failed? [self] false) | |
Throwable (has-failed? [self] true) | |
nil (has-failed? [self] true)) | |
;; inspired by with-open macro | |
(defmacro try-let | |
"bindings => [name init ...] | |
Evaluates body only if ALL the values of the inits were computed | |
successfully. Returns body, or the first failed-to-init value. | |
Uses ComputationFailed protocol to decide if an init has failed. Out | |
of the box, it treats throwables raised by init expressions as | |
computation failures. Same goes for nils." | |
[bindings & body] | |
(when-not (vector? bindings) | |
(throw (IllegalArgumentException. "bindings must be a vector"))) | |
(when-not (even? (count bindings)) | |
(throw (IllegalArgumentException. "bindings must contain even number of forms"))) | |
(if (zero? (count bindings)) | |
`(do ~@body) | |
`(let [x# (try ~(bindings 1) (catch Throwable e# e#))] | |
(if (has-failed? x#) | |
x# | |
(let [~(bindings 0) x#] | |
(try-let ~(subvec bindings 2) ~@body)))))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment