pre and post assertions, always in the meta data?

Skip to first unread message


Feb 3, 2022, 1:56:59 PMFeb 3
to Clojure

I see this old post by Fogus:

With this example:

(defn constrained–fn [f x]
  {:pre  [(pos? x)]
   :post [(= % (* 2 x))]}
  (f x))

But I see this modern example:

(defn func ^{:pre [(pos? x)] :post [(< % 100) (> % 1)]} [x] (+ 1 x))

Where it is in the metadata. 

But here I still the old style:

(defn constrained-sqr [x] {:pre [(pos? x)] :post [(> % 16), (< % 225)]} (* x x))

I was away from Clojure for a few years, so I think it I missed some of its evolution. Is one of these styles favored? 

I'm struggling with an issue where I cannot get the error to show up, even when I deliberately send in data that would cause the assertion to return false. 

My function started: 

(defn get-cisa-advisories
   :pre [(set? cisa-advisory-urls)]
   :post [(vector? %)]
  (println "get-cisa-advisories")

When I called this with a vector, I got no error, but the app silently died. I'm confused about this. The call to this function is wrapped in a try/catch block, and that assertion must have thrown an error because that is where the app dies, yet I couldn't see the exception in my catch block. 


Feb 3, 2022, 4:38:17 PMFeb 3
to Clojure
Hmmm, okay, I was using slingshot/try+ everywhere and then, just once, I used a plain 'try' and forgot to use the correct catch. My fault. 

Sean Corfield

Feb 16, 2022, 1:27:33 AMFeb 16
to Clojure
Whilst you solved your problem, you didn't get an answer about metadata.

There are multiple places metadata can appear in a function definition:

dev=> (defn ^{:one true} func (^{:two true} [x] {:three true} x) {:four true})
dev=> (meta #'func)
{:one true, :arglists ([x]), :four true, :line 1, :column 1, :file "/home/seanc/.clojure/dev.clj", :name func, :ns #object[clojure.lang.Namespace 0x17b6ad97 "dev"]}
dev=> (->> #'func (meta) :arglists (mapv meta))
[{:two true, :three true}]

I've delineated the arity of the function with ( ) for clarity so you can which metadata belongs to the function Var and which belongs to a specific arity, and you can see they are combined.

I've never seen anything except :pre/:post in position three and I've never seen :pre/:post in position two (until I saw your example from -- but as you can see they are equivalent (and they combine).

I don't think I've ever seen function Var metadata in position four.
Reply all
Reply to author
0 new messages