A talk I did at Intertrust on September 18, 2015.
I present some core concepts from functional programming and show how the work done by Chris Okasaki and others on efficient immutable data structures has made it practical to use functional techniques in production programs.
4. 4 SEPTEMBER 2015
Tom Faulhaber
➡ Planet OS CTO
➡ Background in
networking, Unix OS,
visualization, video
➡ Currently working mostly
in “Big Data”
➡ Contributor to the
Clojure programming
language
18. 18 SEPTEMBER 2015
Why functional?
➡ No shared state makes it easier to reason about
programs
➡ Concurrency problems simply go away (almost!)
➡ Undo and backtracking are trivial
➡ Algorithms are often more elegant
It is better to have 100 functions operate on one data
structure than 10 functions on 10 data structures. -
Alan Perlis
19. 19 SEPTEMBER 2015
Why functional?
A host of new languages support the functional model:
- ML, Haskell, Clojure, Scala, Idris
- All with different degrees of purity
25. 25 SEPTEMBER 2015
Persistent Data Structures
The goal: Approximate the performance of mutable
data structures: CPU and memory.
The big secret: Use structural sharing!
There are lots of little secrets, too. We won’t cover
them today.
26. 26 SEPTEMBER 2015
Persistent Data Structures - History
1990 2000 2010
Persistant
Arrays
(Dietz)
ML Language
(1973)
Catenable
Queues
(Buchsbaum/
Tarjan)
Okasaki
Haskell
Language
Clojure
CollectionsFinger Trees
(1977)
Zipper
(Huet)
Data.Map
in Haskell
Priority
Search
Queues
(Hinze)
Fast And
Space Efficient
Trie Searches
(Bagwell)
Ideal Hash
Trees
(Bagwell)
RRB
Trees
(Bagwell/
Rompf)
27. 27 SEPTEMBER 2015
The quick brown dog jumps over
6
Example: Vector
➡ In Java/C# ArrayList; in C++ std::vector.
➡ A list with constant access and update and amortized
constant append.
The quick brown fox jumps over
6 a[3] =“dog”dog
28. 28 SEPTEMBER 2015
Example: Vector
➡ In Java/C# ArrayList; in C++ std::vector.
➡ A list with constant access and update and amortized
constant append.
The quick brown dog jumps over
6 a.push_back(“the”)
The quick brown dog jumps over
7
the
the
The quick brown dog jumps over
7
the
29. 29 SEPTEMBER 2015
Example: Vector
➡ To build a persistent vector, we start with a tree:
Persistent
^
depth =
dlog ne
Data is in
the leaves
6
The quick brown fox jumps over
30. 30 SEPTEMBER 2015
The quick brown fox jumps over
6
0 1 2 3 4 5
000 001 010 011 100 101
LLL LLR LRL LRR RLL RLR
The quick brown fox jumps over
6
0 1 2 3 4 5
000 001 010 011 100 101
LLL LLR LRL LRR RLL RLR
The quick brown fox jumps over
6
0 1 2 3 4 5
000 001 010 011 100 101
LLL LLR LRL LRR RLL RLR
x = a[3]
The quick brown fox jumps over
6
0 1 2 3 4 5
000 001 010 011 100 101
LLL LLR LRL LRR RLL RLR
The quick brown fox jumps over
6
0 1 2 3 4 5
000 001 010 011 100 101
LLL LLR LRL LRR RLL RLR
31. 31 SEPTEMBER 2015
The quick brown fox jumps over
6 7
The quick brown fox jumps over
6 7
The quick brown fox jumps over
6 7
The quick brown fox jumps over
6
b = a.add(“the”)
7
The quick brown fox jumps over
6
the
37. 37 SEPTEMBER 2015
2
4
6
8
10
0 250 500 750 1000
Number of elements
Treedepth
2
4
6
8
10
0 250 500 750 1000
Number of elements
Treedepth
2
4
6
8
10
0 250 500 750 1000
Number of elements
Treedepth
d = 1
d = dlog2 ne
42. 42 SEPTEMBER 2015
2
4
6
8
10
0 250 500 750 1000
Number of elements
Treedepth
d = 1
d = dlog2 ne
2
4
6
8
10
0 250 500 750 1000
Number of elements
Treedepth
d = dlog32 ne
44. 44 SEPTEMBER 2015
Clojure code to implement the walker:
(postwalk
(fn [node]
(if (= :blue (:color node))
(assoc node :color :green)
node))
tree)
Example: Tree Walking
45. 45 SEPTEMBER 2015
Example: Zippers
➡ Allow you to navigate and update a tree across many
operations by “unzipping” it.
46. 46 SEPTEMBER 2015
Takeaways
➡ Functional data structures can approximate the
performance of mutable data structures, but will
usually won’t be quite as fast.
➡ … but not having to do state management often
wins back the difference
➡ We need to choose data structures carefully
depending on how they’re going to be used.
➡ This doesn’t solve shared state, just reduces it. (but
see message passing, software transactional
memory, etc.)
47. 47 SEPTEMBER 2015
References
Chris Okasaki, Purely Functional Data Structures, Doctoral dissertation, Carnegie Mellon University, 1996.
Rich Hickey, “Are We There Yet?” Presentation at the JVM Languages SUmmit, 2009. http://www.infoq.com/
presentations/Are-We-There-Yet-Rich-Hickey
Gerard Huet, "Functional Pearl: The Zipper". Journal of Functional Programming 7 (5): 549–554. doi:10.1017/
s0956796897002864
Jean Niklas L’orange, “Understanding Clojure's Persistent Vectors” Blog post at http://hypirion.com/musings/
understanding-persistent-vector-pt-1.