This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-07-04
Channels
- # announcements (10)
- # asami (6)
- # babashka (22)
- # beginners (44)
- # biff (1)
- # calva (8)
- # clj-kondo (13)
- # clojure (62)
- # clojure-art (1)
- # clojure-europe (27)
- # clojure-nl (1)
- # clojure-norway (19)
- # clojure-spec (19)
- # clojure-uk (2)
- # component (29)
- # datascript (1)
- # fulcro (9)
- # gratitude (2)
- # kaocha (6)
- # klipse (1)
- # luminus (16)
- # malli (9)
- # nbb (5)
- # off-topic (4)
- # reagent (5)
- # shadow-cljs (85)
- # spacemacs (1)
- # tools-deps (10)
- # vim (9)
- # xtdb (2)
Hey.
Is there a good way to spec an atom
that has a list of functions? 😄 Is there at least a way to spec an atom?
Ah, I see. Thanks.
e.g.
(s/def ::fns (s/coll-of ifn?))
(s/def ::my-atom
(s/and (s/conformer
#(if (instance? clojure.lang.Atom %)
@%
::s/invalid))
::fns))
(s/valid? ::my-atom (atom [dec identity inc])) ; => true
maybe this use of conformer
is not idiomatic. tbh I’m not sure what’s an idiomatic use of conformer
I think this is not idiomatic, because spec is a “library [that] specifies the structure of data” (as per https://clojure.org/guides/spec), and atoms are state, not data
I think I'll not do it.
Atoms are stateful containers of data. It often makes a lot of sense to spec atoms, especially if they're a highly structured central data store for your application – similar to having a formal schema for a database. The atom
function even has an option for including a validator, which could be built on spec (though be mindful of performance and consider making it no-op in prod).
https://clojuredocs.org/clojure.core/atom#example-567add80e4b01f598e267e8f
A naive (in the sense that it doesn't check function signatures) spec for a list of functions might be (s/* ifn?)
In the core.specs, isn't ::map-special-bindings
always going to be a subset of ::map-bindings
? how would ::map-special-bindings
spec ever be used given that it's only part of :map-binding-form
spec which is defined as (s/def ::map-binding-form (s/merge ::map-bindings ::map-special-binding))
https://github.com/clojure/core.specs.alpha/blob/master/src/main/clojure/clojure/core/specs/alpha.clj#L29-44
https://clojure.wladyka.eu/posts/form-validation/#trick-about-mirroring-s-def-and-via
here is use case showing the difference (s/def ::created ::instant)
vs (s/def ::created (s/and ::instant))
I don’t know the exact code which you are asking, but I know the difference between this too
I'm not sure I understand your answer, do you mean the intention might just be to produce better error messages?
I mean without s/and
you miss the information about the full path, because it cut corners to make path simpler
ok, although there's no and
involved in the code I linked to (clojure.core.spec.alpha), it's a merge of a spec map-bindings
with another map-special-binding
after double checking it seems to me like the only point of map-special-binding
is to keep the map-binding-form
spec open to new keywords