This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-12-21
Channels
- # adventofcode (24)
- # announcements (1)
- # beginners (122)
- # braveandtrue (9)
- # calva (45)
- # cider (24)
- # cljdoc (8)
- # cljs-dev (23)
- # clojure (112)
- # clojure-europe (2)
- # clojure-india (2)
- # clojure-italy (36)
- # clojure-nl (3)
- # clojure-spec (32)
- # clojure-uk (35)
- # clojurescript (52)
- # core-typed (12)
- # cursive (4)
- # datomic (61)
- # emacs (4)
- # figwheel-main (2)
- # fulcro (14)
- # hoplon (5)
- # hyperfiddle (1)
- # jobs-discuss (6)
- # kaocha (5)
- # leiningen (2)
- # nrepl (15)
- # off-topic (62)
- # re-frame (26)
- # reagent (39)
- # ring (3)
- # shadow-cljs (56)
- # spacemacs (8)
- # specter (5)
- # tools-deps (1)
- # yada (2)
anyway if your spec is a literal set, you could do
(s/def ::foo #{1 2 3})
(s/form ::foo)
=> #{1 3 2}
or you could define the set separately, and reference it from the s/def
and wherever you need to count
it
Is there a way to abstract over whether a key in a map is namespaced or not? In a certain context, as long as the value conforms, I want to accept both with the same spec.
If you’re using s/keys, the :req-un and :opt-un will do that
The guide does not really go into details on records, except that one can spec their fields/attributes: https://clojure.org/guides/spec
records don’t really have methods
they implement interfaces/protocols which define methods
currently, you can’t spec protocols or interface methods
and because of the calling implementation it’s not possible to instrument them (and probably not something we’re ever going to really do because of that)
but I wouldn’t completely rule it out
@alexmiller So I can spec neither the protocol for all its implementations, nor every record implementation individually?
But I could place the implementation in a function, which I could spec, and then from the record implementation just call that function? I.e. insert one step of indirection?
yes, but I wouldn’t do that just to be able to spec it
Well, right now my implementations look like (s/assert ...args...) (s/assert ...body...)
, which is hardly better...
this is a case where the impl of protocols (designed to tap into the highly optimized java/jvm calling semantics) is at odds with the dynamic indirection possible in Clojure via vars
I guess maybe there’s some possible future where newer Java capabilities like method handles could be used to implement this kind of thing
retaining most of the speed but also giving you the dev time instrumentation
So what do you do when during development you want to ensure that the maps returned from a method implementation of the record conform to a spec? And that all callers call it properly? Insert (s/assert arg-spec arg) (s/assert ...body...)
, like I did?
I don't really care if the call slows down by an order of magnitude, if it helps me in debugging where that borked data came from.
Or do you just split up the code in such small pieces that the method implementation in the record does not really do any significant work anymore, so you have enough functions that you can properly instrument?
I don’t think there is one canonical answer to that question, it depends on the code
splitting up code into smaller pieces is usually a good idea though