The docstring for clojure.core/binding
says that it "executes the exprs in an implicit do". I would thus expect the elements of the body to be executed in order and the value of the last be returned (c.f. the docstring for do
).
However, the body expressions are not wrapped in a do
or a let
, but rather a try
. This allows for some surprising behavior:
(binding [clojure.core/*print-length* 10]
(/ 10 0)
(catch Exception e
:failure))
The above expression returns :failure
, while the following more obviously throws a compiler exception because catch
can't be used without a try
.
(binding [clojure.core/*print-length* 10]
(do
(/ 10 0)
(catch Exception e
:failure)))
As far as I can tell from the git history, this implementation detail hasn't changed since 2008, so maybe there's some good reason for it. If there is, what is it? If not, can we change the implementation of binding
to actually have a do
around ~@body
?