Fork me on GitHub
#clojure-spec
<
2018-07-31
>
lilactown18:07:43

how do I spec a function that takes only one argument?

seancorfield18:07:18

(s/fdef my-func :args (s/cat :arg ::spec)) (to be more specific)

seancorfield18:07:01

@lilactown Here's an example from our codebase at work

(s/fdef me
  :args (s/cat :access-token string?)
  :ret (s/nilable (s/keys :req-un [::id ::name])))

👍 4
lilactown20:07:54

how are people enabling instrumentation in development?

lilactown20:07:43

I'm using CLJS. I'm thinking of doing something like:

(when js/goog.DEBUG
  (stest/instrument))
but I'm worried that clojure.spec.test.alpha is going to end up in my release bundle

justinlee21:07:00

let me know if you figure out the right solution 🙂

seancorfield21:07:44

(we use clojure.spec in production code for validation and conformance so I'm puzzled as to why you'd want to avoid it? doesn't cljs use tree-shaking anyway to remove unused code?)

lilactown21:07:04

validating and conforming can be done without including clojure.spec.test

lilactown21:07:35

and I'm not sure if tree-shaking is smart enough to completely eliminate the lib if it's not used in a release build. will have to test

lilactown21:07:52

I have a second stupid question: is there an easy way to alias a spec?

lilactown21:07:17

e.g. (s/def ::my-spec <point to ::other-spec>)

hiredman21:07:02

spec validates functions by generating example arguements and calling the function on the examples, which is not something you'll want to do in production

hiredman21:07:18

if you are strictly validating datastructures that should be fine

lilactown22:07:13

right. I know I definitely don't want to instrument my fdefs in prod 🙂

avi22:07:44

:thinking_face: I don’t think instrumentation involves generators … not saying instrument is appropriate for runtime, just might be helpful to keep things clear…

noisesmith22:07:40

doesn't it, for the case where the arg is specced to be a function, it would be checked by exercising it

noisesmith22:07:02

(let me know if I misunderstand something here...)

avi13:08:45

:man-shrugging: I dunno, I think I spoke beyond my level of understanding — sorry

avi13:08:57

your example is fascinating!

noisesmith22:07:09

user=> (require '[clojure.spec.alpha :as s])
nil
user=> (require '[clojure.spec.test.alpha :as stest])
nil
user=> (s/fdef bar :args (s/cat :f (s/fspec :args (s/cat :x int?) :ret int?)) :ret int?)
user/bar
user=> (defn bar [f] (f 0))
#'user/bar
user=> (stest/instrument `bar)
[user/bar]
user=> (bar (fn [x] (println "called with arg" x) x))
called with arg 0
called with arg 0
called with arg 0
called with arg 0
called with arg 1
called with arg 2
called with arg -1
called with arg 0
called with arg -2
called with arg -24
called with arg 3
called with arg -2
called with arg 9
called with arg -1
called with arg -757
called with arg -1
called with arg 3
called with arg 1963
called with arg 1165
called with arg -359
called with arg -3956
called with arg 0
0

noisesmith22:07:39

example of the generation behavior with instrument

🆒 4