In this function:
(defn my-post
[a]
{:post (number? %)}
a)
The post-condition doesn't execute (or at least, doesn't cause an assertion error). I now know that it should have been:
(defn my-post
[a]
{:post [(number? %)]} ;; note the square brackets around the expression
a)
Which does, in fact, work correctly.
The problem is that this failed silently, and took me a while to figure out what was wrong. No syntax errors, runtime exceptions.
I would like to understand what Clojure does with this code, in order to understand why Clojure didn't complain. Macro expansions? Destructuring? Does the code just disappear if it doesn't see square braces?
http://clojure.org/special_forms documents that the condition-map for
fn
(thus alsodefn
) should be of the form:{:post (number? %)}
will result in(number? %)
being treated as a sequence of assertions, which means it's interpreted as two separate assertions:number?
and%
.(assert number?)
always passes as long asnumber?
is defined and has a true value, which being a core function, it probably does.(clojure.core/assert %)
passes if%
has a true value. It's bound to the value of your argumenta
via thelet
, so it passes ifa
has a true value. Try calling(my-post nil)
with your first function definition and it'll fail the assertion.If you properly put your post-condition in a vector, it expands like this: