This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-07-16
Channels
- # aleph (4)
- # bangalore-clj (10)
- # beginners (39)
- # boot (24)
- # cljs-dev (66)
- # cljsrn (79)
- # clojure (39)
- # clojure-italy (7)
- # clojure-russia (6)
- # clojure-spec (4)
- # clojure-uk (1)
- # clojurescript (91)
- # core-async (1)
- # core-typed (2)
- # datomic (49)
- # hoplon (42)
- # lumo (2)
- # nyc (1)
- # off-topic (1)
- # parinfer (20)
- # pedestal (2)
- # reagent (4)
- # rum (14)
- # vim (2)
what’s the proper way to spec protocols? i’m assuming I can just spec some client fn instead of the protocol? but I’m having a conceptual issue about how to have multiple implementations of the protocol with this approach:
;; protocols.cljs
(defprotocol IMyProto
(-foo [this v]))
;; client.cljs
(defn foo [this v]
(protocols/-foo this v))
;; impl-A.cljs
(defrecord AImpl []
IMyProto
(-foo [this v] ...))
(defn foo [this v] (-foo this v)) ;; this is the fn I would instrument for A types
;; impl-B.cljs
(defrecord BImpl []
IMyProto
(-foo [this v] ...))
(defn foo [this v] (-foo this v)) ;; this is the fn I would instrument for B types
in client.cljs
I want to be able to call protocols/foo
instead of prototols/-foo
, because I can instrument (defn foo...)
. But this breaks the purpose of a protocol - how do I know which implementation to invoke from the client a-impl/foo
or b-impl/foo
?
What’s the proper way to organize these guys so I can stest/check 'foo
?I suppose I could turn it on its head so that client calls always invoke (protocols/foo this v)
, and each impl points to an internal function IMyProto (foo [this v] (-foo this v))
? But this doesn’t seem friendly, particularly once the records start having fields and if any protocol fn needs to refer back to those fields.
*or perhaps I should re-apply s/fdef
to the protocol’s foo
when I actually want to run my checks? (s/fdef protocols/foo ::args (s/cat :type ::a-type)
, then re-def with ::b-type
?
Protocols are open for extension -- so you can't write a spec for all possible argument types. I think you could write a multi-spec for foo
-- where the defmulti
discriminator function returns the type
of the first argument?