pre and post assertions, always in the meta data?

85 views
Skip to first unread message

Laws

unread,
Feb 3, 2022, 1:56:59 PM2/3/22
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
  [cisa-advisory-urls]
  {
   :pre [(set? cisa-advisory-urls)]
   :post [(vector? %)]
   }
  (println "get-cisa-advisories")
  (try

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. 

Laws

unread,
Feb 3, 2022, 4:38:17 PM2/3/22
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

unread,
Feb 16, 2022, 1:27:33 AM2/16/22
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/func
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}]
dev=>

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 ostash.dev) -- 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
Forward
0 new messages