Fork me on GitHub
#clojure-spec
<
2019-08-02
>
kenny16:08:00

I am getting this exception "Additional data must be non-nil." when using st/check on my function. I have gotten this before and then it mysteriously went away. I am now getting it constantly and am curious what is going on. It is coming from these Spec lines: https://github.com/clojure/spec.alpha/blob/5228bb75fa10b7b13ea088d84f4d031cce74a969/src/main/clojure/clojure/spec/test/alpha.clj#L278-L284.

ghadi16:08:27

if you have a reproducible example case, please paste it @kenny

kenny16:08:03

Working on that. It's pretty coupled to this code but I should be able to pull something out.

ghadi16:08:09

cool -- thanks!

ghadi16:08:48

this has been reported before, but AFAIK there's not a deterministically reproducible case

kenny16:08:24

Hopefully I can get one! It's definitely reproducible for me right now.

Alex Miller (Clojure team)16:08:17

the error occurs when you try to create an ex-info with nil data. the case where this happens here is when spec validation fails, but explain-data succeeds (which ideally should never happen). usually, this is a bug in spec. occasionally, it's a bad predicate in user code.

kenny16:08:03

This error is quite confusing. Seems like a bug either way 😉

Alex Miller (Clojure team)16:08:13

well the error should never happen

ghadi16:08:28

right, it's an invariant violation

kenny16:08:26

haha, the best kind of bugs

kenny16:08:55

I pulled some code out to get a repro case and was running st/check on it. It failed with a regular specification error. I thought that was weird because it hasn't failed yet. Turned on instrumentation and ran again and got the "Additional data must be non-nil." message. May be related to instrument.

Alex Miller (Clojure team)16:08:57

this won't help you, but I've made a change in spec-alpha2 to better report this case

kenny17:08:29

Alright, here's a repro: https://gist.github.com/kennyjwilli/f324b94eaadc404cb72fdfe41067b469. Not minimal but I've gotta go make some food. Within 3 or so runs of (st/check formula->fn)`, it will get the exception.

Alex Miller (Clojure team)18:08:45

so I misdiagnosed above - even more subtle... s/conform and s/valid? are returning different answers when run on the same input

Alex Miller (Clojure team)18:08:03

which is because the spec is an fspec, which generates its own source of random inputs

Alex Miller (Clojure team)18:08:11

this is a known issue and generally we've been suggesting people don't use fspec because it has all these unexpected consequences

kenny18:08:58

fspec has proven to be quite valuable though. What is the alternative? Just fn?

Alex Miller (Clojure team)18:08:07

unfortunately it's not even easy to override in a spec alias or anything

kenny18:08:31

Won't that just generate any old function during gen tests and pass it to my function?

Alex Miller (Clojure team)19:08:50

yes, it is significantly harder to use it in check. I'm not saying any of this is good.

Alex Miller (Clojure team)19:08:02

this is a known area I'm hoping to spend some rethink time on in spec 2, but we're going to overhaul the function return value stuff first

kenny19:08:52

Oh ok. Any workaround for now to avoid this error?

Alex Miller (Clojure team)19:08:38

I don't think I have any simple advice for you, other than to remove your :ret spec :(

kenny19:08:00

:ret on the fspec of the top level fn?

Alex Miller (Clojure team)19:08:05

no, the :ret on the fdef

kenny20:08:01

I was trying to add some gen improvements to clojure.spec.alpha but I cannot load the ns in a REPL. I get

CompilerException java.lang.Exception: #object[clojure.spec.alpha$and_spec_impl$reify__2171 0x4a332076 "clojure.spec.alpha$and_spec_impl$reify__2171@4a332076"] is not a fn, expected predicate fn, compiling:(/home/kenny/Forks/spec.alpha/src/main/clojure/clojure/spec/alpha.clj:78:1) 
Is there some magic that needs to happen to have a REPL with Spec itself?

y.khmelevskii20:08:46

hi gents! How I can define spec of vector where I know only first element and don’t know length of vector. For example [:in 1 2 3 4]

y.khmelevskii20:08:56

it would be great to use something like

(s/tuple #{:in :or} & nat-int?)

Alex Miller (Clojure team)20:08:42

(s/cat :in #{:in :or} :nums (s/* nat-int?))

Alex Miller (Clojure team)20:08:00

this is exactly the job the regex ops are made for

y.khmelevskii21:08:27

I see, thank you!