Avi Drucker / May 04 2021
Remix of Clojure by
Nextjournal
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