_vya7
Joined 15 years ago
Karma
2,337
Submissions
1,518
Member since
Jun 25
Joined 15 years ago
Then what is it good for? Just simple apps?
(let-every [x (foo) err "foo failed"
y (bar x) err (format "bar %s failed" x)
z (goo x y) err (format "goo %s %s failed" x y)]
(qux x y z)
(handle-error err))
Where `let-every` is a macro that works like let, but stops short on the first nil/false variable, runs only the next symbol binding expression, and then runs the else-clause.There'd be nothing special about the "err" symbol on each line. It's just the next symbol binding, but on the same line as a convenience, and this means it can reference any previously valid symbol bindings.
Here's a quick & dirty implementation of that macro. I don't have a Clojure interpreter installed, so I don't know if it works.
(defmacro let-every [bindings if-body else-body]
(let [pairs (partition 2 bindings)
quad-pairs (partition 2 pairs)]
(loop [quad-pairs quad-pairs]
(if quad-pairs
(let [[quad-pair] quad-pairs
[try-pair err-pair] quad-pair
[try-sym try-expr] try-pair
[err-sym err-expr] err-pair]
`(if-let [~try-sym ~try-expr]
(recur (next quad-pairs))
`(let [~err-sym ~err-expr]
~else-body)))
if-body))))
Given the above example, it should expand to this: (if-let [x (foo)]
(if-let [y (bar x)]
(if-let [z (goo x y)]
(qux x y z)
(let [err (format "goo %s %s failed" x y)]
(handle-error err)))
(let [err (format "bar %s failed" x)]
(handle-error err)))
(let [err "foo failed"]
(handle-error err)))And without even needing to install anything! "Processing maliciously crafted web content may lead to arbitrary code execution."