Fork me on GitHub

So, reached what seems to me to be a bug: (gen/sample (s/gen (s/and (s/? string?) string?))) -> ([""] [""] ["4"] [""] ["Ii5"] ["fye"] ["x4oa"] ["6i"] ["2LH7cR"] ["Y"]) But it seems that this should fail just as (s/and number? nil?). [""], for instance, is not a string?.

Alex Miller (Clojure team)11:05:33

s/? matches collections but conforms to a value and s/and flows conformed values so I think this is the expected behavior

Alex Miller (Clojure team)11:05:36

Using s/? as a top level regex op often leads to confusing behavior - this is tricky. Usually it gets nested in s/cat or something

👍 4

Thanks! Yeah I found that it works with s/exercise so that makes sense at least


Should I expect spec validation errors to be thrown if I call a function that has a spec registered with s/fdef in CLJS?


(defn foo [a b] a)
=> #'elp.components.dialogs/foo
(s/fdef foo :args (s/cat :attributes map? 
                         :children vector?))
=> elp.components.dialogs/foo
(foo 1 2)
=> 1
I have check-asserts on…working with specs defined with s/def and {:pre (s/valid? ….

Alex Miller (Clojure team)13:05:48

have you instrumented it?


I was confused about that as well. An example I saw used s/instrument from the spec namespace….maybe it moved? Showing as undeclared var

Alex Miller (Clojure team)13:05:09

it’s in the clojure.spec.test.alpha namespace (in clojure) and parallel in cljs

Alex Miller (Clojure team)13:05:27

although I think you can just require that same ns in cljs and it will automatically load the right one


Thanks. Sorry…lazy this morning


I’m on cljs 1.9.946 (unfortunately). Tried googling and can’t discern whether spec.test.alpha is a separate library


Question after that would be how to instrument all functions there’s a fdef for

Alex Miller (Clojure team)13:05:35

clojure.spec.test.alpha is a namespace and is included in clojurescript

Alex Miller (Clojure team)13:05:51

(well the cljs equivalent)

Alex Miller (Clojure team)13:05:00

several arities - no args = instrument all registered fdefs, or with a single symbol or with a collection of symbols

Alex Miller (Clojure team)13:05:25

instrument is covered in the guide above and should work the same way in clojure and clojurescript

🎉 4
Alex Miller (Clojure team)14:05:56

oh, one caveat is that you will likely need to include org.clojure/test.check 0.9.0 as a dep


Ah hah. Thank you 🙂

Alex Miller (Clojure team)14:05:03

ClojureScript 1.10.238
cljs.user=> (defn foo [a b] a)
cljs.user=> (require '[clojure.spec.test.alpha :as stest])

cljs.user=> (require '[clojure.spec.alpha :as s])

cljs.user=> (s/fdef foo :args (s/cat :attributes map?
                         :children vector?))
cljs.user=> (stest/instrument `foo)
cljs.user=> (foo 1 2)
#error {:message "Call to #'cljs.user/foo did not conform to spec:\nIn: [0] val: 1 fails at: [:args :attributes] predicate: map?\n:cljs.spec.alpha/spec  #object[cljs.spec.alpha.t_cljs$spec$alpha1385]\n:cljs.spec.alpha/value  (1 2)\n:cljs.spec.alpha/args  (1 2)\n:cljs.spec.alpha/failure  :instrument\n", :data #:cljs.spec.alpha{:problems [{:path [:args :attributes], :pred cljs.core/map?, :val 1, :via [], :in [0]}], :spec #object[cljs.spec.alpha.t_cljs$spec$alpha1385], :value (1 2), :args (1 2), :failure :instrument}}
Error: Call to #'cljs.user/foo did not conform to spec:
In: [0] val: 1 fails at: [:args :attributes] predicate: map?
:cljs.spec.alpha/spec  #object[cljs.spec.alpha.t_cljs$spec$alpha1385]
:cljs.spec.alpha/value  (1 2)
:cljs.spec.alpha/args  (1 2)
:cljs.spec.alpha/failure  :instrument


Thanks @alexmiller. Dev setup for cljs with spec is now:

(defn dev-setup []
  (when config/debug?
    (s/check-asserts true)
    (set! s/*explain-out* expound/printer)
    (println "dev")))


Hi, guys, we'are having problems spec'ing protocols, we're implementing the protocols with records, so instead of wrap manually the protocol methods with functions, we're defining a defrecord* macro of the kind

defmacro defrecord*
  [name fields pname & opts+body]
  (let [[{:keys [method-parser],
          :or   {method-parser rest-symbol}}
        (parse-opts opts+body)]
    `(do (defrecord ~name
         ~(-build-defns-from-protocol pname (eval method-parser)))))


Is it a good approach for now?

Alex Miller (Clojure team)15:05:41

I think it’s a bad idea to wrap protocol functions (as you then destroy many of the benefits of protocol functions)


why? that's the advice I've always seen given (even before spec was a thing) : use protocol methods for polymorphism and a wrapping function for validation + varargs + else


unless you're talking about a different "wrapping"

Alex Miller (Clojure team)16:05:34

I wouldn’t wrap it purely to use spec

Alex Miller (Clojure team)16:05:12

there are some good reasons to wrap a call to a protocol but you don’t necessarily need one

Alex Miller (Clojure team)15:05:16

rather, I would recommend just not spec’ing protocol functions


@alexmiller I'm curious, why not spec protocol functions?

Alex Miller (Clojure team)18:05:04

or rather you can’t for the purposes of instrument

Alex Miller (Clojure team)18:05:50

I suppose you could spec them regardless for doc (and maybe check)? I haven’t tried it.


@alexmiller I thought you were suggesting it would be a bad idea even if it could be done. I wasn't missing any reason it would be a bad idea 😊