This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-05-17
Channels
- # aws (16)
- # beginners (82)
- # boot (29)
- # cider (43)
- # cljs-dev (90)
- # cljsrn (14)
- # clojure (79)
- # clojure-dev (12)
- # clojure-greece (4)
- # clojure-italy (12)
- # clojure-russia (81)
- # clojure-shanghai (1)
- # clojure-spec (39)
- # clojure-uk (28)
- # clojurescript (159)
- # consulting (1)
- # cursive (16)
- # data-science (6)
- # datomic (18)
- # devops (3)
- # emacs (22)
- # figwheel (1)
- # graphql (15)
- # hoplon (3)
- # jobs (1)
- # jobs-discuss (8)
- # leiningen (1)
- # luminus (6)
- # lumo (1)
- # off-topic (18)
- # om (6)
- # onyx (38)
- # pedestal (30)
- # perun (3)
- # re-frame (38)
- # reagent (8)
- # ring-swagger (2)
- # rum (2)
- # sql (2)
- # unrepl (14)
- # untangled (1)
- # vim (8)
is there a way to in-line this: (s/def ::a integer?) (s/keys :req-un [::a]) so that I can state I expect ::a in the map that should be checked against integer? without having to specify ::a first?
@chillenious no, you could write a macro to do something like (my-keys :req-un [(::a integer?)])
that expands to it
ok, thx
@chillenious that's by design, see https://clojure.org/about/spec - Map specs should be of keysets only
Yeah, I was afraid you were going to say that 🙂 I can't be the first one who thinks that that's a PITA though. I very often have the situation where I'd like to use a different key from the 'type'.
chillenious: something like this? https://github.com/metosin/spec-tools/blob/master/README.md#data-specs
Yes! Thanks!
That looks great, will try it out later this week.
@chillenious I encourage you to avoid this, there are many reasons for spec to encourage doing things in the way it does, to encourage you to have value definitions and just make compositions out of it, if you start thinking on your data as records you gonna lose a lot of the benefits on the long run, I recommend watching this presentation from Rich, where he talks a lot about the grand ideas and why things are the way they are: https://vimeo.com/195711510
I'll look at it, thanks. I'm using this as part of test code where I want some validation and documentation as to what data structures can/ should be used. So it's as important to me that it is easy to read and terse, and doesn't have to be a perfect water tight solution for all things spec 🙂
hello 🙂
I noticed when a spec is created with (s/with-gen)
it loses track of the original form:
(s/def ::some-spec (s/with-gen int? #(s/gen int?)))
=> :user/some-spec
(s/form ::some-spec)
=> :clojure.spec.alpha/unknown
but doing it using the (s/def (s/spec int? :gen #(s/gen int?)))
works fine
(s/def ::other-spec (s/spec int? :gen #(s/gen int?)))
=> :user/other-spec
(s/form ::other-spec)
=> clojure.core/int?
is this expected?
there’s a patch pending to fix this
There was a question last year about speccing a binary tree:
(def BinaryTree
(maybe ;; any empty binary tree is represented by nil
{:value long
:left (recursive #‘BinaryTree)
:right (recursive #‘BinaryTree)}))
@alexmiller: you told Andrey Grin :“Yes, you can create recursive definitions by registering a spec that refers to itself via registered name (a namespaced keyword).“. I can’t find a way to do it, could please post a snippet of code ?
Relevant message: https://groups.google.com/forum/#!topic/clojure/5sZdCPQgZz4%5B1-25%5D
(s/def :bt/value number?)
(s/def :bt/left (s/nilable :a/bt)) ;;<- recursive
(s/def :bt/right (s/nilable :a/bt)) ;;<- recursive
(s/def :a/bt
(s/nilable
(s/keys
:req-un [:bt/value]
:opt-un [:bt/left :bt/right])))
(s/explain :a/bt
{:value 1
:left {:value 21 :right {:value 31}}
:right {:value 22 :left {:value 32 :right {:value 4} :left {:value 33}}}})
Success!
=> nil
s/exercise
, however, stackoverflows at different points, so might need to tinker with that.
(binding [s/*recursion-limit* 2]
(map first (s/exercise :a/bt 3)))
=>
({:value -1.0, :right {:value -1}, :left nil}
{:value -1,
:left {:value -3.0, :left {:value -1, :right {:value 0.75}}},
:right {:value 0}}
{:value 0})
@alexmiller I was having this idea yesterday, about spec hierarchy tracking, currently when you define a spec from another (eg: (s/def ::something ::other-thing)
) the resolving happens on definition time, I understand that is preferable for performance reasons, but doing that makes us lose track of the hierarchy. I was implementing a coerce engine on top of spec, and I miss having this hierarchy information, so I was thinking that we could have Clojure hierarchy for the specs, so when defining those we do a derive on those keywords, so we would have this information aside available for use, do you think this is a reasonable feature to have on spec?
I don’t know about all that. there are some open tickets about the resolution aspects that I expect will be addressed.
it is not the intent that you lose that tracking now
for example, given the following specs:
(s/def ::a int?)
(s/def ::b ::a)
(s/def ::c ::b)
is there a way, starting from ::c
to know that it is derived from ::b
and ::a
?
(s/get-spec ::c)
should tell you ::b
but things like https://dev.clojure.org/jira/browse/CLJ-2067 and https://dev.clojure.org/jira/browse/CLJ-2079 make me think that not everything is exactly right in this area
interesting, I didn't knew that get-spec
would do that, and testing with the previous example works
glad to hear that my assumptions were wrong on this
thanks Alex