3. The package contains
● functions as values
● immutable (persistent) data structures
● pure functions
● recursion
● lazy evaluation
with
4. with
The package contains
● functions as values
● immutable (persistent) data structures
● pure functions
● recursion
● lazy evaluation
5. with
Brief intro to Clojure
● I will trade precision for clarity
● there’s much more to know
● one huge missing topic: the REPL
● you can try this at home
6. with
Clojure data anatomy
1 2.0 3/4 ; numbers
foo bar ; symbols
:one :two ; keywords
“value” ; strings
true false ; bools
a b c ; chars
nil ; null
9. with
Clojure code anatomy
(* 132.715
(- 1.06 1.02))
-> 5.308600000000005
nested unquoted lists, in facts:
“The name LISP derives from "LISt Processing".” -- Wikipedia
10. with
Clojure code anatomy
(* 132.715
(- 1.06 1.02))
-> 5.308600000000005
no “return”: everything
is an expression
33. with
Functional schmunctional
● functions as values
● immutable (persistent) data structures
● pure functions
● recursion
● lazy evaluation
(doseq [_ (range 2000)]
(inc 41)) ; => always 42
For a given input, pure functions yield the same result,
making them dead-easy to maintain and prove correct
34. with
Functional schmunctional
● functions as values
● immutable (persistent) data structures
● pure functions
● recursion
● lazy evaluation
(doseq [_ (range 2000)]
(rand)
(http/GET “http://...”))
Impure code enables interaction, but introduces side effects
which make your program harder to test and reason about
35. with
Functional schmunctional
● functions as values
● immutable (persistent) data structures
● pure functions
● recursion
● lazy evaluation
(defn my-inc [[h & t]]
(when h
(cons (inc h)
(my-inc t))))
recursive call
36. with
Functional schmunctional
● functions as values
● immutable (persistent) data structures
● pure functions
● recursion
● lazy evaluation
(defn my-inc [[h & t]]
(when h
(cons (inc h)
(my-inc t))))exit condition
37. with
Functional schmunctional
● functions as values
● immutable (persistent) data structures
● pure functions
● recursion
● lazy evaluation
destructuring:
pattern-match your input
(defn my-inc [[h & t]]
(when h
(cons (inc h)
(my-inc t))))
38. with
Functional schmunctional
● functions as values
● immutable (persistent) data structures
● pure functions
● recursion
● lazy evaluation
def my-inc(s) {
def res = []
for(i in s)
res << i + 1
res
}
(defn my-inc [[h & t]]
(when h
(cons (inc h)
(my-inc t))))
39. with
What if the input is infinite?
(defn my-inc [[h & t]]
(when h
(cons (inc h)
(my-inc t))))
40. with
Kaboom!
(defn my-inc [[h & t]]
(when h
(cons (inc h)
(my-inc t))))
with no tail call optimisation (TCO),
recursive invocations blows up the stack
41. with
Working around the lack of TCO
(defn my-inc [s]
(loop [res () rem s]
(let [[h & t] rem]
(if h
(recur (cons (inc h) res) t)
res))))
42. with
Working around the lack of TCO
(defn my-inc [s]
(loop [res () rem s]
(let [[h & t] rem]
(if h
(recur (cons (inc h) res) t)
res))))
ECMAScript 6
Java 9 (?)
43. with
Functional schmunctional
● functions as values
● immutable (persistent) data structures
● pure functions
● recursion
● lazy evaluation
(defn lazy-inc [[h & t]]
(lazy-seq
(when h
(cons (inc h)
(lazy-inc t))))
44. with
Functional schmunctional
● functions as values
● immutable (persistent) data structures
● pure functions
● recursion
● lazy evaluation
(defn lazy-inc [[h & t]]
(lazy-seq
(when h
(cons (inc h)
(lazy-inc t))))
retuns a “thunk”
45. with
What if the input is infinite?
(defn lazy-inc [[h & t]]
(lazy-seq
(when h
(cons (inc h)
(lazy-inc t)))))
46. with
What if the input is infinite?
(defn lazy-inc [[h & t]]
(lazy-seq
(when h
(cons (inc h)
(lazy-inc t)))))
48. with
Thanks!
Carlo Sciolla
p r o f e s s i o n a l t i n k e r e r
https://twitter.com/skuro
https://github.com/skuro
http://skuro.tk
http://amsclj.nl