clojure-spec

About: http://clojure.org/about/spec Guide: http://clojure.org/guides/spec API: https://clojure.github.io/spec.alpha/clojure.spec.alpha-api.html
arnaud_bos 2020-04-28T09:23:28.282900Z

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"?

alexmiller 2020-04-28T12:52:36.283900Z

No, just bugs I think

alexmiller 2020-04-28T12:53:47.284700Z

Spec 2 is not ready for use

arnaud_bos 2020-04-28T14:32:09.286800Z

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

alexmiller 2020-04-28T14:32:52.287600Z

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

2020-04-28T14:35:44.289100Z

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?

arnaud_bos 2020-04-28T14:37:08.289200Z

I see, thank you πŸ™‚

Franklin 2020-04-28T18:31:41.290300Z

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

Franklin 2020-04-28T18:31:52.290800Z

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.

Franklin 2020-04-28T18:32:27.291400Z

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

Franklin 2020-04-28T18:32:40.291700Z

Any help with be appreciated

jaihindhreddy 2020-04-28T18:33:12.292300Z

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

Franklin 2020-04-28T18:33:36.292600Z

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

jaihindhreddy 2020-04-28T18:33:37.292800Z

spec uses it for generation

alexmiller 2020-04-28T18:37:27.293400Z

this is covered in the spec guide btw https://clojure.org/guides/spec

Franklin 2020-04-28T18:37:27.293500Z

@jaihindhreddy That worked πŸ˜ƒ :thumbsup:

πŸ‘ 1
Franklin 2020-04-28T18:37:58.293600Z

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

kenny 2020-04-28T19:19:08.294700Z

Is there a spec collection macro that works with eduction?

kenny 2020-04-28T19:20:45.294900Z

e.g., something that returns true here:

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

shooit 2020-04-28T19:25:41.296500Z

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

dominicm 2020-04-28T19:29:24.296600Z

@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.

kenny 2020-04-28T19:30:10.297300Z

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

alexmiller 2020-04-28T19:32:10.298100Z

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

kenny 2020-04-28T19:34:36.299800Z

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.

alexmiller 2020-04-28T19:42:25.300Z

Right