This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-04-20
Channels
- # announcements (10)
- # architecture (7)
- # babashka (49)
- # beginners (125)
- # calva (2)
- # chlorine-clover (33)
- # clj-kondo (15)
- # cljs-dev (18)
- # cljsrn (28)
- # clojure (91)
- # clojure-argentina (37)
- # clojure-austin (4)
- # clojure-dusseldorf (1)
- # clojure-europe (3)
- # clojure-france (2)
- # clojure-germany (2)
- # clojure-nl (4)
- # clojure-portugal (4)
- # clojure-spec (26)
- # clojure-uk (19)
- # clojuredesign-podcast (5)
- # clojurescript (19)
- # conjure (20)
- # core-async (4)
- # cursive (60)
- # data-science (4)
- # datomic (1)
- # duct (9)
- # emacs (11)
- # events (1)
- # fulcro (9)
- # graalvm (17)
- # jobs-discuss (7)
- # luminus (19)
- # malli (36)
- # meander (2)
- # off-topic (23)
- # pathom (2)
- # quil (1)
- # rdf (4)
- # re-frame (16)
- # reitit (10)
- # ring (21)
- # ring-swagger (1)
- # shadow-cljs (137)
- # spacemacs (10)
- # sql (27)
so I am reading docs and I am sure I will figure this out too, but someone could help me here a lot with a shortcut to speccing a hashmap that has 3 levels, the first is a fixed set of keys, second also a fixed set of keys, and the third is depending on the key either a string or a vector of keywors. so a valid example would be {:firstlevelkey {:label "string" :fields [:fieldone :fieldtwo]}} and I just want to say that on the first level only certain keys are allowed( one predefined set of keywords), second level always have to be both a :label and :fields and label always have to be string and the :fields always needs to be a vector of keywords from another set of predefined keys
i don't need a full solution, just tell me please what to use so I can read up on those specifics because it's taking forever to sieve through 🙂
> I just want to say that on the first level only certain keys are allowed
This isn't something Spec favors -- it follows the concept of "open for extension". So you will need additional predicates with s/and
to restrict keys (and remember that it's not really "idiomatic" to do that).
The whole spec is going to end up looking something like this:
(s/def :key/label string?)
(s/def :field/keys #{:fieldone :fieldtwo ,,,}) ; your set of predefined keys allowed
(s/def :key/fields (s/coll-of :field/keys :kind vector?)) ; maybe you want min and/or max counts too?
(s/def :second/level (s/keys :req-un [:key/label :key/fields]))
(s/def :top/keys #{:firstlevelkey ,,,}) ; available top-level keys
(s/def :top/level (s/map-of :top/keys :second/level))
If your set of keys isn't known at spec-time, it's a bit harder but that's probably a good first cut outline to start with.
(with better names, of course)
That actually solved the restricted set of top-level keys, but at the expense of not requiring a minimum set either.
the naming of keywords is arbitrary, right? so I could do just :label instead of :key/label, it just pays off to have very specific names of symbols so there is no collision?
Right. Qualified names help avoid collisions.
Only s/keys
cares -- :req-un
treats the qualified names as just their unqualified part (`:req` would pay attention to the qualifier as well).
one more question that I think I know the answer for but still, if I want to spec anything, I always have to give a name to both the thing I want to spec and either use the definitions in place or create a named spec, right? So there is no way to write specs that would fit existing names automatically.
I'm not quite sure I'm following your question but I think the answer is "no, no way to do that in Spec 1".
Spec 2 does allow unqualified keys in a schema to have inline specs (predicates).
in app namespace I define something like (def whatever "string") and then in app.specs namespace I say (s/def whatever string?) and there is some magic to match them
Specs are in a completely separate "space" from regular Var names so you need to associate them yourself explicitly.
With functions, that's s/fdef
but there's nothing for other Vars.
You need to use s/valid?
or s/conform
to "apply" a spec to a value at runtime.
(does that answer your question?)