Fork me on GitHub
#clojure-spec
<
2019-07-17
>
talgiat14:07:43

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

talgiat14:07:31

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

talgiat15:07:09

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 …)

talgiat15:07:27

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

talgiat15:07:18

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

talgiat15:07:28

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

talgiat15:07:43

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

talgiat15:07:45

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

talgiat15:07:20

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?

talgiat15:07:44

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

talgiat16:07:02

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

talgiat16:07:33

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)