Date post: | 15-Jul-2015 |
Category: |
Software |
Upload: | carlo-sciolla |
View: | 279 times |
Download: | 1 times |
The package contains● functions as values
● immutable (persistent) data structures
● pure functions
● recursion
● lazy evaluation
with
with
The package contains● functions as values
● immutable (persistent) data structures
● pure functions
● recursion
● lazy evaluation
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
with
Clojure data anatomy
1 2.0 3/4 ; numbersfoo bar ; symbols:one :two ; keywords“value” ; stringstrue false ; bools\a \b \c ; charsnil ; null
with
Clojure data anatomy
[1 2 3] ; vector‘(foo bar) ; list#{:one :two} ; set{:key “value”} ; map
with
Clojure data anatomy
[1 2 3] ; vector‘(foo bar) ; list#{:one :two} ; set{:key “value”} ; map
with
Clojure code anatomy
(* 132.715 (- 1.06 1.02))
-> 5.308600000000005nested unquoted lists, in facts:
“The name LISP derives from "LISt Processing".” -- Wikipedia
with
Clojure code anatomy
(* 132.715 (- 1.06 1.02))
-> 5.308600000000005no “return”: everything is an expression
with
Clojure beer anatomy
(* 132.715 (- 1.06 1.02))
-> 5.31º
Alcohol by volume formula (Wikipedia):
with
The Reader
Or:HowI
LearnedToStop
WorryingAndLoveTheEval
(* 132.715 (- 1.06 1.02))
*
132.715 -
1.06 1.02
with
The Reader
Or:HowI
LearnedToStop
WorryingAndLoveTheEval
(* 132.715 (- 1.06 1.02))
*
132.715 -
1.06 1.02
with
The Reader
Or:HowI
LearnedToStop
WorryingAndLoveTheEval
(* 132.715 (- 1.06 1.02))
STAR
132.715 -
1.06 1.02
The symbol * evaluates to:clojure.core/_STAR_
with
The Reader
Or:HowI
LearnedToStop
WorryingAndLoveTheEval
(* 132.715 (- 1.06 1.02))
STAR
132.715 -
1.06 1.02
Values evaluate to themselves
with
The Reader
Or:HowI
LearnedToStop
WorryingAndLoveTheEval
(* 132.715 (- 1.06 1.02))
STAR
132.715 -
1.06 1.02
with
The Reader
Or:HowI
LearnedToStop
WorryingAndLoveTheEval
(* 132.715 (- 1.06 1.02))
STAR
132.715
SUB
1.06 1.02
The symbol - evaluates to:clojure.core/_
with
The Reader
Or:HowI
LearnedToStop
WorryingAndLoveTheEval
(* 132.715 (- 1.06 1.02))
STAR
132.715
SUB
1.06 1.02
Values evaluate to themselves
with
The Reader
Or:HowI
LearnedToStop
WorryingAndLoveTheEval
(* 132.715 (- 1.06 1.02))
STAR
132.715
SUB
1.06 1.02
Values evaluate to themselves
with
The Reader
Or:HowI
LearnedToStop
WorryingAndLoveTheEval
(* 132.715 (- 1.06 1.02))
STAR
132.715
SUB
1.06 1.02
All args evaluated? Function call!
with
The Reader
Or:HowI
LearnedToStop
WorryingAndLoveTheEval
(* 132.715 (- 1.06 1.02))
STAR
132.715
0.04
All args evaluated? Function call!
with
The Reader
Or:HowI
LearnedToStop
WorryingAndLoveTheEval
(* 132.715 (- 1.06 1.02))
STAR
132.715
0.04
All args evaluated? Function call!
with
The Reader
Or:HowI
LearnedToStop
WorryingAndLoveTheEval
5.31
(* 132.715 (- 1.06 1.02))
All args evaluated? Function call!
with
The Reader
Or:HowI
LearnedToStop
WorryingAndLoveTheEval
(* 132.715 (- 1.06 1.02))
with
Naming stuff: global bindings
(def scalar 42)
(def fun (fn [a b] (+ a b)))
(defn moar-fun [a b] (+ a b)))
with
Naming stuff: lexical bindings
(let [one “one” key (keyword one)] key)
; => :one
with
Ready to go● functions as values
● immutable (persistent) data structures
● pure functions
● recursion
● lazy evaluation
with
Functional schmunctional● functions as values
● immutable (persistent) data structures
● pure functions
● recursion
● lazy evaluation(defn compose [f g] (fn [x] (f (g x))))
with
Functional schmunctional● functions as values
● immutable (persistent) data structures
● pure functions
● recursion
● lazy evaluation(defn compose [f g] (fn [x] (f (g x))))
returns a function
accepts functions in input
with
Functional schmunctional● functions as values
● immutable (persistent) data structures
● pure functions
● recursion
● lazy evaluation(defn compose [f g] (fn [x] (f (g x))))
((compose inc dec) 42); => 42
with
Functional schmunctional● functions as values
● immutable (persistent) data structures
● pure functions
● recursion
● lazy evaluation(let [foo [{:pi 3.14} {:g 9.8}]] (conj foo {:phi 1.62}))
; => [{:pi 3.14} {:g 9.8} {:phi 1.63}]
with
Functional schmunctional● functions as values
● immutable (persistent) data structures
● pure functions
● recursion
● lazy evaluation(let [foo [{:pi 3.14} {:g 9.8}]] (conj foo {:phi 1.62}) (count foo)) ; => 2
3.14:pi
foo foo’
9.8:g 1.62:phi
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
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
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
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
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))))
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))))
with
What if the input is infinite?
(defn my-inc [[h & t]] (when h (cons (inc h) (my-inc t))))
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
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))))
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 6Java 9 (?)
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))))
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”
with
What if the input is infinite?
(defn lazy-inc [[h & t]] (lazy-seq (when h (cons (inc h) (lazy-inc t)))))
with
What if the input is infinite?
(defn lazy-inc [[h & t]] (lazy-seq (when h (cons (inc h) (lazy-inc t)))))
with
Q / A
with
Thanks!
Carlo Sciollap 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