Clojure Koans 23 Meta Notebook

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

Spoilers Alert

{: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

When and where is using meta beneficial to me as a writer of Clojure?

(def giants
    (with-meta 'Giants
        {:league "National League"}))
;; skill 23001: Tag an object with meta data by using the `with-meta` function (?)
;; question 23001: What role & function does `'Giants` play here?
;; question 23002: What is the structure of the object returned by `with-meta`?
;; question 23003: What is meant by "object" in the context of the input for `with-meta`? reference: https://clojuredocs.org/clojure.core/with-meta
Clojure
;; "Some objects can be tagged using the with-meta function"
(= {:league "National League"} (meta giants))
;; skill 23002: Access an object's meta data by using the `meta` function (?)
Clojure
;; "Or more succinctly with a reader macro"
(= {:division "West"}
   (meta '^{:division "West"} Giants))
;; question 23004: What role does `Giants` play here? It appears to be a symbol. Might it be a local binding of sorts? Does it function as an object?
;; guess 23004a: It appears that a reader macro for assigning/tagging meta-data to an object is being used to assign a meta-tag hashmap to the symbol `Giants` (?), and then that meta-data is read/accessed by the `meta` function
Clojure
;; "While others can't"
(= "This doesn't implement the IObj interface"
   (try
       (with-meta
           2
           {:prime true})
       (catch ClassCastException e
           "This doesn't implement the IObj interface")))
;; question 23005: Is the IObj interface a Java thing, a Clojure thing, both, or neither?
;; question 23006: Supposedly, the `with-meta` functon cannot assign meta-data to things (objects?) that do not implement the clojure.lang.IObj interface - What are the things that do not implement clojure.lang.IObj? What are the things that do? How can one programmatically determine if something implements clojure.lang.IObj?
Clojure
;; "Notice when metadata carries over"
(= {:foo :bar} (meta (merge '^{:foo :bar} {:a 1 :b 2}
                            {:b 3 :c 4})))
;; question 23007: What exactly is happening here? What is meant by "carries over"?
;; question 23008: To what is the meta-data here being assigned?
Clojure
;; "And when it doesn't"
(= nil (meta (merge {:a 1 :b 2}
                    '^{:foo :bar} {:b 3 :c 4})))
;; question 23009: What exactly is happening here?
Clojure
;; "Metadata can be used as a type hint to avoid reflection during runtime"
(= \C (#(.charAt ^String % 0) "Cast me"))
;; skill 23003: Use metadata as a type hint to avoid reflection during runtime (?)
;; question 23010: What is a "type hint" in the above context?
;; question 23011: What is "reflection" in Clojure? Please show concise/concrete/clear examples.
;; question 23012: What is "reflection during runtime"? Please show a couple concise/concrete/clear examples.
;; question 23013: How is this different than `(.charAt "Cast me" 0)`?
Clojure
;; "You can directly update an object's metadata"
(= 8 (let [giants
           (with-meta
               'Giants
               {:world-series-titles (atom 7)})]
         (swap! (:world-series-titles (meta giants)) inc)
         @(:world-series-titles (meta giants))))
;; question 23014: What does the `@` (at) sign prefix stand for?
Clojure
;; "You can also create a new object from another object with metadata"
(= {:league "National League" :park "AT&T Park"}
   (meta (vary-meta giants
                    assoc :park "AT&T Park")))
;; skill 23004: Create a new object from another object with metadata by using the `vary-meta` function
Clojure
;; "But it won't affect behavior like equality"
(= giants (vary-meta giants dissoc :league))
;; question 23015: What do they mean by "it", and how so will "it" not affect behavior like equality?
;; question 23016: What exactly is happening here, and what kind of issue is this & when does it occur? (human error, syntax, etc., at read, compilation, runtime, etc.)
Clojure
;; "Or the object's printed representation"
(= (pr-str 'Giants) (pr-str (vary-meta giants dissoc :league)))
;; question 23017: What does `pr-str` do exactly?
;; question 23017a: It seems to cast/convert to string type with some differences from the `str` function. from the docs: "pr to a string, returning it" source: https://clojuredocs.org/clojure.core/pr-str
;; question 23018: What does the `pr-str` stand for?
;; answer 23018a: Well... `pr` stands for `pr`, from the docs:
;;     Prints the object(s) to the output stream that is the current value
;;     of *out*.  Prints the object(s), separated by spaces if there is
;;     more than one.  By default, pr and prn print in a way that objects
;;     can be read by the reader
;;     source: https://clojuredocs.org/clojure.core/pr-str
Clojure

Closing Thoughts

Reading the docs lately has been more fun for me. It feels less like gibberish, and more like sage wisdom.

For next time:

Runtimes (1)