Checking whether a number is contained in a range
(let [x 10]
(< 3 x 5))
Reference: Do Things: A Clojure Crash Course
Solve the exercises at the end of the chapter
let
is lexically scoped
def
creates a global variable in the current namespace
In many languages, we have:
unary operators
binary operators
functions
In Clojure, we have only Symbolic expressions (Sexp).
It scales well with the number of arguments.
Checking whether a number is contained in a range
(let [x 10]
(< 3 x 5))
Storing an if
expression in a var
(def my-value (if true 42 56))
In other languages, if
is not an expression: it’s a statement.
The docstring of a function is stored in the metadata of the variable that defines the function.
Defining a function with a docstring
| Displaying the metadata
|
A function returns the value of the last expression of its body.
A silly function with two expressions
(defn fn-two-expressions [a b]
(+ a b)
(* a b))
Calling a function whose body is made of two expressions
(foo 10 3)
☕ Usually, the body of a function is made of a single (nested) expression
do
is needed for side effectstwo expressions wrapped in a single do
(if true
(do
(println "It's true")
52)
(do
(println "It's false")
44))
Keywords have less features than strings
Keywords are like enums: an id with a name
Comparison of keywords is faster than comparison of strings
Common idiom: keywords as keys in map
Keyboard naming convention is kebab-case
A map with keyword keys
(def clojure-inventor {:first-name "Rich"
:last-name "Hickey"})
Retrieving the value associated to a keyword in a map
(:first-name clojure-inventor)
let
vs. def
The benefits of uniform function calls
do
is usually not needed
keywords vs strings
where is the docstring stored? (metadata)
the last expression of the function body
The data
(def asym-hobbit-body-parts [{:name "head" :size 3} {:name "left-eye" :size 1} {:name "left-ear" :size 1} {:name "mouth" :size 1} {:name "nose" :size 1} {:name "neck" :size 2} {:name "left-shoulder" :size 3} {:name "left-upper-arm" :size 3} {:name "chest" :size 10} {:name "back" :size 10} {:name "left-forearm" :size 3} {:name "abdomen" :size 6} {:name "left-kidney" :size 1} {:name "left-hand" :size 2} {:name "left-knee" :size 2} {:name "left-thigh" :size 4} {:name "left-lower-leg" :size 3} {:name "left-achilles" :size 1} {:name "left-foot" :size 2}])
The code
(defn matching-part
[part]
{:name (clojure.string/replace (:name part) #"^left-" "right-")
:size (:size part)})
(clojure.set/union (map matching-part asym-hobbit-body-parts)
asym-hobbit-body-parts)