This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-12-16
Channels
- # adventofcode (99)
- # announcements (2)
- # babashka (37)
- # beginners (111)
- # cider (4)
- # cljsrn (5)
- # clojure (51)
- # clojure-australia (2)
- # clojure-chicago (3)
- # clojure-europe (141)
- # clojure-nl (2)
- # clojure-provo (2)
- # clojure-spec (48)
- # clojure-sweden (2)
- # clojure-uk (26)
- # clojurescript (34)
- # conjure (1)
- # core-logic (5)
- # cursive (16)
- # datomic (2)
- # events (2)
- # fulcro (54)
- # graphql (13)
- # jobs-discuss (116)
- # kaocha (14)
- # meander (101)
- # off-topic (41)
- # pathom (6)
- # planck (3)
- # re-frame (53)
- # reagent (10)
- # reitit (1)
- # reveal (13)
- # shadow-cljs (35)
- # spacemacs (22)
Curious if there are any ideas around how spec2's select would allow for requiring deeply nested keys based on some dispatch function? e.g., (if the event is type "a" then a specific set of keys are required, if event type is "b" then ...)
@kenny if I understand correctly select is there to be used in specific contexts. Not sure if that answers your question.
No. Essentially I'm curious what the story is wrt deeply nested multi-spec and select since that is a common use case.
Can you explain?
Perhaps an example is best.
(s/def ::order (s/schema [:order/id
:order/type
:order/a
:order/b
:order/c]))
(s/def :user/orders (s/coll-of ::order))
(s/def ::user (s/schema [:user/orders]))
(s/select ::user [:user/orders {:user/orders [:order/id
:order/type
;; if :order/type is :order.type/a then require :order/a
]}])
The required order keys depend on the order's type.I’m curious (never used spec2) as well. My intuition is that you are trying to solve something with select when it should be a separate schema for order types. But I have to think about it/read a bit more 😄
Oh. Yes, that is possible here. It results in really bad error messages though (if you have a bad input, every single case of the or is outputted). multi-specs output a really nice error.
have you tried to parse explain-data to kind of narrow it down? just talking off my ass here
You can manipulate the output however you normally would 🙂 The thing is, multi-specs solve this problem nicely (albeit a bit cumbersome to work with). They just don't work with select, and it seems that there is a good fit for something there.
So I was curious if there were any thoughts on how/if something like this would be a part of spec2. For us, this use case happens everywhere.
since select is just a spec too, then you would dispatch with a multimethod too right?
so it would be something like (defmulti order-type :order/type...
The main thing is that you always declare required keys "top-level." Pretty sure what you have there wouldn't work :thinking_face:
No matter the "level" (read nesting) you're at, you're always able to select which keys are required.
(s/def ::order (s/schema [::order-id
::order-type
::order-a
::order-b
::order-c]))
(s/def ::orders (s/coll-of ::order))
(defmulti order-type ::order-type)
(defmethod order-type ::order.type-a [_]
(s/select ::order [::order-a]))
(defmethod order-type ::order.type-b [_]
(s/select ::order [::order-b]))
(s/def ::order-typed (s/multi-spec order-type ::order-type))
(s/valid? ::order-typed {::order-type ::order.type-b ::order-b "foo"})
(s/def ::orders-typed (s/coll-of ::order-typed))
(s/valid? ::orders-typed [{::order-type ::order.type-b ::order-b "foo"}])
At the level of the "user" map, I want to select what keys are required in each map under :user/orders.
i have to leave it at that (it’s late) but was fun so far. maybe someone actually knowledgeable can find a better way
Not sure what you mean exactly 🙂 This is what I'd like.
(s/select ::user [:user/orders {:user/orders [:order/id
:order/type
;; if :order/type is :order.type/a then require :order/a
]}])
What I mean is that I’m still a beginner with these things. I don’t really see a solution right now other than dispatching the select and conform/validate on the select spec.
Oh, I understand. Yes, I was 99% certain spec2 does not cover this. I am interested in thoughts on this particular problem and how spec2 might solve it.
i mean this sound pretty powerful (from the wiki): https://github.com/clojure/spec-alpha2/wiki/Differences-from-spec.alpha#creating-specs-programmatically
For sure! I'm confident something could be built to solve this (likely even in spec1). Curious if this use-case is in scope for spec2 though. It seems like a core problem.
Two things here - first selects do not currently have the ability to handle maps of colls of maps of ... , only nested maps. That is something we are thinking about though as it is very common. Second, there is not currently any way to indicate any sort of predicate or condition on the nested data like you're talking about but that is something we're thinking about. What you're asking for might be beyond where we end up though, not sure yet.
select is currently only about nested map structures (what keys are provided at each level)
> there is not currently any way to indicate any sort of predicate or condition on the nested data like you're talking about but that is something we're thinking about. This sounds exactly like what I'm after 🙂 This is such a big issue for us I may need to tackle it internally for now. Would love to know what those thoughts are. Though, I assume they are not public yet?