Fork me on GitHub

Is there a way to reuse fspec in clojurscript? the only way to spec functions in clojurescript seems to use fdef but that can’t take fspec defined somewhere else as an argument. My goal is to define a function spec in one place and re-use it for all functions that have the same function spec. This can be done in clojure the following way (I believe):

(def n->n-fn-spec (s/fspec :args (s/cat :n number?) :ret number?))

(s/def add5 n->n-fn-spec)
(defn add5 [n] (+ n 5))

(s/def add6 n->n-fn-spec)
(defn add6 [n] (+ n 6))

Alex Miller (Clojure team)14:07:49

instead of def, use s/def

Alex Miller (Clojure team)14:07:54

oh, you're trying to reuse the whole fspec as a function's spec

Alex Miller (Clojure team)14:07:16

not sure I know enough about the cljs impl to say if this is possible


yes that’s what I’m trying to do. But this example should work in clojure (I think without s/def in the first expression)

Alex Miller (Clojure team)15:07:41

it won't work exactly like this in spec 2 in Clojure

Alex Miller (Clojure team)15:07:08

but there is a similar path


I tested and it works both with def and s/def in this example (but with s/def it should be ::n->n-fn-spec …)


Looking at clojurescript fdef code it adds the fn-sym to specedvars atom that is used with instrument.


so you can’t use s/def in clojurescript to spec function symbols (at least I can’t get it to work)

Alex Miller (Clojure team)15:07:49

the fact that it even works in Clojure is somewhat accidental


you mean with def or even with s/def, or you mean reusing fspec in general?

Alex Miller (Clojure team)15:07:53

being able to use s/def with function spec objects

Alex Miller (Clojure team)15:07:23

that won't work in spec 2, but there is a new function s/register that will be available to do the equivalent


will it work with def (not s/def)?

Alex Miller (Clojure team)15:07:18

that's really incidental - def doesn't do anything with the registry so no change there

Alex Miller (Clojure team)15:07:26

the changes are around what s/def does


yeah def just binds a symbol to fspec

Alex Miller (Clojure team)15:07:03

importantly, an fspec object (not a form)

Alex Miller (Clojure team)15:07:17

s/def doesn't work with objects anymore in spec 2, only forms

Alex Miller (Clojure team)15:07:41

but s/register is a new function in spec 2 that s/def (macro) uses


I guess my question is, is reusing fspec is a valid use case for spec? or what is the correct way to have reusable function spec?


that works in clojure and clojurescript

Alex Miller (Clojure team)15:07:25

I can't really answer the latter, but in spec 2 it's possible by registering the same object via s/register. cljs spec 2 work has not been started so tbd


Thanks Alex, I’ll chase David for clojurescript

Alex Miller (Clojure team)16:07:30

I think they're going to wait until we're much further along with spec 2 before they start working on it


It will be great if with spec 2 things will work the same way in Clojure and Clojurescript

Alex Miller (Clojure team)16:07:51

well that's certainly the intent (other than things that can't work the same way)