Fork me on GitHub
#clojure-spec
<
2018-11-15
>
stijn11:11:16

How can I create a generator that either generates something of a type or nil? (e.g. (spec/gen (spec/inst-in start end)) or nil)

borkdude11:11:29

@stijn the either part you can do with s/or or s/alt

borkdude11:11:47

or use nilable

stijn11:11:04

oh, of course 🙂

borkdude14:11:58

what’s the minimum clojure version in which spec can be used, 1.9.0?

mpenet14:11:38

1.8 if you use clojure-future-spec

mpenet14:11:01

prolly lower too, but we ran on 1.8 + clojure-future-spec smoothly for a while on some services

borkdude15:11:30

ah yes, now that you remind me, we did too

Wilson Velez16:11:02

Hi all, Where can I start to learn spec?

eoliphant16:11:50

hi one of my devs is playing with spec, and ran into this issue when composing a couple

(s/def ::even-or-odd (s/or
                       :even even?
                       :odd odd?))

(s/def ::small-even-odd (s/and ::even-or-odd #(< % 100)))

(s/valid? ::small-even-odd 1)
; causes
=> ClassCastException clojure.lang.MapEntry cannot be cast to java.lang.Number   (Numbers.java:226)
It seems like the anon function is getting a KV pair instead of the value that’s being checked.

borkdude16:11:41

@eoliphant what’s the result of (s/conform ::even-or-odd 1)?

eoliphant16:11:29

that’s what I was thinking, but i didn’t realize that that would ‘carry forward’ into the next spec

borkdude16:11:30

maybe try nonconforming around the spec

borkdude16:11:42

wonder what the current state of that is

eoliphant17:11:39

yeah to your point it’s a tuple [:odd 1]

jaihindhreddy-duplicate18:11:03

Well, you could flip the order. (s/def ::small-even-odd (s/and #(< % 100) ::even-or-odd))

Alex Miller (Clojure team)18:11:11

actually, I guess it won’t gen regardless

Alex Miller (Clojure team)18:11:25

you need an int? at the beginning or something

devth19:11:05

if i have two functions in the same namespace that i want to spec with req-un with the same named arg e.g. match but different shapes, must I put those specs in other namespaces in order to specify the different shapes?

devth19:11:31

since the spec must be named match and I can't specify two specs with the same name, e.g.:

(s/def ::match string?)

...

(s/def ::match number?)

noisesmith19:11:44

if they are req-un why not just give them different namespaces?

devth19:11:01

instead of :: you mean?

devth19:11:15

like :fun1/match :fun2/match?

noisesmith19:11:33

right - :: is a shorthand for the current namespace

devth19:11:06

ok. guess i wasn't sure if it's appropriate to abandon the :: convention since all my other specs in that namespace are using it :thinking_face:

devth19:11:44

almost seems like that makes them private/internal specs

Alex Miller (Clojure team)19:11:32

it’s ok and fine to do that

devth19:11:46

got it. thanks 👍

Alex Miller (Clojure team)19:11:51

fyi, changes coming in this area for next version of spec that should make it less weird

👍 4
noisesmith19:11:57

I've never seen any assumption or convention that specs that don't use the current namespace are private

4
borkdude19:11:23

another way to mark them private is to move them to an foo/impl.clj namespace 🙂

devth19:11:43

is that a java thing? 🙂

borkdude19:11:01

pretty general convention

noisesmith19:11:17

it's a convention in many clojure projects, if the ns has impl as part of its path you know you aren't expected to rely on it as a consumer

Alex Miller (Clojure team)19:11:27

core.async is a good example

seancorfield19:11:52

@alexmiller Are you aware that clojure.spec-alpha2.test/check is "broken" at the moment?

Alex Miller (Clojure team)19:11:25

and I will fix it as soon as I finish getting the next Clojure released :)

seancorfield19:11:16

I tried to fix it locally but I haven't quiet gotten my head around the path through the code to figure out exactly what needs changing... yet...

Alex Miller (Clojure team)19:11:18

I did not intentionally change anything around this, so it’s something I (unintentionally) broke, but haven’t looked yet

seancorfield19:11:48

I think it's because stest/check still, ultimately, calls s/spec (a macro) and this line in check-1 no longer behaves the same as before:

specd (s/spec spec)]

seancorfield19:11:26

(I just haven't quite figured out the correct invocation to replace that with)

Alex Miller (Clojure team)20:11:48

prob a bug in the s/spec impl

seancorfield21:11:57

FYI, I tried switching our code over to clojure.spec-alpha2 because, why not? I ran into two speed bumps (so far)...

seancorfield21:11:47

1. we reuse :clojure.core.specs.alpha/binding in one of our specs (I got around that by using eval to s/def that spec into the new spec's registry).

seancorfield21:11:38

2. we use test.chuck and it's wired into clojure.spec.alpha so I'd need to create a fork of that using the new clojure.spec-alpha2 artifact to make things work. A spec that uses test.chuck fails with

Caused by: java.lang.IllegalArgumentException: No method in multimethod 'create-spec' for dispatch value: ws.domain.member/bounded-string

seancorfield21:11:48

Not yet sure what causes that.

seancorfield21:11:16

(s/def ::email (s/with-gen (s/and (bounded-string 5 128)
                                  wstr/valid-email?)
                 (wgen/fn-string-from-regex wstr/email-regex)))

seancorfield21:11:30

(defn bounded-string
  "Given min/max lengths, return a spec for a string within
  those lengths (inclusive).)"
  [from to]
  (s/and string? #(<= from (count %) to)))

seancorfield21:11:02

I have a feeling this is related to the stest/check failure since it seems to be due to an assumption that a form like (a-fn ...) can be dispatched on the first argument, rather than evaluating it and dispatching on the result?

Alex Miller (Clojure team)21:11:03

yeah, might be missing a case there

seancorfield21:11:07

If it's any help, I tried this

(defn bounded-string
  "Given min/max lengths, return a spec for a string within
  those lengths (inclusive).)"
  [from to]
  (s/and string? #(<= from (count %) to)))
(def ^:private email-bounded-string? (bounded-string 5 128))
and it failed with
Exception in thread "main" Syntax error compiling at (ws/domain/member.clj:87:1).
Unable to resolve symbol: from in this context
so at this point I'll give up 🙂