clojure.spec validation for fdef
Asked Answered
Q

1

6

I am trying to write a higher order function in clojure.spec with version 1.9.0-alpha11 and have not been able to get the validation to execute against the returned function.

Using the example in the Higher order functions section of the clojure.spec guide, I define an adder form as:

(defn adder [x] #(+ x %))

As described in the guide, I create a spec as:

(s/fdef adder
  :args (s/cat :x number?)
  :ret (s/fspec :args (s/cat :y number?)
                :ret number?)
  :fn #(= (-> % :args :x) ((:ret %) 0)))

When I execute it in the repl, an exception is thrown instead of the desired spec validation error:

user> (def add2 (adder 2))
#'user/add2
user> (add2 2)
4
user> (add2 "s")
ClassCastException java.lang.String cannot be cast to java.lang.Number  clojure.lang.Numbers.add (Numbers.java:128)                                                                                                                                                           
user> 

I attempted to turn spec'ing on with (stest/instrument `adder). While this works for functions, it is not working for Higher order functions.

Quenelle answered 8/9, 2016 at 3:42 Comment(2)
I could reproduce the same behavior. Where exactly refers your last "as described above" to? And is the double backtick a typo or intended?Predictory
@AntonHarald. I updated the code block. The "as described above" refers to the bolded Higher Order Functions at the top of the post.Quenelle
I
3

As it stands in clojure 1.9-alpha14 higher order functions cannot be validated in that way. Looking at clojure.spec.test/instrument, it is looking for functions in spec's registry, which will only include fdef'd functions.

The fspec in the :ret will be used when testing adder via clojure.spec.test/check and alongside documenting the function that is the value of it.

Ingeborgingelbert answered 9/11, 2016 at 17:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.