Top Banner
Thinking Functionally with Clojure by John Stevenson @jr0cket www.practical.li
69

Thinking Functionally with Clojure

Apr 11, 2017

Download

Technology

John Stevenson
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Thinking Functionally with Clojure

Thinking Functionally with Clojureby John Stevenson @jr0cket

www.practical.li

Page 2: Thinking Functionally with Clojure
Page 3: Thinking Functionally with Clojure

Why Functional Programmingit's not just because it's really fun...

Page 5: Thinking Functionally with Clojure

The Complexity Iceberg

- @krisajenkins

● complexity is very dangerous when hidden

● You can't know what a function does for certain if it has side effects

Page 6: Thinking Functionally with Clojure

Side Effects

Side Causes term coined by @krisajenkins

Page 7: Thinking Functionally with Clojure

Pure FunctionsThe results of the function are purely determined by its initial output and its own code

- no external influence, a function only uses local values- referential transparency (the function can be replaced by its value)

Page 8: Thinking Functionally with Clojure

Impure Functions - side causesThe results of the function are purely determined by its initial output and its own code

- behaviour externally influenced and non-deterministic

Page 9: Thinking Functionally with Clojure

Eliminating Side Effects

Functional programming is about eliminating side effects where you can, controlling them where you can't - @krisajenkins

The features in Functional Programming come from a desire to reduce side effects

Page 10: Thinking Functionally with Clojure

ClojureGeneral purpose language hosted on JVM, JavaScript & CLR

Page 11: Thinking Functionally with Clojure

Clojure / ClojureScript

A hosted language with simple interoperability with the host language

- (java.Util.Date.)- (js/alert “Client side apps are easier in Clojure”)

Page 12: Thinking Functionally with Clojure

Clojure - basic syntax for this talk( ) ;; an empty list. The first element of a list is evaluated as a function call

(function-name data) ;; call a function with the data as its argument

(def name “data-or-value”) ;; assign (bind) a name to a data or legal value

:keyword-name ;; a keyword is a name that points to itself

;; Thread-first macro - chain function calls, passing the result of each call as the first argument to the next function. The ,,, indicates where the resulting argument goes.

(-> (function-a “data”) (function-b ,,,) ;; In Clojure commas , are whitespace (function-c ,,, “data”))

Page 13: Thinking Functionally with Clojure

Persistent data structuresBuilt-in Immutability leading to deterministic code

Page 14: Thinking Functionally with Clojure

List, Vector, Map & Set

Clojure’s built-in data structures are all immutable- returning a new data structure when a function is applied

(list 1 2 3 4 5) ‘(“fish” “chips” 42)

(vec ‘(1 2 3 4)) [1 2 3 4]

{:key “value”} {:name “John” :skill “conferencing”}

(set ‘(1 2 3 4 4)) #{1 2 3 4}

Page 15: Thinking Functionally with Clojure

Persistent Data Structures - shared memory

Each function creates a new vector

Memory space for values is shared between each vector

Page 16: Thinking Functionally with Clojure

Persistent Data Structures - shared memory

By sharing memory you can apply functions over and over again effectively

Values persist until they are no longer referenced

Page 17: Thinking Functionally with Clojure

Concurrency is Easier

Concurrency is much easier to write and reason about because of

- Pure functions- Immutability is encouraged by default- Persistent Data Structures- All values are immutable

- unless explicitly wrapped in an atom or ref

- state changes managed atomically (software transactional memory)- core.async library allows you to write asynchronous code as easily as sequential

code

Page 18: Thinking Functionally with Clojure

Using persistent data structuresIterate over collectionsGenerate new collections by applying functions

Page 19: Thinking Functionally with Clojure

Sequence / List Comprehension

Iterate over collections

Page 20: Thinking Functionally with Clojure

Sequence / List Comprehension

Iterating through a range of generated values to create a list of 2 value vectors

Page 21: Thinking Functionally with Clojure

Immutability - local binding

Assignments made locally are immutable

- words is a local binding to the result of running the function upper-case on “Hello World”

- letter->clack is a function that converts a character to a code

Page 22: Thinking Functionally with Clojure

Lazy EvaluationOnly return a value when necessary

● maintain precision● optimise evaluation

Page 23: Thinking Functionally with Clojure

Lazy EvaluationClojure's lazy sequences- returns a reference to a file and step through it one line at a time- line-seq returns a lazy sequence of lines, so we can read files larger than available memory, one line at a time

Page 24: Thinking Functionally with Clojure

PolymorphismFunctions evaluate different algorithms based on arity of arguments

Page 25: Thinking Functionally with Clojure

Recursion & PolymorphismProcess a collection of values by feeding the remaining elements back to the function

- the sum function is polymorphic, it has different behaviours that could be evaluated depending on if passed 1 or 2 arguments

Page 26: Thinking Functionally with Clojure

Recursion - tail call optimisationProtect the heap space from blowing by using the recur function

