Share your thoughts in the 2020 Clojure Community Survey!

Welcome! Please see the About page for a little more info on how this works.

0 votes
in Clojure by

Consider this example

`
user=> (defprotocol Foo (foo [x] x))
Foo
user=> (defrecord Bar [gaz waka] Foo)
user.Bar
user=> (def bar (Bar. 1 2))

'user/bar

user=> (.foo bar)

AbstractMethodError user.Bar.foo()Ljava/lang/Object; sun.reflect.NativeMethodAccessorImpl.invoke0 (NativeMethodAccessorImpl.java:-2)
user=>
`

What about the default implementation.

4 Answers

0 votes
by

Comment made by: mobiusinversion

As it stands you have to workaround with this

http://stackoverflow.com/questions/15039431/clojure-mix-protocol-default-implementation-with-custom-implementation

0 votes
by

Comment made by: wagjo

I don't think we need it. What's the rationale behind extending some protocol, not implementing its methods, and then calling those methods, expecting them not to throw. Be explicit about what yout type should do, whether it is a default or custom behavior. You basically have three options

`
(defn default-foo
[this]
:foo)

(defprotocol P
(-foo [this]))

(deftype T
P
(-foo [this] (default-foo))

(defn foo
[x]
(-foo x))
`

or

`
(defprotocol P
(-foo [this]))

(deftype T)

(defn foo
[x]
(if (satisfies? P x)

(-foo x)
:foo))

`

or

`
(defprotocol P
(-foo [this]))

(extend-protocol P
java.lang.Object
(-foo [this] :foo))

(deftype T)

(defn foo
[x]
(-foo x))
`

I think however that my first approach is unidiomatic and you should prefer the latter ones.

0 votes
by

Comment made by: mobiusinversion

I agree, this is a low priority enhancement. I think it could make the Protocol experience more DWIMy, and Java 8 has default implementations on interfaces for the same kind of convenience.

0 votes
by
Reference: https://clojure.atlassian.net/browse/CLJ-1563 (reported by alex+import)
...