This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-11-08
Channels
- # bangalore-clj (4)
- # beginners (88)
- # boot (12)
- # cljs-dev (10)
- # cljsjs (1)
- # clojure (284)
- # clojure-denmark (2)
- # clojure-dev (35)
- # clojure-italy (8)
- # clojure-russia (36)
- # clojure-spec (38)
- # clojure-uk (51)
- # clojurescript (145)
- # cursive (6)
- # data-science (1)
- # datomic (8)
- # duct (43)
- # emacs (9)
- # figwheel (2)
- # fulcro (29)
- # graphql (1)
- # immutant (3)
- # instaparse (1)
- # jobs (1)
- # jobs-discuss (1)
- # lumo (16)
- # off-topic (50)
- # onyx (90)
- # re-frame (6)
- # reagent (20)
- # remote-jobs (3)
- # ring-swagger (18)
- # schema (8)
- # shadow-cljs (141)
- # slack-help (3)
- # spacemacs (36)
- # unrepl (7)
- # vim (1)
- # yada (2)
I suppose there is no way to conform a sequence and get a sequence rather than a map?
I know you can use coll-of but that doesn’t work if you want a sequence rather than a collection
the rationale is that s/cat starts a regex spec, and regexes have alternates, so you need to give everything names to know which part of the regex it matched
there's a non-documented not currently supported function that makes a spec nonconforming https://github.com/clojure/spec.alpha/blob/master/src/main/clojure/clojure/spec/alpha.clj#L1761
are there any docs/guides etc on conforming / conformers and tweaking output etc? I understand roughly how they work, but am curious about how to apply them in practice. What it’s ok to use them for, what it’s not a good idea to use them for etc…
conformers exist primarily to build custom composite spec types (s/keys* for example)
interesting hadn’t seen s/keys*
before
s/nilable was originally written this way too although I ended up rewriting a custom impl for better performance
generally I would say you should not use them for data coercion or tweaking output
I have a case where I try to spec a HOF but I can not get check
to satisfy. Here's a toy example of the problem:
(def uuid-regex #"^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$")
(s/def ::name string?)
(s/def ::age pos-int?)
(s/def ::id (s/and string? #(re-matches uuid-regex %)))
(s/def ::person (s/keys :req-un [::name ::age ::id]))
(s/fdef do-stuff
:args (s/cat :person ::person
:lookup (s/fspec :args (s/cat :p ::person) :ret int?)))
(defn do-stuff [person lookup-fn]
(let [result (lookup-fn person)]
:important-work-on-result))
;; works
(s/exercise ::person 1 {::id (fn [] (gen/fmap str (gen/uuid)))})
;; do not work
(s/exercise `do-stuff 1 {::id (fn [] (gen/fmap str (gen/uuid)))})
;; do not work
(stest/check `do-stuff {:gen {::id (fn [] (gen/fmap str (gen/uuid)))}})
I am also open to that there are better ways to run check
on HOFs that I am missingyou’ll need to supply a generator on s/fspec
the thing that’s breaking down is really the gen of ::id I think
what you’re doing should be working - I think this is a bug
(s/exercise (s/fspec :args (s/cat :p ::person) :ret int?) 10 {::id #(gen/fmap str (gen/uuid))})
is minimally sufficient
Good to know, then I can stop scratching my head. Yes, that example yields the same result
yeah, I see the bug in the code. can’t say I know how to fix it though.
when the fspec is conformed by exercise (or by check), it “checks” the generated function spec, but that conform does not have access to the gen overrides so it gens without them.
should I file a ticket? Have not done so before but I am willing to try if that would be helpful
I’m filing one
thanks, will follow the activity, and thanks for your help and explanation of the problem
it’s kind of a deep problem - we’ve got other tickets that are related but I never took the time to really get it.
I would be happy to help, but it sounds like its above my knowledge of the code base if it is a deep problem, not a novice ticket
@rickmoynihan Where I've found conformers useful is dealing with input data that is all strings, but is expected to conform to numeric, boolean, date, etc types.
@seancorfield: yeah I understand the input coercion at boundaries case
That's pretty much the only place I'd "recommend" them, having worked with spec in production since it first appeared.
ok thanks, that’s useful. I just remember rich saying that conformed values are basically the parsed/labelled output you want; and it’s very close to a shape I want for a specific case… thinking it’s better to conform then post-process, rather than use the conformers to do it.
but it occurred to me that if I used conformers then I’d really need to write unformers too, and my spec output would no longer be spec output… so what you’re saying seems to agree my gut feeling
so one thing I’d quite like (for myself) is to write a variant of s/keys
and s/def
that uses URIs as keys instead of clojure keywords.
I work with RDF, so mapping to keywords just to spec something feels somewhat redundant, when the URI straight out of the database is basically the same thing so I’d like to basically save a redundant mapping and write:
(def rdfs:label (URI. "http://,,,/label"))
(rdf/def rdfs:label string?)
(rdf/keys :req [rdfs:label])
And have it do the same thing as keys. Is there an easy way to do this? Thinking I need to extend s/Spec
/`s/Specize` to URI
and then rewrite s/keys
? s/keys
looks pretty hairy, is there any easy way?
I think this is roughly how you would do this, yes, and it would not be super easy. Also, I expect some of that plumbing to possibly change soon.
I’m assuming there are no plans/proposals in the pipeline to let you plugin and you use arbitrary values as keys/keywords?
or am I thinking the thoughts of a madman?
I think what rich says about the design influence of RDF on clojure and spec is very clear; in many ways they’re almost identical. I’d basically like to reduce the friction of working in clojure with RDF… Also compare SHACL/SHEX to spec, they’re almost just different syntaxes for the same abstract model.