Clojure Koans 10 Runtime Polymorphism* Notebook
Original Clojure Koans: https://github.com/functional-koans/clojure-koans/
Spoilers Alert
*2021_05_04 Update: According to a Clojure developer friend of mine, there is no "runtime polymorphism" going on in this notebook... So... What exactly is runtime polymorphism, and how can I consistently accurately identify it when I see it? And what is going on here (instead of runtime polymorphism)?
{: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"}}}{:hello (clojure-version)}Initial Thoughts
I learned about polymorphism formally first in school, in context of Object Oriented Programming ("OOP"). It'll be an interesting, fun, & engaging endeavor for me to pick apart what makes polymorphism without classes or objects.
2021_04_28 Update: With the help of my friends over at Brave Clojurians, I've been fortunate to have some questions answered, and a few new questions raised.
(defn hello ([] "Hello World!") ([a] (str "Hello, you silly " a ".")) ([a & more] (str "Hello to this group: " (apply str (interpose ", " (cons a more))) "!")));; question 10010: How would a tiny example of defmulti and defmethod look without any multi-arity functions?;; answer 10010a: See `needs-food` example down below(defmulti diet (fn [x] (:eater x)))(defmethod diet :herbivore [a] (str (a :name) " eats veggies."))(defmethod diet :carnivore [a] (str (a :name) " eats animals."))(defmethod diet :default [a] (str "I don't know what " (a :name) " eats."));; ~~question 10001: What are the similarities and differences between defn, defmulti, defmethod, and multi-arity methods?~~;; answer 10001a: Marking this as a little too vague and big to answer simply for now.;; question 10002: Multimethods are useful for what?;; answer 10002a: Multimethods are useful for, "dispatching on types, values, attributes and metadata of, and relationships between, one or more arguments" reference: https://clojure.org/reference/multimethods;; answer 10002b: Multimethods are useful for implementing essentially what is conditional logic without needing to write branching code such as if, case, or cond. A simple, concrete example of this is the bunny-lion example code here: https://clojure.org/about/runtime_polymorphism !!!;; question 10003: What is the purpose/intent/function behind the keyword that follows a function identifier (?) above such as "defmethod diet :herbivore";; answer 10003a: This is the "dispatch value.";; answer 10003b: Clearer answer TBD...;; question 10004: Might these be examples of "rules" that Rich Hickey mentioned in his talked "Simple Made Easy"?;; answer 10004a: This question Subjective, and opinionated... Why not ask directly?;; skill 10001: Define a custom multi-method;; "Some functions can be used in different ways - with no arguments"(= "Hello World!" (hello));; skill 10002: Invoke/Call a function with no arguments.;; note: skill 10002 may be duplicated in another notebook, TODO: confirm this is a unique skill;; "With one argument"(= "Hello, you silly world." (hello "world"));; skill 10003: Invoke/Call a function with one argument.;; note: skill 10003 may be duplicated in another notebook, TODO: confirm this is a unique skill;; "Or with many arguments"(= "Hello to this group: Peter, Paul, Mary!" (hello "Peter" "Paul" "Mary"));; skill 10004: Invoke/Call a function with multiple arguments.;; "Multimethods allow more complex dispatching"(= "Bambi eats veggies." (diet {:species "deer" :name "Bambi" :age 1 :eater :herbivore}));; question 10005: What is "dispatching" as refered to above?;; question 10006: What exactly is a multi-method?;; "Animals have different names"(= "Thumper eats veggies." (diet {:species "rabbit" :name "Thumper" :age 1 :eater :herbivore}));; "Different methods are used depending on the dispatch function result"(= "Simba eats animals." (diet {:species "lion" :name "Simba" :age 1 :eater :carnivore}));; "You may use a default method when no others match"(= "I don't know what Rich Hickey eats." (diet {:name "Rich Hickey"}));; question 10007: What does runtime polymorphism do, put simply?;; question 10008: What would be a simple comparison example of runtime polymorphism versus non-runtime polymorphism?;; question 10009: What are the pieces/elements/parts of "polymorphism a la carte"?Closing Thoughts
At the risk of sounding like a broken record, I'm struck by a sense of, "There must be much more going on behind the scenes." with Clojure, and in particular today, multimethods. I hope to have more insight into reading stack traces, and understanding how Java is used (for starters) to power (scaffold the functionality of) Clojure.
Room For Improvement
[ ] Compile a list of all skills, questions, descriptions, etc. into one GitHub document or Google Sheets for collaboration
[ ] Compile all suggestions/fixes as issues on single GitHub document
;; question 10011: What would be a super small simple problem be that could be solved by **both** `defmethod`+`defmulti` as well as `if`;; answer 10011a: See code below.(defmulti needs-food (fn [person] (:is-hungry person))) ;; dispatching-function(defmethod needs-food true [person] "This person needs food.");; defmethod identifier-symbol dispatching-value(defmethod needs-food false [person] "This person doesn't need food.")(def steve {:is-hungry true})(def joe {:is-hungry false})(needs-food steve)(needs-food joe)(defn needs-food-if [person] (if (:is-hungry person) "This person needs food." "This person doesn't need food."))(needs-food-if steve)(needs-food-if joe);; question 10012: Where do defmulti+defmethod really shine as useful/helpful constructs? ;; question 10013: Please describe this example in plain words: https://clojuredocs.org/clojure.core/defmethod#example-542692c7c026201cdc3269cb[ ] TODO: Parse this page for more skills and questions: https://clojuredocs.org/clojure.core/defmethod
[ ] TODO: Parse and distill syntax composition: https://blog.frankel.ch/learning-clojure/3/
[ ] TODO: Add awesome example "add" function from here: https://stackoverflow.com/questions/12872513/how-and-why-is-defmulti-and-defmethod-used-and-what-are-the-advantages/12872943
[ ] TODO: Create visual (venn diagram perhaps) here for awesome breakdown of difference between method overloading and multimethods: https://cs.stackexchange.com/questions/4660/difference-between-multimethods-and-overloading?newreg=e014ec9730a64db38d4f971ab14e77d9
[ ] TODO: Attempt to linguistically parse this https://clojure.org/reference/multimethods to create a simple-to-complex, comprehensible breakdown & demo
[ ] TODO: Break down examples here: https://stackoverflow.com/questions/28995474/can-the-dispatch-values-of-a-clojure-multimethod-be-queried
[ ] TODO: Analyze and break down: https://stackoverflow.com/questions/28961343/clojure-multimethod-with-multiple-dispatch-values