This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-05-19
Channels
- # ai (3)
- # aws (1)
- # beginners (94)
- # boot (26)
- # cider (3)
- # cljs-dev (99)
- # cljsrn (86)
- # clojure (263)
- # clojure-dusseldorf (4)
- # clojure-greece (22)
- # clojure-italy (2)
- # clojure-quebec (1)
- # clojure-russia (12)
- # clojure-spec (71)
- # clojure-uk (123)
- # clojurescript (92)
- # core-async (4)
- # cursive (13)
- # data-science (2)
- # datomic (123)
- # docker (2)
- # emacs (15)
- # events (1)
- # graphql (2)
- # hoplon (71)
- # jobs-discuss (7)
- # lumo (5)
- # off-topic (12)
- # om (6)
- # onyx (97)
- # other-languages (4)
- # overtone (2)
- # pedestal (1)
- # re-frame (20)
- # reagent (33)
- # remote-jobs (1)
- # ring-swagger (1)
- # rum (5)
- # slack-help (6)
- # uncomplicate (1)
- # unrepl (33)
- # untangled (48)
- # vim (23)
- # yada (21)
I’m playing around with the specs for spec from CLJ-2112, and I’m having some problems with it.
(s/conform ::spec (s/form 'clojure.core/let))
IllegalArgumentException Don't know how to create ISeq from: clojure.lang.Keyword clojure.lang.RT.seqFrom (RT.java:547)
I understand that the specs there are half-baked, but I didn’t expect to get exceptions back.
Hmm, clearly I should be quoting the form I’m passing in, but then I just get back to the IllegalArgumentException
at the beginning when you do this: (s/form 'clojure.core/let)
- that returns the fspec for let, not sure if you wanted that or the args spec which would be (s/form (:args (s/get-spec 'clojure.core/let)))
when you do (s/conform ::spec (clojure.spec.alpha/cat :name ... ))
, you’ll need to quote there as the spec is expecting a sequential thing
I’m actually heading to bed but could load it up tomorrow and look at it
(s/conform ::spec (s/form (:args (s/get-spec 'clojure.core/let))))
IllegalArgumentException Don't know how to create ISeq from: clojure.lang.Keyword clojure.lang.RT.seqFrom (RT.java:547)
can you (pst *e) ?
java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Keyword
at clojure.lang.RT.seqFrom(RT.java:547)
at clojure.lang.RT.seq(RT.java:527)
at clojure.lang.RT.first(RT.java:683)
at clojure.core$first__6389.invokeStatic(core.clj:55)
at clojure.core$first__6389.invoke(core.clj:55)
at clojure.spec.alpha$multi_spec_impl$predx__912.invoke(alpha.clj:904)
at clojure.spec.alpha$multi_spec_impl$reify__919.conform_STAR_(alpha.clj:916)
at clojure.spec.alpha$or_spec_impl$fn__958.invoke(alpha.clj:1035)
at clojure.spec.alpha$or_spec_impl$reify__963.conform_STAR_(alpha.clj:1057)
at clojure.spec.alpha$conform.invokeStatic(alpha.clj:150)
at clojure.spec.alpha$conform.invoke(alpha.clj:146)
at clojure.spec.alpha$dt.invokeStatic(alpha.clj:748)
at clojure.spec.alpha$dt.invoke(alpha.clj:743)
at clojure.spec.alpha$dt.invokeStatic(alpha.clj:744)
at clojure.spec.alpha$dt.invoke(alpha.clj:743)
at clojure.spec.alpha$deriv.invokeStatic(alpha.clj:1475)
at clojure.spec.alpha$deriv.invoke(alpha.clj:1469)
at clojure.spec.alpha$deriv.invokeStatic(alpha.clj:1483)
at clojure.spec.alpha$deriv.invoke(alpha.clj:1469)
at clojure.spec.alpha$deriv.invokeStatic(alpha.clj:1486)
at clojure.spec.alpha$deriv.invoke(alpha.clj:1469)
at clojure.spec.alpha$deriv.invokeStatic(alpha.clj:1483)
at clojure.spec.alpha$deriv.invoke(alpha.clj:1469)
at clojure.spec.alpha$re_conform.invokeStatic(alpha.clj:1610)
at clojure.spec.alpha$re_conform.invoke(alpha.clj:1601)
at clojure.spec.alpha$regex_spec_impl$reify__1340.conform_STAR_(alpha.clj:1651)
at clojure.spec.alpha$conform.invokeStatic(alpha.clj:150)
at clojure.spec.alpha$conform.invoke(alpha.clj:146)
at clojure.spec.alpha$dt.invokeStatic(alpha.clj:748)
at clojure.spec.alpha$dt.invoke(alpha.clj:743)
at clojure.spec.alpha$dt.invokeStatic(alpha.clj:744)
at clojure.spec.alpha$dt.invoke(alpha.clj:743)
at clojure.spec.alpha$multi_spec_impl$reify__919.conform_STAR_(alpha.clj:917)
at clojure.spec.alpha$or_spec_impl$fn__958.invoke(alpha.clj:1035)
at clojure.spec.alpha$or_spec_impl$reify__963.conform_STAR_(alpha.clj:1057)
at clojure.spec.alpha$conform.invokeStatic(alpha.clj:150)
at clojure.spec.alpha$conform.invoke(alpha.clj:146)
at clojure.spec.specs$eval3133.invokeStatic(form-init2127301951087080660.clj:1)
at clojure.spec.specs$eval3133.invoke(form-init2127301951087080660.clj:1)
at clojure.lang.Compiler.eval(Compiler.java:6977)
I suspect this is related to CLJ-2152, Metosin in a blog post said that their spec walker/visitor didn’t work with s/&
or s/keys*
because of it.
From your test cases in that patch, I get this:
(s/conform ::spec (s/form (s/keys* :req [::foo])))
IllegalArgumentException Don't know how to create ISeq from: clojure.lang.Keyword clojure.lang.RT.seqFrom (RT.java:547)
that code had a number of broken cases due to form - we’ve fixed most of them since but there are a few known problems still
s/&, s/keys* in particular
I guess some of the nested specs in let bindings could be getting tripped up
but the specs for s/cat could use it
anyhow, that ticket is incomplete because it’s a wip and there are many things that don’t work with it yet so it doesn’t surprise me that things don’t work
rather than just having it sit on my hard drive I figured it was better to be a wip on a ticket
Sure, is there a workaround I could use? It doesn’t seem like a problem with the specs themselves, but more likely with form
I don’t think it is - it looks like (s/form (s/keys* :req [::foo]))
returns the right thing
sorry, grabbed wrong code there
(s/form (:args (s/get-spec 'clojure.core/let)))
I get (clojure.spec.alpha/cat :bindings :clojure.core.specs.alpha/bindings :body (clojure.spec.alpha/* clojure.core/any?))
for that, which seems good
the spec specs should only need to have working s/cat and s/* for that to conform
well, I’m too wiped to take it any further atm
will take a glance tomorrow
It seems like s/&
is the root cause - if I macroexpand (s/keys* :req [::foo])
I get:
(let* [mspec# (s/keys :req [:clojure.spec.specs/foo])]
(s/with-gen (s/& (s/* (s/cat :clojure.spec.alpha/k keyword? :clojure.spec.alpha/v any?))
:clojure.spec.alpha/kvs->map
mspec#) (fn [] (clojure.spec.gen.alpha/fmap (fn [m#] (apply concat m#)) (s/gen mspec#)))))
the error message looks like the ::spec multi-spec is using the dispatch function first on a keyword
so maybe it’s just that ::spec needs to be expanded to include keywords as valid specs
(s/def ::spec
(s/or :set set?
:pred symbol?
:registered-spec keyword?
:form (s/multi-spec spec-form (fn [val tag] val))))
I probably just didn’t test that case
I was spending most of my time fixing s/form bugs :)
anyhow, good night…
for real!
Probably a dumb question, but when I use s/describe
I’m getting back a list in the form of (keys :req [:person/first-name :person/last-name] :opt [:person/contact])
. Is there an easy way to convert this to a map? Is it hacky to use n’th to access the required and optional fields?
@seantempesta I really wouldn't worry about that. If you write a single function to handle the extraction of what you want into a data structure suitable to your needs you only have a single function to refactor should the world change...
Well the prior conversation here is about specs for specs which allow you to conform a spec form into a map
But still a wip
this looks like a bug to me:
(s/conform (s/keys :req-un [:bogus/bogus]) {:bogus "foo"}))
1) define an s/keys, without defining :bogus/bogus. There’s no warning/error that :bogus/bogus is undefined, and the spec conforms
agreed, file a jira
although as I try other things, this is also the behavior with :req
“The validator will ensure the :req keys are present.”
from the s/keys docstring
I’m agreeing with you
“keys … are required, and will be validated and generated by specs (if they exist)”
so, I’ve changed my mind - I think it’s doing what it says will do
What would be a good way of and-ing multiple specs without the conforming behavior of s/and
?
Good point. Thanks!