Using recur in the last line is the same as calling sum, however the memory required from the previous sum function call is over-written in memory. So only 1 memory slot is used instead of 10 billion

Page 27: Thinking Functionally with Clojure

Higher Order FunctionsA function that takes one or more functions as arguments, ora function that returns a function

Page 28: Thinking Functionally with Clojure

Higher Order FunctionsFunctions always return a value & can be used as an argument to another function

Page 29: Thinking Functionally with Clojure

Composing functions togetherExample: current value of the Clojure project from the configuration file- `slurp` in the project file, convert into a string and return the value at index 2

Page 30: Thinking Functionally with Clojure

Design idiom:Composing functions together

You can think of functional design as evaluating one or more functions in series of functions

Page 31: Thinking Functionally with Clojure

Functional Composition - map

Map the function inc over each number of the collection, returns a new collection of numbers incremented by 1

Page 32: Thinking Functionally with Clojure

Functional Composition - reduce

Reduce the numbers inside a collection to a single value by applying the + function,returns a single value

Page 33: Thinking Functionally with Clojure

Higher Order functions - partial, compHigher order functions can return a function

- The comp function composes other functions together - The partial function allows you to lazily add another argument to a function

Page 34: Thinking Functionally with Clojure

Managing StateState changes should be managed easily

Page 35: Thinking Functionally with Clojure

Safe State changes

Changing state safely by not changing it

● Persistent data structures● Local bindings

Changing state safely by changing it atomically

● Software Transactional Memory (STM)○ Gives an mechanism like an in-memory atomic database that manages mutable state changes

under the covers

● Atoms● core.async

Page 36: Thinking Functionally with Clojure

Concurrency syntax - atoms

An online card game has players that can join and have their winnings tracked

Page 37: Thinking Functionally with Clojure

Concurrency syntax - atoms

The join-game function adds players to the atom by their name, but only up to 2 players

Page 38: Thinking Functionally with Clojure

Concurrency syntax - refs for sync updatesThe join-game-safely adds players to the ref and alters their account & game account

Page 39: Thinking Functionally with Clojure

Putting it all togetherLet's find all the most common words used in a popular Science Fiction novel

Page 40: Thinking Functionally with Clojure

ParallelismScale to the maximum

Page 41: Thinking Functionally with Clojure

What is ParallelismIn simple terms: run the same code across multiple CPU’s

Page 42: Thinking Functionally with Clojure

Parallelism - pmappmap - the same as map but in parallel

Page 43: Thinking Functionally with Clojure

Parallelism - reduceSignificantly lower completion time running in parallel using Immutable data structures

https://github.com/aphyr/tesser

Page 44: Thinking Functionally with Clojure

Parallelism - reducers & folds

Page 45: Thinking Functionally with Clojure

Tools to learn Clojureinspire them & build up their motivation

Page 46: Thinking Functionally with Clojure

Clojure support in many different tools

Page 47: Thinking Functionally with Clojure

Leiningen - Clojure powered build automation

Page 48: Thinking Functionally with Clojure
Page 49: Thinking Functionally with Clojure

LightTable - Instarepl

Page 50: Thinking Functionally with Clojure

Emacs & Spacemacs

Page 51: Thinking Functionally with Clojure

Figwheel (flappy birds example)

Page 52: Thinking Functionally with Clojure
Page 53: Thinking Functionally with Clojure

Examples, examples, exampleswe learn by example...

Page 54: Thinking Functionally with Clojure

Over 20 Books on Clojure...

Where to start with Clojure will be different...

Example:

I typically suggested BraveClojure.com as a starting point, however many people prefer LivingClojure or ClojureScript Unraveled...

Help people understand the relevance of a book and if it's the right thing for them at that time.

Page 55: Thinking Functionally with Clojure

Clojure.org & ClojureDocs.org

Page 56: Thinking Functionally with Clojure
Page 57: Thinking Functionally with Clojure

Github

Page 58: Thinking Functionally with Clojure

Clojure-through-code Git repository

Page 59: Thinking Functionally with Clojure

http://practical.li/clojure-webapps

Page 60: Thinking Functionally with Clojure
Page 61: Thinking Functionally with Clojure

Testing your Clojure skills...

Page 62: Thinking Functionally with Clojure
Page 63: Thinking Functionally with Clojure

Clojurian Community in Person

Probably the most active language-specific developer communities in London

Page 64: Thinking Functionally with Clojure

Learning by teaching others

I really started thinking in Clojure when I started talking to & teaching others

- Coding dojos- talks on Clojure (starting with the basics, showing the art of the possible)- moving on to running conferences- workshops at hack days

Page 65: Thinking Functionally with Clojure

Overtone live performance - MetaX

Page 66: Thinking Functionally with Clojure

Overtone live performance - MetaX

Page 67: Thinking Functionally with Clojure

Take your own journey into Clojure

Page 68: Thinking Functionally with Clojure

Thank you

@jr0cketjr0cket.co.uk