Clojure Koans 8 Conditionals Notebook

Welcome to my 8th notebook on the Clojure Koans :)

Please note there are spoilers below, so try to solve the Koans yourself first!

Now, if you please...

{: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.0s
Clojure
(ns koans.08-conditionals
  (:require [clojure.test :as test]))
;; note: this cell of code was added in order to find out whether or not we can determine programmatically whether something is a function or not
;; skill 8011: Add a library as a dependency for your current namespace by using the `:require` keyword in the `ns` namespace macro @ https://github.com/clojure/clojure/blob/clojure-1.10.1/src/clj/clojure/core.clj#L5764
0.1s
Clojure

Initial Thoughts:

I expected things to be iffy... I'm sorry, I couldn't help but to pun haha!

`case` and `cond` seem quite similar... Implicit returns abound, I'd like to see additional code examples with practical, real-world context (assuming the Koan exercises here are focused more on syntax and basic conditional functionality first).

(defn explain-exercise-velocity [exercise-term]
  (case exercise-term
    :bicycling        "pretty fast"
    :jogging          "not super fast"
    :walking          "not fast at all"
    "is that even exercise?"))
;; skill 8001: Write a `case` macro with a non-nil implicit else return value without writing ":else"
;; skill 8002: Look up a definition of a core macro/function
;; question 8006: Why use the `case` macro rather than the `cond` macro?
;; research 8006: https://reshmeeauckloo.wordpress.com/2015/12/13/clojure-if-cond-case/ https://clojure.org/guides/learn/flow http://taoofcode.net/cond-and-friends/
;; answer 8006a: "cond is a series of tests and expressions. Each test is evaluated in order and the expression is evaluated and returned for the first true test. If no test is satisfied, nil is returned. A common idiom is to use a final test of :else. Keywords (like :else) always evaluate to true so this will always be selected as a default." vs "case compares an argument to a series of values to find a match. This is done in constant (not linear) time! However, each value must be a compile-time literal (numbers, strings, keywords, etc). Unlike cond, case will throw an exception if no value matches. case can have a final trailing expression that will be evaluated if no test matches." @ https://clojure.org/guides/learn/flow
0.0s
Clojure
;; "You will face many decisions"
(= :a (if (false? (= 4 5))
        :a
        :b))
;; skill 8003: Use an if to branch on a boolean condition
;; question 8001: What is a "special form" in Clojure?
;; answer 8001a: Firstly, read this to get an overview: https://clojure.org/reference/special_forms
;; answer 8001b: Secondly, read this to get another high level blurb: https://clojure.org/reference/evaluation
;; answer 8001c: Thirdly, it may be helpful to ask the following, "What do I need to understand about special forms in Clojure? Further, when? For example; As a person new to Clojure, an entry-level engineer, or a Clojure master? What kinds of applications/problem spaces require a deeper understanding of Clojure special forms?", follow-up TBD...
;; question 8002: How do special forms in Clojure differ & relate to functions and macros?
;; answer 8002a: Not sure yet how to answer this... I think this question may be too vague, big, or complex to be answered by me just yet. For starters, I'd guess though that these are all expressions, because everything in Clojure is an expression. Follow-up TBD...
0.0s
Clojure
;; "Some of them leave you no alternative"
(= [] (if (> 4 3)
        []))
;; skill 8004: Write an if special form without an explicit else branch
;; question 8003: What (if any) relevant & useful skills are demonstrated here?
;; answer 8003a: It appears that this if special form is simply returning an empty vector, and demonstrating that an explicit return clause/expression/form is omittable.
;; question 8007: What are the names of the arguments of the if special form?
;; answer 8007a: "(if test then else?)" where "then" and "else?" are also branches that can be evaluated depending on how "test" evaluates (to true or to false)  @ https://clojuredocs.org/clojure.core/if
;; note: It appears that `when` (instead of `if`) is recommended for cases like this where there is no explicit "else?" branch
0.0s
Clojure
;; "And in such a situation you may have nothing"
(= nil (if (nil? 0)
        [:a :b :c]))
;; skill 8005: Return `nil` from an if special form with no explicit else return value
0.0s
Clojure
;; "In others your alternative may be interesting"
(= :glory (if (not (empty? ()))
            :doom
            :glory))
;; question 8004: Why does clj-kondo say to use "idiom" (seq x) instead of (not (empty? x)) ?
;; answer 8004a: TBD...
;; question 8005: What is an idiom in Clojure? (see question 8004 for context)
;; answer 8005a: TBD...
0.0s
Clojure
;; "You may have a multitude of possible paths"
(let [x 5]
  (= :your-road (cond (= x 1) :road-not-taken
                      (= x 2) :another-road-not-taken
                      :else :your-road)))
;; skill 8006: Write a switch (?) statement using the `cond` macro (?)
;; skill 8007: Write a switch (?) statement using the `cond` macro (?) with a default case/condition (?) (an :else) 
0.0s
Clojure
;; "Or your fate may be sealed"
(= 'doom (if-not (zero? 5)
            'doom
            'more-doom))
;; skill 8008: Check if something is falsy with the `if-not` macro (which is more concise than using a combo `if` and `not`)
0.0s
Clojure
;; "In case of emergency, go fast"
(= "pretty fast"
  (explain-exercise-velocity :bicycling))
;; skill 8009: Identify whether a something is a function
;; question 8010: What are the smallest building blocks of expressions in Clojure (eg. "term"/"symbol"/"token"/"name"/etc.)? As a related example, see skill 8009
;; answer 8010a: TBD...
0.0s
Clojure
(test/function? explain-exercise-velocity)
;; question 8009: How may one determine whether something is a function or not? Related skill: skill 8009
;; answer 8009a: One may determine whether something is a function or not by using the `clojure.test/function?` function, see demo in this cell
0.0s
Clojure
;; "But admit it when you don't know what to do"
(= "is that even exercise?"
  (explain-exercise-velocity :watching-tv))
;; skill 8010: Query a case map with a keyword that it does not have to get the default else return value
;; question 8008: Are the words "query", "case map", and "default else return value" clear and specific, or can their wording be improved upon? For example, "Use the case macro as a function, and pass to it as an argument a keyword whihc doesn't exist inside the case's list of conditions to have the case's default value returned." @ https://github.com/clojure/clojure/blob/clojure-1.10.1/src/clj/clojure/core.clj#L6697
;; answer 8008a: TBD...
0.0s
Clojure

Closing Thoughts

There definitely is more ground to explore here. I will be back or else ;)

Update: 2021_04_19 (year, month, day)

I'm back as promised today. I've added answers to questions, and added a few new questions, either as a result of research to answer prior questions, or to clarify on ambiguous skills or skill wordings. Yet to be answered questions have been marked with "TBD..." (to be determined)

Runtimes (1)