Fork me on GitHub
#clojure-spec
<
2017-06-09
>
lambder11:06:20

is there a way to have :gen-max with s/+ ?

lambder11:06:32

e.g. to limit the size of the collection generated by s/+ spec

Alex Miller (Clojure team)11:06:56

currently no, although I think that would be a good enhancement

linuss12:06:52

Hahahaha, wow, thanks!

linuss12:06:00

that's a waste of a morning...

linuss12:06:17

yeah, I must have dozed off while writing that

stbgz15:06:20

Hey all, I haven been having problems trying to write a spec as follows. I have a map that looks like this

{
:key1   "val1"
:key2    ""
:key3   34
:x-somestring "some string"
:x-someotherstring "string as well"
}
In essence the map is a mix of well know keys(:key1, :key2, :key3) and and optional set of patterned keys (:x-…). I can easily model either part: (s/keys for the first part and s/map-of for the second part) but I am having a hard time expressing both at the same time. Any ideas on how I can do it?

Alex Miller (Clojure team)16:06:12

this is sometimes called a “hybrid map”

Alex Miller (Clojure team)16:06:43

you can’t use s/map-of

Alex Miller (Clojure team)16:06:06

but you can use an s/merge of s/keys and an s/every-kv that specs the map entry tuples

Alex Miller (Clojure team)16:06:36

there is a slightly more complicated example outlined in this blog: http://blog.cognitect.com/blog/2017/1/3/spec-destructuring

Alex Miller (Clojure team)16:06:02

search for “hybrid” in there to find that part

ikitommi17:06:04

@pithyless hi, and thanks for the report - there was a bug in explain, should be fixed in [metosin/spec-tools "0.2.1-SNAPSHOT"] (which now uses the latest clj, cljs & spec):

(require '[spec-tools.core :as st])
(require '[spec-tools.data-spec :as ds])
(st/explain-data (ds/spec ::foo {:foo string?}) {:foo 42})
; ::s{:problems ({:path [:foo]
;                 :pred clojure.core/string?
;                 :val 42
;                 :via [:user$foo/foo]
;                 :in [:foo]})
;     :spec #Spec{:form (clojure.spec.alpha/keys :req-un [:user$foo/foo])
;                 :type :map
;                 :keys #{:foo}}
;     :value {:foo 42}}

pithyless18:06:27

@ikitommi - Perfect! I can confirm it fixes my issue. Thanks for the lightning-fast response and apologies for not going through GH issues. I figured I was just doing something wrong 🙂

don.dwoske19:06:15

I'd like to pass parameters into a predicate function along with the value being checked ... a simple example might be a predicate to validate a integer with a min and max value... i.e. validate x is between 1-10. What are common design patterns for this? First thought is to write a function that returns a closure ... any real-world, slick examples of such a thing?

joshkh19:06:05

is it possible to have something like (s/coll-of :some.other/spec)?

ghadi19:06:40

@don.dwoske there's already some builtins like int-in-range?

ghadi19:06:25

err rather int-in

don.dwoske19:06:45

@ghadi - thanks for the example, that's what I was thinking - write macros or functions which return specs or predicates. https://github.com/clojure/clojure/blob/d920ada9fab7e9b8342d28d8295a600a814c1d8a/src/clj/clojure/spec.clj#L1623

ghadi20:06:30

@don.dwoske yup. fyi all of clojure.spec is being tracked in a different repository now.

don.dwoske20:06:09

Ah - of course. In my defense, whenever I search for docs, I end up here : https://clojure.github.io/clojure/branch-master/clojure.spec-api.html and when clicking on "source" for a function.. I end up where I linked to.

misha20:06:08

@joshkh what do you mean?

(s/def :some/spec int?)
(s/def :another/spec (s/coll-of :some/spec :kind vector?))
(s/exercise :another/spec)
=>
([[0 0 -1 0] [0 0 -1 0]]
 [[-1 0 -1 -1] [-1 0 -1 -1]] ...