On Github si14 / fprog-2013-04-slides
SPb FProg, 12 Apr 2013, Dmitry Groshev@lambdadmitry
Вектор:
[1 2 3]
Применение функции:
(foo a b c)
Определение функции:
(defn foo [x y z] (+ x y z))
Анонимная функция, сахарная версия:
(#(map inc %) [1 2 3])
Threading macro:
(-> a (foo b) (bar c d))=
(bar (foo a b) c d)
(->> a (foo b) (bar c d))=
(bar c d (foo b a))
a = 1:2:3:[]
(cons a (cons b (cons c ())))
(defn map [f coll] (cons (f (first coll)) (map f (rest coll))))
foldr f z [] = z foldr f z (x:xs) = f x (foldr f z xs)
(defn reduce [f init coll] (clojure.core.protocols/coll-reduce coll f init))
(reduce + 0 (map inc [1 2 3])) ; allocates chunks!
S.foldl (+) 0 $ S.map (+1) $ S.stream [1, 2, 3] -- does not
val
|
---reduce--
/ | | | | \
| | | | | |
f f f f f f <- map
| | | | | |
a b c d e f
val
|
---reduce--
/ | |
| | |
p p p p p p <- filter
| | | | | |
a b c d e f
(defn mapping [f]
(fn [f1]
(fn [result input]
(f1 result (f input)))))
(defn filtering [pred]
(fn [f1]
(fn [result input]
(if (pred input)
(f1 result input)
result))))
(defn mapcatting [f]
(fn [f1]
(fn [result input]
(reduce f1 result (f input)))))
(defn reduce [f init coll] (clojure.core.protocols/coll-reduce coll f init))
(reduce + 0 (map inc [1 2 3]))
VS
(reduce + 0 (reducer [1 2 3] (mapping inc)))
(defn rmap [f coll] (reducer coll (mapping f)))
(reduce + 0 (rmap inc [1 2 3]))
(defcurried map [f coll] (reducer coll (mapping f)))
(def foo (comp (r/filter even?) (r/map inc))) ; currying! (reduce + (foo [1 1 1 2])) ; 6
(reduce + 0 (parallel-map inc (break-into-chunks data)))
filter это проблема (map отображает 1:1, нужен Maybe)
(combine + 0
(parallel-map #(reduce + 0 (rmap inc %))
(break-into-chunks data)))
combine тоже reduce
reduce отображает M:N
(combine-fn + 0
(parallel-map #(reduce-fn + 0 (rmap inc %))
(break-into-chunks data)))
(r/fold + + (r/map inc (r/filter even? data)))
(def v (into [] (range 10000000))) ; 10m elements (time (reduce + (map inc (filter even? v)))) ; 470-490msec (time (reduce + (r/map inc (r/filter even? v)))) ; 260-290msec (time (r/fold + (r/map inc (r/filter even? v)))) ; 150-160msec (2 cores)
;; Count number of non-empty fields in TSV file
(->> (iota/vec filename)
(r/filter identity) ;; filter out empty lines
(r/map
#(->> (clojure.string/split % #"[\t]" -1)
(filter (fn [^String s] (not (.isEmpty s))))
count))
(r/fold +))
Ссылки: