Cover by Brian Carper, Christophe Grand, Chas Emerick

Safari, the world’s most comprehensive technology and business learning platform.

Find the exact information you need to solve a problem on the fly, or go deeper to master the technologies and skills you need to succeed

Start Free Trial

No credit card required

O'Reilly logo

A Few More Things

Multiple Inheritance

Our running fill example doesn’t have a hierarchy complex enough to introduce multiple “inheritance.” Such relationships arise frequently when you have multimethods dealing with interfaces.

Let’s say we want a run function that can execute anything vaguely runnable (like java.lang.Runnable and java.util.concurrent.Callable):

(defmulti run "Executes the computation." class)

(defmethod run Runnable
  [x]
  (.run x))

(defmethod run java.util.concurrent.Callable
  [x]
  (.call x))

Let’s test it on a function:

(run #(println "hello!"))
;= #<IllegalArgumentException java.lang.IllegalArgumentException:
;=   Multiple methods in multimethod 'run' match dispatch value:
;=     class user$fn__1422 -> interface java.util.concurrent.Callable and
;=                            interface java.lang.Runnable, and neither is preferred>

The exception is pretty self-explanatory: since Clojure functions implement both Runnable and Callable, the multimethod doesn’t know which implementation to pick and hints that one should be preferred.

Preferences are expressed through the prefer-method function. This function expects three arguments: the multimethod considered and two dispatch values, the first being the one that should be preferred over the second:

(prefer-method run java.util.concurrent.Callable Runnable)
;= #<MultiFn clojure.lang.MultiFn@6dc98c1b>
(run #(println "hello!"))
;= hello!
;= nil

Now the multimethod knows which implementation to pick, to prefer, and runs without problem.

This preferences mechanism ...

Find the exact information you need to solve a problem on the fly, or go deeper to master the technologies and skills you need to succeed

Start Free Trial

No credit card required