Clojure Koans 27 Multimethods Notebook

Original Clojure Koans: https://github.com/functional-koans/clojure-koans/

Please note there are spoilers for the Clojure Koans below.

{:deps {org.clojure/clojure {:mvn/version "1.10.1"}
        ;; complient is used for autocompletion
        ;; add your libs here (and restart the runtime to pick up changes)
        compliment/compliment {:mvn/version "0.3.9"}}}
deps.edn
Extensible Data Notation
{:hello (clojure-version)}
0.1s
Clojure

Initial Thoughts

Wait a tic... Wasn't the Clojure Koans 10 Runtime Polymorphism Notebook all about multi-methods? That said, I'm seeing new syntax here, so let's dive in and see what we can learn!

(defmulti multimethod-without-args
    (fn [keyword-arg] keyword-arg))
;; note: This appears to be some sort of identity function...
;; question 27011: What exactly is going on here?
(defmethod multimethod-without-args :first [_]
    (str "Hello, World!"))
(defmethod multimethod-without-args :second [_]
  (str "Hello there"))
;; note: The two defmethods above seem to ignore passed arguments..
;; question 27012: What exactly is going on here?
Clojure
(defmulti multimethod-with-args
  (fn [opt-one opt-two] opt-one))
;; note: This multimethod seems to always return a function that always returns the first of two arguments...
;; question 27013: What exactly is going on here?
(defmethod multimethod-with-args :path-one [_ opts]
    (:first-opt opts))
;; question 27014: What exactly is going on here?
(defmethod multimethod-with-args :path-two [_ opts]
    (let [numbers (:second-opt opts)]
        (->> numbers
             (map inc)
          (reduce +))))
;; question 27015: What exactly is going on here?
(defmethod multimethod-with-args :path-three [_])
;; question 27016: What exactly is going on here?
Clojure
;; "A multimethod takes one or more arguments to dispatch on"
(= "Hello, World!"
   (multimethod-without-args :first))
;; question 27001: What is the function/role/term for the keyword following a defmethod's identifier/name?
;; question 27002: Why is it called "multimethod-without-args"? It seems to take arguments, at least, sometimes (see the underscore on this line `(defmethod multimethod-without-args :first [_]`)?
;; question 27003: What exactly does it mean for a multimethod "to dispatch on" arguments? Please show simple, clear examples, ideally in context. 
;; question 27004: What is a "multimethod" in Clojure? 
;; question 27005: What are the similarities and differences between multimethods and multi-arity functions?
Clojure
;; "Though it can be ignored and represented by _ in defmethods"
(= "Hello there"
   (multimethod-without-args :second))
;; question 27006: What is the significance/function/role of the underscore character/symbol "_" (?) in defmethods?
;; question 27007: What exactly can be ignored and represented by "_"? (What is "it" referring to above?)
Clojure
;; "Alternatively, we can use the arguments in defmethods"
(= 1
   (multimethod-with-args :path-one {:first-opt 1
                                     :second-opt 2}))
;; question 27008: What do "opt" and "opts" stand for, "options"?
Clojure
;; "This allows us to do something different in each method implementation"
(= 6
   (multimethod-with-args :path-two {:first-opt 1
                                     :second-opt [0 1 2]}))
;; question 27009: What are some helpful/practical use cases for multimethods?
;; question 27010: What are the pros/cons/tradeoffs of multimethods?
Clojure

Closing Thoughts

It's pretty crazy to me that I'm already at the end of the Clojure Koans. I still have so much to learn.

For the future:

  • [ ] Confirm questions answered in Notebook #10

  • [ ] Highlight meaningful differences between this and Notebook #10

Runtimes (1)