Clojure Koans 7 Functions Notebook
Finally, I can unlock the power of functional programming...
... Actually, we've been using functions since day 1! 😉
Spoilers alert: Don't forget to try these Koan exercises on your own first, since I am sharing my answers.
Initial Thoughts
The (purpose & function of) syntax of wrapping functions in a 2nd set of parentheses is not clear to me. My questions could be more specific to elicit helpful responses. I believe I am missing a bunch of useful and related function skills.
{: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)}
(defn multiply-by-ten [n]
(* 10 n))
(defn square [n] (* n n))
;; "Calling a function is like giving it a hug with parentheses"
(= 81 (square 9))
;; skill 7001: Invoke a function
;; skill 7002: Invoke a function with one argument passed to it
;; "Functions are usually defined before they are used"
(= 20 (multiply-by-ten 2))
;; skill 7003: Invoke a custom (developer-written) function
;; "But they can also be defined inline"
(= 10 ((fn [n] (* 5 n)) 2))
;; skill 7004: Define and invoke an inline function
;; question 7001: What is the function of wrapping a function in a 2nd set of parentheses?
;; "Or using an even shorter syntax"
(= 60 ((* 15 %) 4))
;; skill 7005: Define and invoke an inline function with the alternate shorter syntax (?)
;; question 7002: Is there a commonly accepted name/label for this shorter syntax (`#(%)`), and if so, what is it?
;; "Even anonymous functions may take multiple arguments"
(= 15 ((+ %1 %2 %3) 4 5 6))
;; skill 7006: Define and invoke an inline function w/ alt. shorter syntax (?)
;; "Arguments can also be skipped"
(= "AACC" ((str "AA" %2) "bb" "CC"))
;; skill 7007: Invoke a function where not all arguments are used
;; skill 7008: Access function parameters by their index number (%1, %2, ...)
;; question 7003: When is skipping arguments a helpful / useful technique?
;; "One function can beget another"
(= 9 (((fn [] +)) 4 5))
;; question 7004: What is happening here?
;; question 7005: How can this function be described in plain words?
;; question 7006: What are the differences between `(((fn [] +)) 4 5)` and `(#(apply + %&) 4 5)`?
;; skill 7009: Wrap a function in an extra set of parenthesis to return the function itself (?)
;; "Functions can also take other functions as input"
(= 20 ((fn [f] (f 4 5))
*))
;; question 7007: How can this function be described in plain words?
;; skill 7010: Define a (higher order) function which takes another function as an argument
;; skill 7011: Pass a function as an argument to another function
;; "Higher-order functions take function arguments"
(= 25 ((% 5)
(fn [n] (* n n))))
;; question 7008: Did I answer this in the most correct way?
;; question 7009: How can I easily check the top/ideal answer for Clojure Koans?
;; question 7010: What are some good examples of custom higher-order functions?
;; skill 7012: Write an inline/anonymous higher-order function that takes another inline/anonymous function as an argument.
;; "But they are often better written using the names of functions"
(= 25 ((% 5) square))
;; skill 7013: Write an inline higher-order function that takes a function reference as an argument.
Extra Content
The skills, questions, and code below have no particular Koan exercise to attach to in this notebook. I am including them here though because I believe they fall under this notebook's theme/scope/focus. Please look forward to more skills, questions, and code examples in the coming days and weeks.
;; skill 7014: Invoke a function with no arguments passed to it