taoensso / truss

Assertions micro-library for Clojure/Script
https://www.taoensso.com/truss
Eclipse Public License 1.0
304 stars 14 forks source link

assertions with pre/post conditions #5

Closed daonsh closed 7 years ago

daonsh commented 7 years ago

I've been reading the docs for truss and you have this example:

(defn square [n] ;; Note the use of have? instead of have {:pre [(have? #(or (nil? %) (integer? %)) n)] :post [(have? integer? %)]} (let [n (or n 1)] (* n n)))

I'm still not a Clojure export so I went to the docs about :pre and :post and found: pre-expr and post-expr are boolean expressions that may refer to the parameters of the function. In addition, % may be used in a post-expr to refer to the function’s return value. If any of the conditions evaluate to false and assert is true, an assertion failure exception is thrown.

As I understand, % may be used only in the :post, but you use it in the :pre, what does that mean?

Thanks

ptaoussanis commented 7 years ago

Hi Shauli,

In the :post case, the % is referring to the function's result and in the :pre case, the % is part of the anonymous predicate function:

{:pre  [(have? (fn [x] (or (nil? x) (integer? x))) n)]
 :post [(have? integer? %)]}

The :pre predicate is (fn [x] (or (nil? x) (integer? x))) and argument n. The :post predicate is integer? and argument %

The :pre predicate can also be expressed as #(or (nil? %) (integer? %)). Nothing special to do with the pre-expr / post-expr, just an anonymous function.

Does that make sense?

daonsh commented 7 years ago

OK, yeah, I understand now, it was a stupid question, sorry. :) I don't like that anonymous function syntax much so I don't use it, it confuses me. :) Thanks for your help.

ptaoussanis commented 7 years ago

No problem (and not at all a stupid question). Yeah, I actually rarely use the anonymous fn syntax myself - it's not much shorter than the longer form, and can be harder to read/understand.