This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-06-30
Channels
- # aws (1)
- # bangalore-clj (1)
- # beginners (73)
- # boot (13)
- # cider (3)
- # clara (19)
- # cljs-dev (33)
- # cljsrn (37)
- # clojure (177)
- # clojure-dev (13)
- # clojure-gamedev (1)
- # clojure-italy (10)
- # clojure-nlp (1)
- # clojure-russia (1)
- # clojure-spec (64)
- # clojure-uk (128)
- # clojurescript (177)
- # core-async (23)
- # cursive (5)
- # datascript (13)
- # datomic (20)
- # devops (49)
- # emacs (13)
- # graphql (5)
- # hoplon (13)
- # keechma (1)
- # leiningen (3)
- # liberator (4)
- # lumo (2)
- # off-topic (11)
- # om (19)
- # om-next (3)
- # onyx (6)
- # re-frame (13)
- # reagent (14)
- # ring-swagger (7)
- # rum (2)
- # spacemacs (7)
- # unrepl (1)
- # untangled (23)
- # vim (8)
- # yada (1)
@alexmiller I got the ball moving here: https://dev.clojure.org/jira/browse/CLJ-2194. Looking forward to seeing what comes out of this.
I have the following om.next style spec:
(s/def ::ident (s/and vector? (s/cat :ident keyword? :value #(not (coll? %)))))
(s/def ::join-key (s/or :prop keyword? :ident ::ident))
(s/def ::join (s/and (s/map-of ::join-key ::query) #(= (count %) 1)))
(s/def ::union (s/and (s/map-of keyword? ::query) #(> (count %) 1)))
(s/def ::param-expr
(s/cat :query-expr ::query-expr
:params map?))
(s/def ::mutation-expr
(s/or :no-params (s/cat :mutate-key symbol?)
:with-params (s/cat :mutate-key symbol?
:params map?)))
(s/def ::query-expr
(s/or :prop keyword?
:ident ::ident
:mutation-expr ::mutation-expr
:union ::union
:join ::join
:param-expr ::param-expr))
(s/def ::query
(s/or :recursion (s/or :depth number?
:unbounded #(= % '...))
:query (s/and vector?
(s/+ ::query-expr))))
(println (s/conform ::query [:one :two :three]))
(println (s/unform ::query (s/conform ::query [:one :two :three])))
Why does the first print give [:query [[:prop :one] [:prop :two] [:prop :three]]]
but the second give (:one :two :three)
(sequence not a vector)?If query is spec'ed as being a vector?
shouldn't unform also return a vector?
hi there, I’m having some troubles regarding circular refs in my specs. I have a spec defining an office which has employees in the office
ns, and I have an employee (in an employee
ns), which should have an office. As you cn guess, this results in circular dependencies (or when I don’t require one of the namespaces, it results in Unable to resolve spec
. Is there any recommended method to deal with issues like this?
@jwkoelewijn code would help. What you're describing should be possible
Does anyone know of any ring middleware that pretty prints ex-info
‘s that raise spec explain-data
? Thinking of something like prone for dev but for spec problems.
prone currently gives me a huge wall of text
Has anyone worked on a partial spec for specs? Or a test.check generator? I’m mostly interested in generating specs rather than conformance or validation
bbrinck: https://dev.clojure.org/jira/browse/CLJ-2112 is about specs for specs. Those also are a step towards spec generators which I’ve also done some more work that’s not public yet.
I may work on some generators soon. I’m guessing it will be a subset of what you’ve done, but it’ll be public, so I’m happy to share in case it’s useful.
I’ve in particular worked on the generators in the direction of testing spec itself. Namely, if you have spec specs with working generators, you can generate specs, then use those to generate data, then validate that the generated values are valid according to the generated specs
the last time I worked on this I mostly convinced myself there was a bug in multi-spec gen for the non-keyword case that was giving me grief, but I never ran it down
I wonder how you spec that s/conform
returns :clojure.spec/invalid
as a valid result.
@rickmoynihan This isn’t directly applicable, but data-frisk includes some nice-looking spec messages. I wonder if that could be ported.
Do you need to return explain-data or could your raise an ex-info that contains explain
(or some other string representation of the errors)?
I’m just wondering if maybe you could solve the issue by formatting the errors at the source. That might not be desirable though.
Can I destructure metadata? For example, if I have a vector [1 2 3]
which has meta {:some :meta}
-> [:vector [1 2 3] :meta {:some :meta}]
.
I can't work out how I'd spec this.
@danielstockton with a predicate I guess
@mpenet Tried that but I couldn't get destructuring as above when conforming. My understanding of spec is still fairly superficial.
Ok, I'll look into that, thanks.
I don't need the conformed output exactly as above but I need to be able to easily identify the two parts.
(s/conform (s/and vector? (s/conformer #(hash-map :vector % :meta (meta %))))) (with-meta {} {:foo 1}) -> {:vector [] :meta {:foo 1}}
. this example conformer is a bit broken but that's the idea for the coercion part
Cool, why do you say it's broken?
Am I right that conformer
takes a second argument to unform? This might address the issue I had above with unforming to a seq.
Still curious to know exactly why it unforms to a seq. I noticed for simpler specs (just vector?
) it unforms correctly so it must be a side effects of something.
Should I be calling it a vector in the conformed output or is it a 'tuple'?
The source (if this is the right place) seems to unform to a vector: https://github.com/clojure/clojure/blob/d920ada9fab7e9b8342d28d8295a600a814c1d8a/src/clj/clojure/spec.clj#L874
If it is a bug, I can't work out where it comes from.
@danielstockton for that case I think a tuple makes more sense than a cat
, a cat
is for more regexy stuff
I think it unforms to a seq
because you are using a cat
, which is for regexy stuff, and I believe it will always conform to a seq
@wilkerlucio Which cat are you referring to?
The only ones I see are deeper in the spec
this one: (s/def ::ident (s/and vector? (s/cat :ident keyword? :value #(not (coll? %)))))
Oh, ident?
or I'm looking at the wrong place?
I don't think the query I'm unforming has any idents: [:query [[:prop :one] [:prop :two] [:prop :three]]]
. The [:prop :one] is the conformed value for a :prop
::query-expr
which is just a keyword?
The original query is just [:one :two :three]
I did think it might be related to a cat
or similar, somewhere, but I couldn't explain it.
ah, I think I was reading it wrongly, sorry, so it seems something is not aligned between conform
and unform
?
I mean, perhaps I just misunderstand unform because it doesn't promise to give back exactly what you put it, only undo the destructuring..
I'm just curious exactly what's causing this behaviour.
it’s unclear to what is not working as you expect from the back chat - can you restate?
Why does the first print give [:query [[:prop :one] [:prop :two] [:prop :three]]]
but the second give (:one :two :three)
(a lazy sequence, not a vector)?
looks like this is sufficient repro:
(s/def ::query (s/and vector? (s/+ keyword?)))
(println (s/conform ::query [:one :two :three]))
(println (s/unform ::query (s/conform ::query [:one :two :three])))
Yep thanks, I made it look unnecessarily complicated.
so in conform, the general approach is to avoid rebuilding a collection if at all possible, so there you just end up with the original vector on conform
unform of a regex spec however will always (I think) yield a seq
unform of an s/and walks the preds in reverse
Make sense, so it's the s/+
specifically. And if I wanted unform to yield the same collection type, I'd use a customer conformer with a second argument?
I'm trying to use spec to implement a parser and I want to be able to go from query <-> ast. I don't know if this is a good use case for spec or not.
the broader problem here is: how do I use a regex spec but constrain to vectors and this is a known problem area that Rich and I have discussed at length as it came up a lot in spec’ing the core macros
there is currently no simple solution that works as you’d like for all of conforming, generation, explain, and unconform (although you can make subsets of those work)
I’m trying to work out if in this case you could actually somehow supply a custom unform function to the vector? pred as that’s not something I’ve tried
looks like there is no easy way to do so although there is certainly the potential to do so
Ok, I'll keep my ear to the ground.
Can i recursively override a generator? e.g. pass a function to s/spec
's :gen
that overrides just the recursive part, and close over such this also overrides the recursive part, making a depth-limited generator?
I've done this from scratch with clojure.test.check.generators, just trying to see if I can reuse most of what spec would have done.
Recursive generators are already depth limited based on the dynamic var in spec
In case that solves the problem