(+ 1 2 3)
+(+ 1 2 3)
;; => 6
diff --git a/index.html b/index.html index fd99a60..91cb06a 100644 --- a/index.html +++ b/index.html @@ -2,95 +2,24 @@
- + - + -ClojureScript is an implementation of the Clojure programming language that targets JavaScript. Because of this, it can run in many different execution -environments including web browsers, Node.js, io.js and Nashorn.
+environments including web browsers, Node.js, Nashorn (and many other).Unlike other languages that intend to compile to JavaScript (like TypeScript, @@ -232,15 +308,15 @@
Another big difference (and in our opinion an advantage) over other languages is -that Clojure is designed to be a guest. It is a language without its own virtual -machine that can be easily adapted to the nuances of its execution environment. This -has the benefit that Clojure (and hence ClojureScript) has access to all the -existing libraries written for the host language.
+that Clojure(Script) is designed to be a guest. It is a language without its own +virtual machine that can be easily adapted to the nuances of its execution +environment. This has the benefit that Clojure (and hence ClojureScript) has +access to all the existing libraries written for the host language.Before we jump in, let us summarize some of the core ideas that ClojureScript brings -to the table. Don’t worry if you don’t understand all of them right now, they’ll -become clear throughout the book.
+Before we jump in, let us summarize some of the core ideas that ClojureScript +brings to the table. Don’t worry if you don’t understand all of them right now, +they’ll become clear throughout the book.
These ideas together have a great influence in the way you design and implement -software, even if you are not using ClojureScript. Functional programming, decoupling -of data (which is immutable) from the operations to transform it, explicit idioms for -managing change over time and polymorphic constructs for programming to abstractions -greatly simplify the systems we write.
+software, even if you are not using ClojureScript. Functional programming, +decoupling of data (which is immutable) from the operations to transform it, +explicit idioms for managing change over time and polymorphic constructs for +programming to abstractions greatly simplify the systems we write.-We can make the same exact software we are making today with dramatically simpler -stuff — dramatically simpler languages, tools, techniques, approaches. +We can make the same exact software we are making today with dramatically +simpler stuff — dramatically simpler languages, tools, techniques, approaches.
(+ 1 2 3)
+(+ 1 2 3)
;; => 6
(zero? 0)
+(zero? 0)
;; => true
'(+ 1 2 3)
+'(+ 1 2 3)
;; => (+ 1 2 3)
(let [x 1
+(let [x 1
y 2
z 3]
(+ x y z))
@@ -396,7 +472,7 @@ 3.2.1. Numbers
23
+23
+23
-100
1.7
@@ -416,54 +492,51 @@ 3.2.2. Keywords
:foobar
+:foobar
:2
:?
As you can see, the keywords are all prefixed with :
, but this character is only
-part of the literal syntax and is not part of the name of the object.
As you can see, the keywords are all prefixed with :
, but this character is
+only part of the literal syntax and is not part of the name of the object.
You can also create a keyword by calling the keyword
function. Don’t worry if you
-don’t understand or are unclear about anything in the following example;
+
You can also create a keyword by calling the keyword
function. Don’t worry if
+you don’t understand or are unclear about anything in the following example;
functions are discussed in a later section.
(keyword "foo")
+(keyword "foo")
;; => :foo
When prefixing keywords with a double colon ::
, the keyword will be prepended by the name of the current namespace.
-Note that namespacing keywords affects equality comparisons.
When prefixing keywords with a double colon ::
, the keyword will be prepended
+by the name of the current namespace. Note that namespacing keywords affects
+equality comparisons.
---
-::foo
-;; => :cljs.user/foo
-::foo
+;; => :cljs.user/foo
+
+(= ::foo :foo)
+;; => false
(= ::foo :foo) -;; ⇒ false ----
Another alternative is to include the namespace in the keyword literal, this is useful when creating namespaced keywords -for other namespaces:
+Another alternative is to include the namespace in the keyword +literal, this is useful when creating namespaced keywords for other +namespaces:
---
-:cljs.unraveled/foo
-;; => :cljs.unraveled/foo
----
+:cljs.unraveled/foo
+;; => :cljs.unraveled/foo
---
-(keyword "cljs.unraveled" "foo")
-;; => :cljs.unraveled/foo
----
+(keyword "cljs.unraveled" "foo")
+;; => :cljs.unraveled/foo
sample-symbol
+sample-symbol
othersymbol
f1
my-special-swap!
@@ -515,7 +586,7 @@ 3.2.4. Strings
"An example of a string"
+"An example of a string"
"This is a multiline
+"This is a multiline
string in ClojureScript."
\a ; The lowercase a character
+\a ; The lowercase a character
\newline ; The newline character
'(1 2 3 4 5)
+'(1 2 3 4 5)
'(:foo :bar 2)
(inc 1)
+(inc 1)
;; => 2
'(inc 1)
@@ -609,7 +680,7 @@ Lists
(list 1 2 3 4 5)
+(list 1 2 3 4 5)
;; => (1 2 3 4 5)
(list :foo :bar 2)
@@ -635,7 +706,7 @@ Vectors
[:foo :bar]
+[:foo :bar]
[3 4 5 nil]
(vector 1 2 3)
+(vector 1 2 3)
;; => [1 2 3]
(vector "blah" 3.5 nil)
@@ -667,7 +738,7 @@ Maps
{:foo "bar", :baz 2}
+{:foo "bar", :baz 2}
{:alphabet [:a :b :c]}
#{1 2 3 :foo :bar}
+#{1 2 3 :foo :bar}
;; => #{1 :bar 3 :foo 2}
(set [1 2 1 3 1 4 1 5])
;; => #{1 2 3 4 5}
@@ -733,7 +804,7 @@ 3.3. Vars
(def x 22)
+(def x 22)
(def y [1 2 3])
(inc 1)
+(inc 1)
;; => 2
(+ 1 2 3)
+(+ 1 2 3)
;; => 6
(fn [param1 param2]
+(fn [param1 param2]
(/ (+ param1 param2) 2.0))
((fn [x] (* x x)) 5)
+((fn [x] (* x x)) 5)
;; => 25
(def square (fn [x] (* x x)))
+(def square (fn [x] (* x x)))
(square 12)
;; => 144
@@ -833,7 +904,7 @@
-(defn square
+(defn square
"Return the square of a given number."
[x]
(* x x))
@@ -858,7 +929,7 @@
-(defn myinc
+(defn myinc
"Self defined version of parameterized `inc`."
([x] (myinc x 1))
([x increment]
@@ -878,7 +949,7 @@
-(myinc 1)
+(myinc 1)
;; => 2
(myinc 1 3)
@@ -911,7 +982,7 @@ 3.4.4. Va
-(defn my-variadic-set
+(defn my-variadic-set
[& params]
(set params))
@@ -934,7 +1005,7 @@
-(def average #(/ (+ %1 %2) 2))
+(def average #(/ (+ %1 %2) 2))
(average 3 4)
;; => 3.5
@@ -945,7 +1016,7 @@
-(def average-longer (fn [a b] (/ (+ a b) 2)))
+(def average-longer (fn [a b] (/ (+ a b) 2)))
(average-longer 7 8)
;; => 7.5
@@ -966,7 +1037,7 @@
-(def my-variadic-set #(set %&))
+(def my-variadic-set #(set %&))
(my-variadic-set 1 2 2)
;; => #{1 2}
@@ -981,7 +1052,7 @@ 3.5. Flow control
JavaScript, C, etc.
-3.5.1. Branching with if
+3.5.1. Branching with if
Let’s start with a basic one: if
. In ClojureScript, the if
is an expression
and not a statement, and it has three parameters: the first one is the condition
@@ -991,7 +1062,7 @@
-(defn discount
+(defn discount
"You get 5% discount for ordering 100 or more items"
[quantity]
(if (>= quantity 100)
@@ -1011,7 +1082,7 @@
-3.5.2. Branching with cond
+3.5.2. Branching with cond
Sometimes, the if
expression can be slightly limiting because it does not have the
"else if" part to add more than one condition. The cond
macro comes to the rescue.
@@ -1021,7 +1092,7 @@
-(defn mypos?
+(defn mypos?
[x]
(cond
(> x 0) "positive"
@@ -1042,7 +1113,7 @@
-(defn translate-lang-code
+(defn translate-lang-code
[code]
(condp = (keyword code)
:es "Spanish"
@@ -1063,7 +1134,7 @@
-3.5.3. Branching with case
+3.5.3. Branching with case
The case
branching expression has a similar use as our previous example with
condp
. The main differences are that case
always uses the =
predicate/function
@@ -1076,7 +1147,7 @@
-(defn translate-lang-code
+(defn translate-lang-code
[code]
(case code
"es" "Spanish"
@@ -1108,18 +1179,19 @@ 3.6. Trut
-(def valid? #{1 2 3})
+(def valid? #{1 2 3})
(filter valid? (range 1 10))
;; => (1 2 3)
-This is because set returns the a value if it exists or nil in case contrary:
+This works because a set returns either the value itself for all contained elements
+or nil
:
-(valid? 1)
+(valid? 1)
;; => 1
(valid? 4)
@@ -1145,7 +1217,7 @@ 3.7.1. Locals
-(let [x (inc 1)
+(let [x (inc 1)
y (+ x 1)]
(println "Simple message from the body of a let")
(* x y))
@@ -1177,7 +1249,7 @@ 3.7.2. Blocks
-(do
+(do
(println "hello world")
(println "hola mundo")
(* 3 5) ;; this value will not be returned; it is thrown away
@@ -1209,7 +1281,7 @@ 3.7.3. Loops
parameters.
-Looping with loop/recur
+Looping with loop/recur
Let’s take a look at how to express loops using recursion with the loop
and
recur
forms. loop
defines a possibly empty list of bindings (notice the
@@ -1221,7 +1293,7 @@
-(loop [x 0]
+(loop [x 0]
(println "Looping with " x)
(if (= x 2)
(println "Done looping!")
@@ -1245,7 +1317,7 @@
-(defn recursive-function
+(defn recursive-function
[x]
(println "Looping with" x)
(if (= x 2)
@@ -1295,7 +1367,7 @@
-(map inc [0 1 2])
+(map inc [0 1 2])
;; => (1 2 3)
@@ -1307,7 +1379,7 @@
-(defn y-value [x] (+ (* 3 x) 5))
+(defn y-value [x] (+ (* 3 x) 5))
(map y-value [1 2 3 4 5])
;; => (8 11 14 17 20)
@@ -1319,7 +1391,7 @@
-(map (fn [x] (+ (* 3 x) 5)) [1 2 3 4 5])
+(map (fn [x] (+ (* 3 x) 5)) [1 2 3 4 5])
;; => (8 11 14 17 20)
(map #(+ (* 3 %) 5) [1 2 3 4 5])
@@ -1333,7 +1405,7 @@
-(filter odd? [1 2 3 4])
+(filter odd? [1 2 3 4])
;; => (1 3)
@@ -1344,7 +1416,7 @@
-(filter (fn [word] (< (count word) 5)) ["ant" "baboon" "crab" "duck" "echidna" "fox"])
+(filter (fn [word] (< (count word) 5)) ["ant" "baboon" "crab" "duck" "echidna" "fox"])
;; => ("ant" "crab" "duck" "fox")
@@ -1355,7 +1427,7 @@
-(reduce + 0 [1 2 3 4])
+(reduce + 0 [1 2 3 4])
;; => 10
@@ -1369,7 +1441,7 @@
-(defn sum-squares
+(defn sum-squares
[accumulator item]
(+ accumulator (* item item)))
@@ -1382,7 +1454,7 @@
-(reduce (fn [acc item] (+ acc (* item item))) 0 [3 4 5])
+(reduce (fn [acc item] (+ acc (* item item))) 0 [3 4 5])
;; => 50
@@ -1391,7 +1463,7 @@
-(reduce (fn [acc word] (+ acc (count word))) 0 ["ant" "bee" "crab" "duck"])
+(reduce (fn [acc word] (+ acc (count word))) 0 ["ant" "bee" "crab" "duck"])
;; => 14
@@ -1408,7 +1480,7 @@
-;; wrong starting value
+;; wrong starting value
(reduce * 0 [3 4 5])
;; => 0
@@ -1419,7 +1491,7 @@
-for
sequence comprehensions
+for
sequence comprehensions
In ClojureScript, the for
construct isn’t used for iteration but for generating
sequences, an operation also known as "sequence comprehension". In this section
@@ -1431,7 +1503,7 @@
-(for [x [1 2 3]]
+(for [x [1 2 3]]
[x (* x x)])
;; => ([1 1] [2 4] [3 9])
@@ -1447,7 +1519,7 @@
-(for [x [1 2 3]
+(for [x [1 2 3]
y [4 5]]
[x y])
@@ -1465,7 +1537,7 @@
-(for [x [1 2 3]
+(for [x [1 2 3]
y [4 5]
:let [z (+ x y)]]
z)
@@ -1478,7 +1550,7 @@
-(for [x [1 2 3]
+(for [x [1 2 3]
y [4 5]
:while (= y 4)]
[x y])
@@ -1492,7 +1564,7 @@
-(for [x [1 2 3]
+(for [x [1 2 3]
y [4 5]
:when (= (+ x y) 6)]
[x y])
@@ -1506,7 +1578,7 @@
-(for [x [1 2 3]
+(for [x [1 2 3]
y [4 5]
:let [z (+ x y)]
:when (= z 6)]
@@ -1527,7 +1599,7 @@
-(doseq [x [1 2 3]
+(doseq [x [1 2 3]
y [4 5]
:let [z (+ x y)]]
(println x "+" y "=" z))
@@ -1548,7 +1620,7 @@
-(run! println [1 2 3])
+(run! println [1 2 3])
;; 1
;; 2
;; 3
@@ -1579,7 +1651,7 @@
-(let [xs [1 2 3]
+(let [xs [1 2 3]
ys (conj xs 4)]
(println "xs:" xs)
(println "ys:" ys))
@@ -1615,7 +1687,7 @@
-(let [xs (list 1 2 3)
+(let [xs (list 1 2 3)
ys (cons 0 xs)]
(println "xs:" xs)
(println "ys:" ys)
@@ -1650,7 +1722,7 @@
-(first [1 2 3])
+(first [1 2 3])
;; => 1
(rest [1 2 3])
@@ -1663,7 +1735,7 @@
-(seq [])
+(seq [])
;; => nil
(seq [1 2 3])
@@ -1680,7 +1752,7 @@
-(rest [])
+(rest [])
;; => ()
(next [])
@@ -1702,7 +1774,7 @@ nil-punning
-(defn print-coll
+(defn print-coll
[coll]
(when (seq coll)
(println "Saw " (first coll))
@@ -1727,7 +1799,7 @@ nil-punning
-(seq nil)
+(seq nil)
;; => nil
(first nil)
@@ -1749,7 +1821,7 @@
-(map inc [1 2 3])
+(map inc [1 2 3])
;; => (2 3 4)
(map inc #{1 2 3})
@@ -1779,7 +1851,7 @@
-(map (fn [[key value]] (* value value))
+(map (fn [[key value]] (* value value))
{:ten 10 :seven 7 :four 4})
;; => (100 49 16)
@@ -1790,7 +1862,7 @@
-(map (fn [value] (* value value))
+(map (fn [value] (* value value))
(vals {:ten 10 :seven 7 :four 4}))
;; => (100 49 16)
@@ -1802,7 +1874,7 @@
-(map inc [])
+(map inc [])
;; => ()
(map inc #{})
@@ -1824,7 +1896,7 @@
-(coll? nil)
+(coll? nil)
;; => false
(coll? [1 2 3])
@@ -1843,7 +1915,7 @@
-(seq? nil)
+(seq? nil)
;; => false
(seqable? nil)
;; => false
@@ -1871,7 +1943,7 @@
-(count nil)
+(count nil)
;; => 0
(count [1 2 3])
@@ -1889,7 +1961,7 @@
-(empty nil)
+(empty nil)
;; => nil
(empty [1 2 3])
@@ -1904,7 +1976,7 @@
-(empty? nil)
+(empty? nil)
;; => true
(empty? [])
@@ -1925,7 +1997,7 @@
-(conj nil 42)
+(conj nil 42)
;; => (42)
(conj [1 2] 3)
@@ -1959,7 +2031,7 @@ Laziness
-(range 5)
+(range 5)
;; => (0 1 2 3 4)
(range 1 10)
;; => (1 2 3 4 5 6 7 8 9)
@@ -1980,7 +2052,7 @@ Laziness
-(take-while (fn [x] (< (+ (* 2 x x) 5) 100))
+(take-while (fn [x] (< (+ (* 2 x x) 5) 100))
(range 0 100))
;; => (0 1 2 3 4 5 6)
@@ -2011,7 +2083,7 @@ Lists
-(cons 0 (cons 1 (cons 2 ())))
+(cons 0 (cons 1 (cons 2 ())))
;; => (0 1 2)
@@ -2023,7 +2095,7 @@ Lists
-(cons 0 '(1 2))
+(cons 0 '(1 2))
;; => (0 1 2)
@@ -2033,7 +2105,7 @@ Lists
-(conj '(1 2) 0)
+(conj '(1 2) 0)
;; => (0 1 2)
@@ -2051,7 +2123,7 @@ Lists
-(def list-stack '(0 1 2))
+(def list-stack '(0 1 2))
(peek list-stack)
;; => 0
@@ -2090,7 +2162,7 @@ Vectors
-(vector? [0 1 2])
+(vector? [0 1 2])
;; => true
(vector 0 1 2)
@@ -2107,7 +2179,7 @@ Vectors
-(conj [0 1] 2)
+(conj [0 1] 2)
;; => [0 1 2]
@@ -2118,7 +2190,7 @@ Vectors
-(nth [0 1 2] 0)
+(nth [0 1 2] 0)
;; => 0
@@ -2131,7 +2203,7 @@ Vectors
-(assoc ["cero" "uno" "two"] 2 "dos")
+(assoc ["cero" "uno" "two"] 2 "dos")
;; => ["cero" "uno" "dos"]
@@ -2141,7 +2213,7 @@ Vectors
-(assoc ["cero" "uno" "dos"] 3 "tres")
+(assoc ["cero" "uno" "dos"] 3 "tres")
;; => ["cero" "uno" "dos" "tres"]
(assoc ["cero" "uno" "dos"] 4 "cuatro")
@@ -2156,7 +2228,7 @@ Vectors
-(["cero" "uno" "dos"] 0)
+(["cero" "uno" "dos"] 0)
;; => "cero"
(["cero" "uno" "dos"] 2)
@@ -2173,7 +2245,7 @@ Vectors
-(def vector-stack [0 1 2])
+(def vector-stack [0 1 2])
(peek vector-stack)
;; => 2
@@ -2200,7 +2272,7 @@ Vectors
-(map inc [0 1 2])
+(map inc [0 1 2])
;; => (1 2 3)
(type (map inc [0 1 2]))
@@ -2228,7 +2300,7 @@ Maps
-(map? {:name "Cirilla"})
+(map? {:name "Cirilla"})
;; => true
(hash-map :name "Cirilla")
@@ -2245,7 +2317,7 @@ Maps
-(def ciri {:name "Cirilla"})
+(def ciri {:name "Cirilla"})
(conj ciri [:surname "Fiona"])
;; => {:name "Cirilla", :surname "Fiona"}
@@ -2266,7 +2338,7 @@ Maps
-(assoc {:name "Cirilla"} :surname "Fiona")
+(assoc {:name "Cirilla"} :surname "Fiona")
;; => {:name "Cirilla", :surname "Fiona"}
(assoc {:name "Cirilla"} :name "Alfonso")
;; => {:name "Alfonso"}
@@ -2281,7 +2353,7 @@ Maps
-({:name "Cirilla"} :name)
+({:name "Cirilla"} :name)
;; => "Cirilla"
({:name "Cirilla"} :surname)
@@ -2295,7 +2367,7 @@ Maps
-(def sm (sorted-map :c 2 :b 1 :a 0))
+(def sm (sorted-map :c 2 :b 1 :a 0))
;; => {:a 0, :b 1, :c 2}
(keys sm)
@@ -2311,7 +2383,7 @@ Maps
-(defn reverse-compare [a b] (compare b a))
+(defn reverse-compare [a b] (compare b a))
(def sm (sorted-map-by reverse-compare :a 0 :b 1 :c 2))
;; => {:c 2, :b 1, :a 0}
@@ -2330,7 +2402,7 @@ Sets
-(set? #{\a \e \i \o \u})
+(set? #{\a \e \i \o \u})
;; => true
(set [1 1 2 3])
@@ -2343,7 +2415,7 @@ Sets
-#{1 1 2 3}
+#{1 1 2 3}
;; clojure.lang.ExceptionInfo: Duplicate key: 1
@@ -2356,7 +2428,7 @@ Sets
-(require '[clojure.set :as s])
+(require '[clojure.set :as s])
(def danish-vowels #{\a \e \i \o \u \æ \ø \å})
;; => #{"a" "e" "å" "æ" "i" "o" "u" "ø"}
@@ -2385,7 +2457,7 @@ Sets
-(def spanish-vowels #{\a \e \i \o \u})
+(def spanish-vowels #{\a \e \i \o \u})
;; => #{"a" "e" "i" "o" "u"}
(def danish-vowels (conj spanish-vowels \æ \ø \å))
@@ -2402,7 +2474,7 @@ Sets
-(def vowels #{\a \e \i \o \u})
+(def vowels #{\a \e \i \o \u})
;; => #{"a" "e" "i" "o" "u"}
(get vowels \b)
@@ -2428,7 +2500,7 @@ Sets
-(def unordered-set #{[0] [1] [2]})
+(def unordered-set #{[0] [1] [2]})
;; => #{[0] [2] [1]}
(seq unordered-set)
@@ -2451,7 +2523,7 @@ Queues
-(def pq #queue [1 2 3])
+(def pq #queue [1 2 3])
;; => #queue [1 2 3]
@@ -2460,7 +2532,7 @@ Queues
-(def pq #queue [1 2 3])
+(def pq #queue [1 2 3])
;; => #queue [1 2 3]
(conj pq 4 5)
@@ -2474,7 +2546,7 @@ Queues
-(def pq #queue [1 2 3])
+(def pq #queue [1 2 3])
;; => #queue [1 2 3]
(peek pq)
@@ -2510,7 +2582,7 @@ 3.9
-(let [v [0 1 2]
+(let [v [0 1 2]
fst (nth v 0)
thrd (nth v 2)]
[thrd fst])
@@ -2524,7 +2596,7 @@ 3.9
-(let [[fst _ thrd] [0 1 2]]
+(let [[fst _ thrd] [0 1 2]]
[thrd fst])
;; => [2 0]
@@ -2543,7 +2615,7 @@ 3.9
-(defn swap-pair [[fst snd]]
+(defn swap-pair [[fst snd]]
[snd fst])
(swap-pair [1 2])
@@ -2562,7 +2634,7 @@ 3.9
-(let [[fst snd & more] (range 10)]
+(let [[fst snd & more] (range 10)]
{:first fst
:snd snd
:rest more})
@@ -2582,7 +2654,7 @@ 3.9
-(let [[fst snd & more :as original] (range 10)]
+(let [[fst snd & more :as original] (range 10)]
{:first fst
:snd snd
:rest more
@@ -2599,7 +2671,7 @@ 3.9
-(let [{language :language} {:language "ClojureScript"}]
+(let [{language :language} {:language "ClojureScript"}]
language)
;; => "ClojureScript"
@@ -2611,7 +2683,7 @@ 3.9
-(let [{name :name} {:language "ClojureScript"}]
+(let [{name :name} {:language "ClojureScript"}]
name)
;; => nil
@@ -2623,7 +2695,7 @@ 3.9
-(let [{name :name :or {name "Anonymous"}} {:language "ClojureScript"}]
+(let [{name :name :or {name "Anonymous"}} {:language "ClojureScript"}]
name)
;; => "Anonymous"
@@ -2638,7 +2710,7 @@ 3.9
-(let [{name :name :as person} {:name "Cirilla" :age 49}]
+(let [{name :name :as person} {:name "Cirilla" :age 49}]
[name person])
;; => ["Cirilla" {:name "Cirilla" :age 49}]
@@ -2651,7 +2723,7 @@ 3.9
-(let [{one 1} {0 "zero" 1 "one"}]
+(let [{one 1} {0 "zero" 1 "one"}]
one)
;; => "one"
@@ -2676,7 +2748,7 @@ 3.9
-(let [{:keys [name surname]} {:name "Cirilla" :surname "Fiona"}]
+(let [{:keys [name surname]} {:name "Cirilla" :surname "Fiona"}]
[name surname])
;; => ["Cirilla" "Fiona"]
@@ -2693,7 +2765,7 @@ 3.9
-(let [{:strs [name surname]} {"name" "Cirilla" "surname" "Fiona"}]
+(let [{:strs [name surname]} {"name" "Cirilla" "surname" "Fiona"}]
[name surname])
;; => ["Cirilla" "Fiona"]
@@ -2703,13 +2775,24 @@ 3.9
+If the map you want to destructure has namespaced keywords as keys, you also can
+do it using the keyword syntax inside :keys
vector:
+
+
+
+(let [{:keys [::name ::surname]} {::name "Cirilla" ::surname "Fiona"}]
+ [name surname])
+;; => ["Cirilla" "Fiona"]
+
+
+
An interesting property of destructuring is that we can nest destructuring forms
arbitrarily, which makes code that accesses nested data on a collection very easy to
understand, as it mimics the collection’s structure:
-(let [{[fst snd] :languages} {:languages ["ClojureScript" "Clojure"]}]
+(let [{[fst snd] :languages} {:languages ["ClojureScript" "Clojure"]}]
[snd fst])
;; => ["Clojure" "ClojureScript"]
@@ -2718,13 +2801,14 @@ 3.9
3.10. Threading Macros
-Threading macros, also known as arrow functions, enables one to write more readable code
-when multiple nested function calls are performed.
+Threading macros, also known as arrow functions, enables one to write
+more readable code when multiple nested function calls are performed.
-Imagine you have (f (g (h x)))
where a function f
receives as its first parameter the
-result of executing function g
, repeated multiple times. With the most basic →
threading
-macro you can convert that into (-> x (h) (g) (f))
which is easier to read.
+Imagine you have (f (g (h x)))
where a function f
receives as its first
+parameter the result of executing function g
, repeated multiple times. With
+the most basic →
threading macro you can convert that into (-> x (h) (g)
+(f))
which is easier to read.
The result is syntactic sugar, because the arrow functions are defined as macros
@@ -2732,22 +2816,22 @@
3.10. Threadi
automatically converted to (f (g (h x))) at compile time.
-Take note that the parenthesis on h
, g
and f
are optional, and can be ommited:
-(f (g (h x)))
is the same as (-> x h g f)
.
+Take note that the parenthesis on h
, g
and f
are optional, and can be
+ommited: (f (g (h x)))
is the same as (-> x h g f)
.
-3.10.1. The thread-first macro (->
)
+3.10.1. ->
(thread-first macro)
This is called thread first because it threads the first argument throught the
different expressions as first arguments.
-Using a more concrete example, this is how the code looks without using threading
-macros:
+Using a more concrete example, this is how the code looks without using
+threading macros:
-(def book {:name "Lady of the Lake"
+(def book {:name "Lady of the Lake"
:readers 0})
(update (assoc book :age 1999) :readers inc)
@@ -2759,20 +2843,21 @@
-(-> book
+