Fork me on GitHub
#clojure-spec
<
2020-04-28
>
arnaud_bos09:04:28

There's this line in spec-alpha2's wiki page on "Schema and select" (emphasis mine): > General form: (s/select schema selection) > β€’ schema (required) - can be a registered schema name, schema form (like s/union), or literal schema But I can't get the "schema form" to work.

(in-ns 'user)
=> #object[clojure.lang.Namespace 0x54029c23 "user"]

(s/def ::a int?)
=> :user/a

(s/def ::b keyword?)
=> :user/b

;; Literal schema: OK
(gen/sample
    (s/gen
      (s/select
        [::a ::b]
        [*]))
    2)
=>
(#:user{:a -1, :b :B/d}
 #:user{:a -1, :b :Q/r})

;; Schema name: OK
(s/register ::ab (s/schema [::a ::b]))
=> :user/ab

(gen/sample
    (s/gen
      (s/select
        ::ab
        [*]))
    2)
=>
(#:user{:a -1, :b :B/_}
 {})


;; Union name: OK
(s/register ::ba (s/union [::a] [::b]))
=> :user/ba

(gen/sample
    (s/gen
      (s/select
        ::ba
        [*]))
    2)
=>
(#:user{:b :./l?}
 #:user{:a -3})

;; s/schema form: Err
(gen/sample
    (s/gen
      (s/select
        (s/schema [::a ::b])
        [*])))
Execution error (IllegalArgumentException) at clojure.alpha.spec.protocols/eval1814$fn$G (protocols.clj:20).
No implementation of method: :keyspecs* of protocol: #'clojure.alpha.spec.protocols/Schema found for class: clojure.lang.PersistentList

;; s/union form: Err
(gen/sample
    (s/gen
      (s/select
        (s/union [::a] [::b])
        [*])))
Execution error (IllegalArgumentException) at clojure.alpha.spec.protocols/eval1814$fn$G (protocols.clj:20).
No implementation of method: :keyspecs* of protocol: #'clojure.alpha.spec.protocols/Schema found for class: clojure.lang.PersistentList
Looks like I've messed something up wrt "symbolic" vs "object"?

Alex Miller (Clojure team)12:04:47

Spec 2 is not ready for use

arnaud_bos14:04:09

Yeah, sorry to make you feel like you have to repeat it again and again. I'm just toying around πŸ™‚

Alex Miller (Clojure team)14:04:52

the whole schema/select impl is due for a rewrite, just don't have time to work on it right now

arnaud_bos14:04:08

I see, thank you πŸ™‚

flipmokid14:04:44

Hi all, I'm playing around with the lastest spec alpha 2. I'm not sure if I'm doing something wrong but:

(spec/def ::tag (spec/and string? (spec/conformer clojure.edn/read-string str)))
(spec/def ::value string?)
(spec/def ::kv (spec/cat :tag ::tag :value ::value))
(spec/def ::fix-message (spec/and string?
                                  (spec/conformer (fn [x] (map #(clojure.string/split % #"=") (clojure.string/split x #"\01"))))
                                  (spec/+ ::kv)))
Should work with a FIX input string (a bunch of k=v pairs joined by ASCII code 01) but currently fails with
["8" "FIX.4.4"] - failed: string? in: [0] at: [:tag] spec: :cme-fix.spec/tag
However, adding an additional predicate into ::kv makes it work:
(spec/def ::tag (spec/and string? (spec/conformer clojure.edn/read-string str)))
(spec/def ::value string?)
(spec/def ::kv (spec/and (constantly true) (spec/cat :tag ::tag :value ::value)))
(spec/def ::fix-message (spec/and string?
                                  (spec/conformer (fn [x] (map #(clojure.string/split % #"=") (clojure.string/split x #"\01"))))
                                  (spec/+ ::kv)))
Am I doing something obviously wrong?

Franklin18:04:41

Hey guys πŸ‘‹ , I'm tring to get started on using clojure.spec and I hit an unexpected/frustrating roadblock...

Franklin18:04:52

user=> (s/exercise false?)

Execution error (FileNotFoundException) at user/eval1428 (form-init5827540222428447763.clj:1).
Could not locate clojure/test/check/generators__init.class, clojure/test/check/generators.clj or clojure/test/check/generators.cljc on classpath.

Franklin18:04:27

This error is thrown for any spec for which I call s/exercise

Franklin18:04:40

Any help with be appreciated

jaihindhreddy18:04:12

You need to add test.check library as a dependency to your classpath

Franklin18:04:36

cool... I'll go ahead and do that

jaihindhreddy18:04:37

spec uses it for generation

Franklin18:04:58

oh... cool.. I didn't actually read that.. I'm following some tutorials... will go through that..

Franklin18:04:27

@jaihindhreddy That worked πŸ˜ƒ :thumbsup:

πŸ‘ 4
kenny19:04:08

Is there a spec collection macro that works with eduction?

kenny19:04:45

e.g., something that returns true here:

(s/valid? (s/coll-of int?) (eduction (map inc) (range 10)))
=> false

shooit19:04:41

I don’t know if there is a spec that you can use but you could alternatively call seq on your eduction to turn it into a LazySeq which would then pass the spec

dominicm19:04:24

@kenny I'm not sure, but I don't think eduction returns a collection, it returns a reducible :). That doesn't help but it does indicate that coll-of probably isn't the right tool.

kenny19:04:10

Right. I'm curious what folks use to validate against it. Hmm, I could do that @shewitt!

Alex Miller (Clojure team)19:04:10

eductions are suspended computations so there is no data to validate without forcing it

kenny19:04:36

This use case is for in a test so I think @shewitt's idea solves it. In general, it probably wouldn't make sense to call valid? on an eduction for that reason, right? Even if checked with s/every, it'd still need to recompute *coll-check-limit* when you finally use the eduction elsewhere.