92 lines
2.7 KiB
Clojure
92 lines
2.7 KiB
Clojure
(chapter "Custom Functions")
|
|
|
|
(section "Simple Functions")
|
|
(example "Define function"
|
|
(defn square [x] (* x x)))(example "Use function"
|
|
(square 8))
|
|
(example "Multi-arg functions"
|
|
(defn mul-add [a b c] (+ (* a b) c))
|
|
(mul-add 3 10 5))
|
|
(example "Nullary function"
|
|
(defn nullary [] 10)
|
|
(nullary))
|
|
(example "Anonymous functions"
|
|
((fn [x] (+ x x)) 10)
|
|
(#(+ % %) 10)
|
|
(#(+ %1 %2) 10 20))
|
|
(example "Functions as values"
|
|
(defn twice [f] (fn [a] (f (f a))))
|
|
((twice square) 3))
|
|
|
|
(section "Recursive Functions")
|
|
(example "Recursive Fibonacci"
|
|
(defn rec-fib [n]
|
|
(cond
|
|
(== 0 n) 1
|
|
(== 1 n) 1
|
|
:else (+ (rec-fib (- n 1))
|
|
(rec-fib (- n 2)))))
|
|
(rec-fib 40))
|
|
(example "Memoized Fibonacci"
|
|
(def mem-fib
|
|
(memoize
|
|
(fn [n]
|
|
(cond
|
|
(== 0 n) 1
|
|
(== 1 n) 1
|
|
:else (+ (mem-fib (- n 1)) (mem-fib (- n 2)))))))
|
|
(mem-fib 90))
|
|
(example "Tail-recursive Fibonacci"
|
|
(defn iter-fib [n]
|
|
(letfn [(iter-fib' [n a b]
|
|
(if (== 0 n)
|
|
a
|
|
(iter-fib' (- n 1) b (+' a b))))]
|
|
(iter-fib' n 1 1)))
|
|
(iter-fib 90)
|
|
(iter-fib 10000)
|
|
(defn iter-fib-recur [n]
|
|
(letfn [(iter-fib' [n a b]
|
|
(if (== 0 n)
|
|
a
|
|
(recur (- n 1) b (+' a b))))]
|
|
(iter-fib' n 1 1)))
|
|
(iter-fib-recur 10000))
|
|
(example "Explicit loop Fibonacci"
|
|
(defn loop-fib [n]
|
|
(loop [n n a 1 b 1]
|
|
(if (== 0 n)
|
|
a
|
|
(recur (- n 1) b (+ a b)))))
|
|
(loop-fib 90))
|
|
|
|
(section "Pre and Post conditions")
|
|
(example "Fast power"
|
|
(defn power
|
|
"Raises a to the b-th power"
|
|
[a b]
|
|
{:pre [(<= 0 b)]
|
|
:post [(or (zero? b) (zero? a) (zero? (rem % a)))]}
|
|
(cond
|
|
(zero? b) 1
|
|
(even? b) (power (* a a) (quot b 2))
|
|
(odd? b) (* a (power a (dec b))))))
|
|
(example "Pre and postconditions ok"
|
|
(power 2 5)
|
|
(power 2 0)
|
|
(power 0 2))
|
|
(example "Precondition violated"
|
|
(power 2 -5))
|
|
(example "Invalid postcondition"
|
|
(defn ipower
|
|
[a b]
|
|
{:pre [(<= 0 b)]
|
|
:post [(zero? (rem % a)) (<= 0 %)]}
|
|
(power a b)))
|
|
(example "First part of invalid postcondition violated"
|
|
(ipower 2 0)
|
|
(power 2 0))
|
|
(example "Second part of invalid postcondition violated"
|
|
(ipower -2 3)
|
|
(power -2 3))
|