Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Transducers
Search
Alex Wheeler
November 15, 2017
0
64
Transducers
Clojure Transducers
Alex Wheeler
November 15, 2017
Tweet
Share
More Decks by Alex Wheeler
See All by Alex Wheeler
Running Rings Around Rack
alexwheeler
0
83
Golang Concurrency
alexwheeler
0
87
Rewriting Rack: A Functional Approach
alexwheeler
2
120
Man Computer Symbiosis
alexwheeler
0
110
Flipper
alexwheeler
0
120
Character Encodings
alexwheeler
0
110
Featured
See All Featured
What's in a price? How to price your products and services
michaelherold
244
12k
Gamification - CAS2011
davidbonilla
80
5.1k
Building Flexible Design Systems
yeseniaperezcruz
328
38k
The Invisible Side of Design
smashingmag
299
50k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
40
2k
Documentation Writing (for coders)
carmenintech
67
4.6k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
280
13k
Optimizing for Happiness
mojombo
376
70k
A Philosophy of Restraint
colly
203
16k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
44
7k
Principles of Awesome APIs and How to Build Them.
keavy
126
17k
Building Applications with DynamoDB
mza
93
6.2k
Transcript
Transducers
• recast sequence processing functions (map, filter, etc.) as process
transformations
processes • succession of steps • each step ingests an
input
Reducing functions • whatever, input -> whatever
• sources/sinks are irrelevant/unspecified
• sum, number -> sum • (+ 1 2) =>
3
• person, attribute -> person (into {:name "Alex"} {:company “VTS”})
=> {:name "Alex" :company "VTS"}
• vector, input -> vector • (conj [1] 2) =>
[1, 2]
• transducers are: 1. reusable 2. avoid intermediary collections 3.
composable
reusable • every new collection defines own version of map,
filter, etc. • MyCollection->MyCollection (append list 1) • Channel->Channel (>! chan 1) • Sequence->Sequence (conj [] 1)
intermediate collections (1..10).map { |x| x * 2 } .select
{ |x| x > 20 } .reduce { |sum, x| sum + x }
composable (1..10).transduce(&method(:push))
composable (1..10).transduce(&method(:merge))
• Clojure 101
None
(def name "Alex")
(println "Hello " name) => Hello Alex
(fn [x] (* x x))
(defn square [x] (* x x))
((comp inc inc) 1) (inc (inc 1))
(def plus-two (comp inc inc))
• Transducers
None
(map inc [1 2 3 4 5 6]) => (2
3 4 5 7) (filter even? [1 2 3 4 5 6]) => (2 4 6)
• write map, filter in terms of reduce?
map (reduce (fn [result input] (conj result (inc input))) []
[1 2 3 4])
filter (reduce (fn [result input] (if (even? input) (conj result
input) result)) [] [1 2 3 4])
(reduce (fn [result input] (conj result (inc input))) [] [1
2 3 4]) (reduce (fn [result input] (if (even? input) (conj result input) result)) [] [1 2 3 4])
(reduce (fn [result input] (conj result (inc input))) [] [1
2 3 4]) (reduce (fn [result input] (if (even? input) (conj result input) result)) [] [1 2 3 4])
map (reduce (fn [result input] (conj result (inc input))) []
[1 2 3 4])
map (reduce (fn [result input] (conj result (inc input))) []
[1 2 3 4]) (reduce ((fn [f] (fn [result input] (conj result (f input)))) inc) [] [1 2 3 4])
map (reduce (fn [result input] (conj result (inc input))) []
[1 2 3 4]) (reduce ((fn [f] (fn [result input] (conj result (f input)))) dec) [] [1 2 3 4])
filter (reduce (fn [result input] (if (even? input) (conj result
input) result)) [] [1 2 3 4]) (reduce ((fn [predicate] (fn [result input] (if (predicate input) (conj result input) result))) even?) [] [1 2 3 4])
(reduce (fn [result input] (if (even? input) (conj result input)
result)) [] [1 2 3 4]) (reduce ((fn [predicate] (fn [result input] (if (predicate input) (conj result input) result))) odd?) [] [1 2 3 4])
(reduce (fn [result input] (if (even? input) (conj result input)
result)) [] [1 2 3 4]) (reduce ((fn [predicate] (fn [result input] (if (predicate input) (conj result input) result)))(fn [x] (< x 10))) [] [1 2 3 4])
None
what’s the problem? (reduce ((fn [f] (fn [result input] (conj
result (f input))) inc) [] [1 2 3 4]) (reduce ((fn [predicate] (fn [result input] (if (predicate input) (conj result input) even?) result))) [] [1 2 3 4])
(reduce ((fn [f] (fn [result input] (conj result (f input)))
inc) [] [1 2 3 4]) (reduce ((fn [predicate] (fn [result input] (if (predicate input) (conj result input) even?) result))) [] [1 2 3 4])
(reduce ((fn [f] (fn [result input] (conj result (f input)))
inc) [] [1 2 3 4]) (reduce ((fn [predicate] (fn [result input] (if (predicate input) (conj result input) even?) result))) [] [1 2 3 4])
(reduce ((fn [f] (fn [result input] (conj result (f input)))
inc) 0 [1 2 3 4]) (reduce ((fn [predicate] (fn [result input] (if (predicate input) (conj result input) even?) result))) 0 [1 2 3 4])
(reduce ((fn [f] (fn [result input] (conj result (f input)))
inc) stream [1 2 3 4]) (reduce ((fn [predicate] (fn [result input] (if (predicate input) (conj result input) even?) result))) stream [1 2 3 4])
(reduce ((fn [f] (fn [result input] (conj result (f input)))
inc) chan [1 2 3 4]) (reduce ((fn [predicate] (fn [result input] (if (predicate input) (conj result input) even?) result))) chan [1 2 3 4])
(reduce ((fn [f] (fn [result input] (step result (f input)))
inc) file [1 2 3 4]) (reduce ((fn [predicate] (fn [result input] (if (predicate input) (step result input) even?) result))) file [1 2 3 4])
(defn mapping [f] (fn [step] (fn [result input] (step result
(f input))))) (defn filtering [predicate] (fn [step] (fn [result input] (if (predicate input) (step result input) result))))
(defn mapping [f] ;; fn to apply to each input
(fn [step] (fn [result input] (step result (f input)))))
(defn mapping [f] (fn [step] ;; reducing fn that moves
reduction forward (fn [result input] (step result (f input)))))
(defn mapping [f] (fn [step] (fn [result input] ;; reducing
function (step result (f input)))))
• mapping/filtering return transducers • Transducers are functions that accept
a reducing (step) function and return a reducing function
• Note to future self: Alex. Do not go to
the next slide yet. Open vim and show the repl examples.
• map, cat • mapcat, filter • remove, take •
take-while, take-nth • drop, drop-while • replace, partition-by • partition-all, keep • keep-indexed, map-indexed • distinct, interpose • dedupe random-sample