Fork me on GitHub

the new specize seems to turn any function into a spec. As collections are also functions, this gives bit unintuitive results:

(s/valid? {:a 1 :b 2} :b) ; true
(s/valid? #{1 2 3} 3)     ; true
(s/valid? [1 2 3] 1)      ; true
(s/valid? [1 2 3] 4)      ; java.lang.IndexOutOfBoundsException
(s/conform > 10)          ; true
(s/conform > >)           ; #object[clojure.core$_GT_


should the collections have special behavior with specize? would not turn into specs? That would help my case, I would like to identify and convert nested vectors and sets into collection specs via my coll-spec macro, but now they can be used as (strangely behaving) specs. Set seems to be the only one of those three that could act as a spec itself. But there could be s/set for it?

Alex Miller (Clojure team)15:11:41

What's unintuitive about the above?

Alex Miller (Clojure team)15:11:55

Any function that takes 1 arg can be used as a spec

Alex Miller (Clojure team)15:11:26

Sets, maps, and vectors satisfy that

Alex Miller (Clojure team)15:11:56

It's very intentional that this works


set as a spec means “one of the values” and it has a generator. what does a vector as a spec mean?

Alex Miller (Clojure team)15:11:09

Nothing very useful but it would mean "has a valid index"


ok, thanks for the answers.


Is there a way to directly reuse a spec defined as multimethod implementation? I mean just one of them.


@yonatanel How do you mean "directly"?


Does calling the multimethod with an appropriate value qualify? 🙂


No, I want to define a similar spec by using the one I already defined with one of the multimethod instances, without calling it with a fake map just for the dispatch value. In the end I just defined the common spec as a keyword but I thought there might be a trick to do that.

Alex Miller (Clojure team)21:11:58

Why don't you do the reverse? Define the spec and then have the multimethod return it.


@alexmiller That's what I ended up doing.