Fork me on GitHub
#clojure-spec
<
2019-01-25
>
Ben Hammond13:01:35

I've just started playing with . I can see that the :args are getting verified, but I cannot see how to get the :ret verified

Ben Hammond13:01:57

this is the code that I pinched from https://blog.taylorwood.io/2017/10/15/fspec.html

(defn digits
  "Takes just an int and returns the set of its digit characters."
  [just-an-int]
  (into #{} (str just-an-int)))
=> #'dev/digits
(s/fdef digits
        :args (s/cat :just-an-int int?)
        :ret (s/coll-of char? :kind set? :min-count 1))
=> dev/digits
(spec.test/instrument `digits)
=> [dev/digits]
(digits 1)
=> #{\1}
(digits "1")
Execution error - invalid arguments to dev/digits at (form-init1603011188380229902.clj:1).
"1" - failed: int? at: [:just-an-int]

Ben Hammond13:01:23

so far so good; now I want to modify the :ret to something impossible and retest

Ben Hammond13:01:59

(s/fdef digits
        :args (s/cat :just-an-int int?)
        :ret (s/coll-of keyword? :kind set? :min-count 1))
=> dev/digits
(digits 1)
=> #{\1}

Ben Hammond13:01:52

Hmm I was expecting the return value to fail. I can see the change in the doc string

(doc digits)
-------------------------
dev/digits
([just-an-int])
  Takes just an int and returns the set of its digit characters.
Spec
  args: (cat :just-an-int int?)
  ret: (coll-of keyword? :min-count 1 :kind set?)
=> nil

Ben Hammond13:01:08

what do I need to do to get the :ret spec verified?

borkdude13:01:11

@ben.hammond ret is not checked during instrumentation

borkdude13:01:20

it is during generative testing

borkdude13:01:35

this is FAQ number 1 I guess

Ben Hammond14:01:11

is that a feature? or a bug?

borkdude14:01:25

design decision

Ben Hammond14:01:04

okay, so I have to manually call (spec/conform that's not a biggie Thanks

borkdude14:01:54

There’s also orchestra which turns on ret checking in instrumentation

Ben Hammond14:01:51

Well I was just trying to pace out my basic understanding don't need to get too fancy at this point

vemv14:01:50

is there a good predicate for checking if x can be used as a spec? should be true for int?, (spec/spec ...), #{1 2 3}

Ben Hammond14:01:07

(doc spec/def)
-------------------------
clojure.spec.alpha/def
([k spec-form])
Macro
  Given a namespace-qualified keyword or resolvable symbol k, and a
  spec, spec-name, predicate or regex-op makes an entry in the
  registry mapping k to the spec. Use nil to remove an entry in
  the registry for k.
=> nil

Ben Hammond14:01:28

any predicate should be fine

Ben Hammond14:01:51

(which will include int? and hashsets)

Ben Hammond14:01:24

or the keyword identifier of an existing spec

Ben Hammond14:01:43

or an inline spec declaration

Ben Hammond14:01:02

by 'regex-op` I think they mean combinations of (spec/+, (spec/cat, ,(spec/alt` etc..?

Ben Hammond14:01:26

how do you tell if an arbritary function is a predicate? I'm not sure if you can distinguish function arity from the outside

Ben Hammond14:01:38

other than by provoking ArityExceptions

Ben Hammond14:01:05

I guess you could get java.lang.reflect to tell you and there is probably a clojurey wrapping somewhere

vemv14:01:49

not sure if we're talking about the same thing

vemv14:01:11

(defn spec? "whether x can can be used as a spec" [x] ...)

vemv14:01:25

^ I'm seeking this

borkdude14:01:41

@vemv you want a predicate that tells you if a thing fits inside (s/fdef x --> ? <--) ?

borkdude14:01:24

spec already has a spec? predicate, but that doesn’t do the same

vemv14:01:36

yeah, not s/spec?

vemv14:01:10

seeking a filler for (s/def ::foo ->>> x <<<-)

borkdude14:01:17

I guess fn? and keyword? and spec? maybe?

vemv14:01:53

(s/or :ifn ifn? :spec s/spec?)?

vemv14:01:06

yeah, guess so, the fun part of my question was seeking a built-in that did that

Alex Miller (Clojure team)14:01:18

there’s some stuff in CLJ-2112 (specs for specs) patch

👌 5
Alex Miller (Clojure team)14:01:43

keep in mind that all of these answers will be different in spec2 :)