An intro to functional programming via clojure
I'm @robashton
Background in C++ and C#
Written too much JS
Learned Clojure two years ago
Now a full-time Erlang developer
I care about building stuff
What's wrong with functional programming?
"All told, a monad in X is just a monoid in the category of endofunctors of X, with product × replaced by composition of endofunctors and unit set by the identity endofunctor'
Saunders Mac Lane
What's right with functional programming?
Carefully controlled
side effects
small amounts of
Data-oriented code
A focus on algorithmic thinking
(and then it depends further on the language)
Clojure
It's a lisp
It runs on the JVM
It's pretty pragmatic
A lisp?
LISt Processing
(how (do (you (like (these (parens?))))))
Polish prefix notation
3 + 4
Polish prefix notation
+ 3 4
Stick a paren in it
(+ 3 4)
Or functions
println("Hello World")
Or functions
(println "Hello World")
Why the parens???
(* (+ 3 4) 5)
Now we can read lisp
Let's talk mutability
Demo: Some Javascript
What went wrong?
> var bob = { name: "bob" }
{ name: 'bob' }
> lib.waveAt(bob)
Waving at bob
> lib.waveAt(bob)
Waving at Alice
Mutability
I'd do a demo where this happens in Clojure,
but it won't let me
Let's write some clojure
WE learned
- How to make basic maps
- How to "mutate" them
- Why Bob can't become Alice by accident
Persistent data structures
(Demo)
PErsistent data structures
Lots of shared data
Rather hidden from the devs
Making code go fast
What other data structures?
Everything is either a map or a collection or an operation on a map or a collection*
*Massive over simplification, but we'll survive
Demo
Let's look at collections too
How about functions?
Demo: Functions
(defn wave-at [person] (println "Waving at" (:name person)))
We learned
- What a function looks like and how you define it
- That Clojure has "vectors []" and lists "()"
Change is obvious
To effect change in a function, your return value is the changed object
This is a clear contract of change.
getting functional
(assoc bob :age (inc (:age bob)))
Getting functional
(update-in bob [:age] inc)
Composition
(map (comp logans-law level-up)
(sample-population))
But what about those parens??
Let me show you some editor tricks*
*emacs is better for this, but I'm married to vim
Parens are amazing
Learn to love them
Let's talk tooling
Leiningen
Package manager for Clojure
Built on top of Maven
This is how you get started
The REPL
All development should be done in the REPL
- Fast iterative feedback
- A focus on composition of understandable logic
- If you're compiling and running, you're doing it wrong.
"lein repl"
Editor integration
It doesn't matter what you use, but having REPL integration with your editor is almost mandatory
I'm using
- vim-fireplace
- vim-redl
- vim-clojure
- vim-paredit
Let's talk data
A lot of complexity is caused by wrapping data up in types in languages like C#
class Farm<Pig>
class AbstractAnimal
class Pig : Animal
Sometimes a pig is just a pig
{ :name "Henry" :species :pig }
And a farm is just a list of pigs
Your functionality is just a map or a reduce away
KEep things simple
- A map is usually all you need
- Keep them flat and simple
- Use clojure.core for all the things
Opaque data means more code
Side effects
Often the trick to good functional code is using pure functional code to set-up a sequence of actions and then piping the result into a side effect.
File writing
Networking
Drawing on the screen
Mutable data in Clojure
Does exist (uses STM)
(def x (atom 0))
(swap! x inc)
Mutable data in clojure
You almost never need it until you need it
Do it without until told otherwise
Recursion is normally better
That's all we have time for :(
Check out
- https://www.4clojure.com/
- http://clojurekoans.com/
- http://www.lighttable.com/
The best way to learn is to build, go build!
Questions?
intro-to-functional-programming-clojure
By Rob Ashton
intro-to-functional-programming-clojure
- 2,132