This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-04-19
Channels
- # announcements (3)
- # aws (1)
- # beginners (25)
- # calva (6)
- # cider (55)
- # clara (13)
- # cljs-dev (3)
- # clojure (79)
- # clojure-europe (1)
- # clojure-nl (6)
- # clojure-spec (59)
- # clojure-uk (6)
- # clojurescript (97)
- # clojureverse-ops (2)
- # cursive (7)
- # data-science (4)
- # datomic (12)
- # emacs (8)
- # figwheel-main (19)
- # fulcro (67)
- # graalvm (3)
- # graphql (12)
- # jobs (4)
- # jobs-discuss (11)
- # lein-figwheel (5)
- # off-topic (50)
- # om (1)
- # other-languages (1)
- # planck (3)
- # quil (2)
- # re-frame (4)
- # reitit (5)
- # remote-jobs (5)
- # ring-swagger (2)
- # shadow-cljs (34)
- # spacemacs (8)
- # xtdb (1)
- # yada (4)
I have a multi-spec for different query types to a service. I also want to dispatch on the query type to actually query the service
cause atm I have:
(defmulti query-type :type)
(defmethod query-type :view/id [_]
(s/keys :req-un [:content.query/id]))
(defmethod query-type :fragment/id [_]
(s/keys :req-un [:content.query/id]))
and then for implementation:
(defmulti query (fn [conn q] (:type q)))
(defmethod query :view/id
[{:keys [url]} {:keys [id]}]
{:url (str url "/view/" id)
:method :get
:as :json})
(defmethod query :fragment/id
[{:keys [url]} {:keys [id]}]
{:url (str url "/view/" id)
:method :get
:as :json})
and then I need to create a wrapper function so I can fdef the implementation, right?afaik spec does not work for multimethods, but you can declare implementation function(s), fdef it/them, and make your multimethod call it/them
it looks like multi-specs s/keys check all available keys, even when not specified?
s/keys does this
If you have a qualified key that matches a spec, it will be checked, whether it's specified in s/keys
or not.
this is documented in the s/keys docstring
@alexmiller just read your inside clojure. The api seems very global for closed specs. Have you given much thought to how it might be scoped?
Scope in what dimension?
It is very global, like instrumentation
Thinking of a web server with many concurrent requests where you want the closed spec on the boundary, but internally within processing the open spec may be used (as other sources are merged).
Interesting choice to turn off and on āclosednessā for specs. Would it make sense to combine this with select somehow?
Like (s/def ::closed-spec (s/select ::open-spec ...))
?
It should work with select too, I just havenāt done that yet. Thereās just a lot of copied code there at the moment
then, no :)
Closeness is intentionally not part of the spec language and wonāt be
Itās part of the api
but when you would like to use a spec in different ways, you would have to toggle this flag all the time?
Thatās the aspect weāre think about still
I guess you can just make a copy of the spec, like (s/def ::foo ::bar)
, but if you close bar, will foo also be closed?
Well thatās not a copy, itās an alias
@borkdude feels like working around the intentional limitation to make closed&open copies.
The answer is tricky, and may change
@alexmiller btw, why the global on/off switch? My reaction was that I'm going to see someone turning it on globally unconditionally in some project and removing the upside of open specs.
Do you just mean the no-arity version of close/open?
is s/valid? part of the spec language? why not make it an option to those functions?
s/valid? is api, not spec language
Still might do that. Breaks all existing APIs and specs though
It will break the protocol
Weāve also been thinking about a fast s/valid? path. Right now thatās tunneled through the conform* protocol, which does a lot of useless work if just validating. So that could also be a flag, or a separate protocol method
Those could all be flags internally on conform*
We are already in a new namespace, no need to number
But ideally could minimize breakage for some of those spec libs
Anyhow, what Iām interested in hearing now is how you would use it
We can work out the best answers from that
a fast s/valid? path would certainly help things like core specs which quickly become noticable in performance
Itās not going to be like 10x or anything
It really matters when you are constructing conformed outputs
I think the closedness aspect is something where people choose different tools or use workarounds for spec right now at API level things, like maybe Reitit and yada (which now uses Schema), but Iāll let those maintainers chime in
Like how often are you likely to use the same spec in both open and closed check modes on the same spec? And where different, is it per usage or per thread or per what?
@alexmiller I can imagine closed for the incoming boundary, open internally when merging additional internal data, and potentially closed again when sending it on to another consumer (e.g. A service which accepts too much or a database)
I'm not the maintainer of yada, but I'm influential there. For incoming web requests, I'm more interested in: - not checking extra keys - not seeing extra keys
My first reaction is: ugh, no! Mutable global state on spec behavior just feels horribly wrong. I could have a spec defined in one place and just looking at that and the uses of it no longer tells me whether extra keys are permitted or not, because any random code, anywhere in the system can toggle that setting :face_vomiting: š¤Æ š