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
66
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
84
Golang Concurrency
alexwheeler
0
88
Rewriting Rack: A Functional Approach
alexwheeler
2
140
Man Computer Symbiosis
alexwheeler
0
120
Flipper
alexwheeler
0
130
Character Encodings
alexwheeler
0
120
Featured
See All Featured
Stop Working from a Prison Cell
hatefulcrawdad
271
21k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
29
1.8k
Faster Mobile Websites
deanohume
307
31k
Reflections from 52 weeks, 52 projects
jeffersonlam
351
21k
YesSQL, Process and Tooling at Scale
rocio
173
14k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
26
2.9k
Principles of Awesome APIs and How to Build Them.
keavy
126
17k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
50
5.5k
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
53
2.9k
Build The Right Thing And Hit Your Dates
maggiecrowley
37
2.8k
Build your cross-platform service in a week with App Engine
jlugia
231
18k
Designing for humans not robots
tammielis
253
25k
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