OKC-FP 2016 - Introduction to Functional Programming

126
Welcome to OKC- FP

Transcript of OKC-FP 2016 - Introduction to Functional Programming

Page 1: OKC-FP 2016 - Introduction to Functional Programming

Welcome to OKC-FP

Page 2: OKC-FP 2016 - Introduction to Functional Programming

Organizers

Jordan ParmerJessica

CampbellJeff Smith

Alex AdriaanseMike Hayes

Page 3: OKC-FP 2016 - Introduction to Functional Programming

Where to Follow Us?meetup.com okcfp.comTwitter @fp_okcSlack #okc-fp

Page 4: OKC-FP 2016 - Introduction to Functional Programming

User Group Topics

Functional Programming ConceptsLanguages

Libraries, Frameworks, Projects, Tools

Page 5: OKC-FP 2016 - Introduction to Functional Programming

What is Functional Programming?

Page 6: OKC-FP 2016 - Introduction to Functional Programming

hello!Jordan Parmer

@ProfParmer

Page 7: OKC-FP 2016 - Introduction to Functional Programming

A Very Short Story

Page 8: OKC-FP 2016 - Introduction to Functional Programming

Page 9: OKC-FP 2016 - Introduction to Functional Programming

“We are builders first; technologists second

Page 10: OKC-FP 2016 - Introduction to Functional Programming

“The better builders we are, the more value we provide.

Page 11: OKC-FP 2016 - Introduction to Functional Programming

1.What is Functional

Programming?

Page 12: OKC-FP 2016 - Introduction to Functional Programming

What Does It Mean to be Imperative?

Page 13: OKC-FP 2016 - Introduction to Functional Programming

What Are The Most Common Problems In

Imperative OOP Code?

Page 14: OKC-FP 2016 - Introduction to Functional Programming

Null Pointer ExceptionsConcurrency Errors With Shared State

Broad Context of ReasoningDeep Inheritance Chains

Mutable State

Page 15: OKC-FP 2016 - Introduction to Functional Programming

What is the emphasis with imperative OOP

code?

Page 16: OKC-FP 2016 - Introduction to Functional Programming

Inheritance over composition

Abstraction by Inheritance

Internal class state and encapsulation

Imperative state mutations

Page 17: OKC-FP 2016 - Introduction to Functional Programming

Can We Do Better?

Page 18: OKC-FP 2016 - Introduction to Functional Programming

Return to Roots

Page 19: OKC-FP 2016 - Introduction to Functional Programming

“A functional programming language is a language that

emphasises programming with pure functions and immutable

data

Page 20: OKC-FP 2016 - Introduction to Functional Programming

Functional ProgrammingDeclarativeDescribe what, not howExpressions over statements

IdempotentImmutabilityFunctions are without side-effectsResults deterministic

Referentially TransparentAny expression can be replaced with the results of its value

AlgebraicTypes, equality, expressionsCategory theory

Functionally ComposableSeparate behavior from dataSmall functions composed together to make small building blocks

ParallelizableIdempotent code by nature enables local and distributed parallelization

Page 21: OKC-FP 2016 - Introduction to Functional Programming

Myths✘Requires a math degree to understand

✘Targets only math/science problems

✘Only relevant in academic circles

✘Not for “Line of Business” or “Form Over Data” apps

Page 22: OKC-FP 2016 - Introduction to Functional Programming

LIES!

Page 23: OKC-FP 2016 - Introduction to Functional Programming

Shocking Adjustments✘No Null✘Recursion over looping✘Avoidance of if-statements✘Map/filter/fold over iterating✘Monadic I/O✘Lots of foreign mathematical nomenclature✘No debuggers

Page 24: OKC-FP 2016 - Introduction to Functional Programming

“OOP makes code understandable by encapsulating moving parts.

FP makes code understandable by minimizing moving parts.

✘Michael Feathers

Page 25: OKC-FP 2016 - Introduction to Functional Programming

We Want These

Page 26: OKC-FP 2016 - Introduction to Functional Programming

You Don’t Need a Functional Language To

Be Functional

Page 27: OKC-FP 2016 - Introduction to Functional Programming

But It Does Help

Page 28: OKC-FP 2016 - Introduction to Functional Programming

Some [Subjective] ExamplesPure-ish

✘ Haskell✘ Erlang✘ Elm✘ Hope✘ Joy✘ Mercury✘ Scheme

Hybrids✘ Scala✘ F#✘ Kotlin✘ Swift✘ ML✘ LISP✘ Rust✘ Groovy✘ R✘ Dart✘ Ruby

Progressively Incorporating✘ Java 8✘ C#✘ Python✘ C++ 11

...and many more

Page 29: OKC-FP 2016 - Introduction to Functional Programming

Popular Languages

Beware Bias Ahead

Page 30: OKC-FP 2016 - Introduction to Functional Programming

JVM LanguagesScala

✘ Statically strong typed✘ FP with OOP good parts✘ Higher-order functions ✘ Insanely advanced type system✘ Currying, lazy-evaluation, pattern matching, etc.✘ Large commercial adoption

Twitter, Spotify, LinkedIn, Apache Spark, Kafka, etc.

✘ Backed by Lightbend + Scala Centre

Clojure✘ Dynamically typed✘ First-order functions✘ S-expressions✘ LISP-dialect

“Modern LISP that is symbiotic with Java”

Page 31: OKC-FP 2016 - Introduction to Functional Programming

.NET Languages

F#✘ Statically typed✘ Multi-paradigm: FP, imperative, OOP✘ .NET Framework✘ Visual Studio Tooling✘ Backed by Microsoft

Page 32: OKC-FP 2016 - Introduction to Functional Programming

Apple Languages

Swift✘ Scala...brought to you by Apple

I kid! I kid!

✘ FP alternative to Objective C✘ Borrowed some constructs from C & Objective

C✘ Optional types✘ Categories (i.e. type-classes)

Page 33: OKC-FP 2016 - Introduction to Functional Programming

Erlang Languages

Erlang✘ Ideal for distributed systems✘ Fault-tolerant, real-time✘ Highly-available systems✘ BEAM virtual machine

Elixir✘ Higher abstractions on top of Erlang

Reduces boilerplate✘ Runs on BEAM✘ New language but closely related to Erlang

Page 34: OKC-FP 2016 - Introduction to Functional Programming

Purist Languages

Haskell✘ Purely functional✘ Named after Haskell Curry✘ Strong type system✘ Introduced type-classes✘ Strict immutability

Elm✘ FP for the web✘ Graphical layout without destructive updates✘ Interops with (not compiles to)

JavaScript/CSS/HTML

Page 35: OKC-FP 2016 - Introduction to Functional Programming

...And So Many More

Page 36: OKC-FP 2016 - Introduction to Functional Programming

But What Does That All Mean?

Page 37: OKC-FP 2016 - Introduction to Functional Programming

Let’s Talk About Some FP Concepts

Page 38: OKC-FP 2016 - Introduction to Functional Programming

The SuspectsPure Functions

ExpressionsType Systems

Function ChainingMap, Filter, Fold

Functors, Monoids, Monads

Page 39: OKC-FP 2016 - Introduction to Functional Programming

Side-Effects Are The Source of Many Woes

Page 40: OKC-FP 2016 - Introduction to Functional Programming

Consider Algebra

Page 41: OKC-FP 2016 - Introduction to Functional Programming

f(x) = 3x2-7x+5Given the above

Find f(-4)

Page 42: OKC-FP 2016 - Introduction to Functional Programming

f(x) = 3x2-7x+5Given the above

Find f(-4)81

Page 43: OKC-FP 2016 - Introduction to Functional Programming

Function Has Side-Effects If It...✘Modifies a variable✘Modifies a data structure in place

e.g. append to linked list✘Throws an exception✘Prints to the console✘Writes to a file✘Updates a database✘Draws to the screen

Page 44: OKC-FP 2016 - Introduction to Functional Programming

Function Has Side-Effects If It...✘Modifies a variable✘Modifies a data structure in place

e.g. append to linked list✘Throws an exception✘Prints to the console✘Writes to a file✘Draws to the screen

Have you ever passed a reference of a list to

something else?

Page 45: OKC-FP 2016 - Introduction to Functional Programming

Single InputSingle OutputNo side effectsReferentially transparent Func

A B

Function Is Pure If It...

Page 46: OKC-FP 2016 - Introduction to Functional Programming

Functional VS Imperative OOP

Pure functions are easy to test

Local reasoning

In => OutVS

Objects are hard to test

Encapsulated state

Context

Global reasoning

Page 47: OKC-FP 2016 - Introduction to Functional Programming

Functional VS Imperative OOP

Pure functions are easy to re-use

Low risk

Little-to-no dependencies

VSWe are terrible at making truly reusable objects

Challenges of tight coupling

Hard to abstract at correct level

Page 48: OKC-FP 2016 - Introduction to Functional Programming

Functional VS Imperative OOP

Pure functions are easy to parallelize

State in isolation

Just lego piecesVS

Sharing is cool in life...not in threads

How many concurrency patterns do we need to deal with shared state?

Page 49: OKC-FP 2016 - Introduction to Functional Programming

Functional VS Imperative OOP

Pure functions reduce need for most OOP design patterns VS

‘Cause who doesn’t want to know about your MVVMVMVMMVCCC singleton factory observer?

Page 50: OKC-FP 2016 - Introduction to Functional Programming

Function Composition

Page 51: OKC-FP 2016 - Introduction to Functional Programming

Single Input Single Output

Func

A B

Page 52: OKC-FP 2016 - Introduction to Functional Programming

Functions Of This Sort Can Be Things

Func

A B

Page 53: OKC-FP 2016 - Introduction to Functional Programming

Functions Of This Sort Can Be Things

Func

A B

Called Types

Page 54: OKC-FP 2016 - Introduction to Functional Programming

Two Functions

Func

Func

Page 55: OKC-FP 2016 - Introduction to Functional Programming

Compose Them Together

Func

Func

Page 56: OKC-FP 2016 - Introduction to Functional Programming

Compose Them Together

Func

Func

f(g(x))or

F o G x

Page 57: OKC-FP 2016 - Introduction to Functional Programming

New Function!

Func

Page 58: OKC-FP 2016 - Introduction to Functional Programming

Function Composition Is The New Old Injection

Page 59: OKC-FP 2016 - Introduction to Functional Programming

// Goal: Allow brewing coffee with different techniques and beans// Types// Beans => Grind// Grind => Coffee

trait Beanstrait Grindtrait Coffee

case class ColumbianBeans() extends Beans

def brew(grind: Beans => Grind, brew: Grind => Coffee): Beans => Coffee = { brew compose grind}

def burrGrind(beans: Beans): Grind = ???def blendGrind(beans: Beans): Grind = ???

def pourOver(grind: Grind): Coffee = ???def drip(grind: Grind): Coffee = ???def frenchPress(grind: Grind): Coffee = ???

val pourOverWithBurrGrind = brew(burrGrind, pourOver)val myFavoriteBeans = ColumbianBeans()val myFavoriteCoffee = pourOverWithBurrGrind(myFavoriteBeans)

// TIME TO WAKE UP!!!

Page 60: OKC-FP 2016 - Introduction to Functional Programming

// Goal: Allow brewing coffee with different techniques and beans// Types// Beans => Grind// Grind => Coffee

trait Beanstrait Grindtrait Coffee

case class ColumbianBeans() extends Beans

def brew(grind: Beans => Grind, brew: Grind => Coffee): Beans => Coffee = { brew compose grind}

def burrGrind(beans: Beans): Grind = ???def blendGrind(beans: Beans): Grind = ???

def pourOver(grind: Grind): Coffee = ???def drip(grind: Grind): Coffee = ???def frenchPress(grind: Grind): Coffee = ???

val pourOverWithBurrGrind = brew(burrGrind, pourOver)val myFavoriteBeans = ColumbianBeans()val myFavoriteCoffee = pourOverWithBurrGrind(myFavoriteBeans)

// TIME TO WAKE UP!!!

brew is a higher order function

Page 61: OKC-FP 2016 - Introduction to Functional Programming

Expressions

Page 62: OKC-FP 2016 - Introduction to Functional Programming

// Which right triangle that has integers for all sides and all sides equal to// or smaller than 10 has a perimeter of 24?

def rightTriangle = for { c <- 1 to 10 b <- 1 to c a <- 1 to b if ((Math.pow(a,2) + Math.pow(b,2) == Math.pow(c,2)) && (a + b + c == 24)) } yield (a, b, c)

rightTriangle.foreach(println(_))

Answer: [6, 8, 10]

Page 63: OKC-FP 2016 - Introduction to Functional Programming

Type Constraints

Page 64: OKC-FP 2016 - Introduction to Functional Programming

f(x) = 3/xInt => Double

Page 65: OKC-FP 2016 - Introduction to Functional Programming

f(x) = 3/x1 => 3/1 => 3.02 => 3/2 => 1.50 => 3/0 => ???

Page 66: OKC-FP 2016 - Introduction to Functional Programming

f(x) = 3/x1 => 3/1 => 3.02 => 3/2 => 1.50 => 3/0 => ???

AH, PICKLES!

Page 67: OKC-FP 2016 - Introduction to Functional Programming

f(x) = 3/x1 => 3/1 => 3.02 => 3/2 => 1.50 => 3/0 => ???

THROW AN EXCEPTION?

Page 68: OKC-FP 2016 - Introduction to Functional Programming

f(x) = 3/xInt => Double

0 => 3/0 => ???

THROW AN EXCEPTION?

THEN THIS IS A LIE!

Page 69: OKC-FP 2016 - Introduction to Functional Programming

f(x) = 3/xInt => Double

0 => 3/0 => ???

THROW AN EXCEPTION?

THEN THIS IS A LIE!

Are You A Liar?

Page 70: OKC-FP 2016 - Introduction to Functional Programming

But Functions Are Types!

Types Don’t Have to Be Open to All

Circumstances

Page 71: OKC-FP 2016 - Introduction to Functional Programming

f(x) = 3/xNonZeroInt => Double

Just Became Constrained And Self-Documented

Page 72: OKC-FP 2016 - Introduction to Functional Programming

f(x) = 3/x Zero Not Allowed BY NonZeroInt

-1 => 3/-1 => -31 => 3/1 => 3

2 => 3/2 => 1.5

Page 73: OKC-FP 2016 - Introduction to Functional Programming

Alternatively Extend Output to Be Monadic

Page 74: OKC-FP 2016 - Introduction to Functional Programming

f(x) = 3/xInt => Option[Double]

2 => 3/2 => Some(1.5)

0 => 3/0 => None

Page 75: OKC-FP 2016 - Introduction to Functional Programming

Static Types Just Became Enforced

Domain Documentation

Page 76: OKC-FP 2016 - Introduction to Functional Programming

Function Types Just Became Interfaces

Page 77: OKC-FP 2016 - Introduction to Functional Programming
Page 78: OKC-FP 2016 - Introduction to Functional Programming

We Sometimes Refer to Our Programs as an

“Algebra”

Page 79: OKC-FP 2016 - Introduction to Functional Programming

If It Compiles, It Probably Works

Page 80: OKC-FP 2016 - Introduction to Functional Programming

FP LOVES Collections

Page 81: OKC-FP 2016 - Introduction to Functional Programming

The Functional TrinityMap

Filter Fold

Page 82: OKC-FP 2016 - Introduction to Functional Programming

Mapval list = List(1, 2, 3, 4, 5)list.map(x => x + 100)

[101, 102, 103, 104, 105]

Map transforms an A to a B

Page 83: OKC-FP 2016 - Introduction to Functional Programming

Filterval list = List(1, 2, 3, 4, 5)list.filter(x => x > 3)

[4, 5]

Filter applies a predicate to each member in the set

Page 84: OKC-FP 2016 - Introduction to Functional Programming

Foldval list = List(1, 2, 3, 4, 5)list.fold(0)((x, y) => x + y)

15

Equivalent to…(((((0 + 1) + 2 )+ 3) + 4) + 5)

Fold applies a binary operation with each member and the result of the previous application

Page 85: OKC-FP 2016 - Introduction to Functional Programming

Function Chaining

Page 86: OKC-FP 2016 - Introduction to Functional Programming

def foo(): Thing = { val x = DoAThing() if (x != null) { val y = DoAnotherThing(x) if (y != null) { val z = DoYetAnotherThing(y) if (z != null) { return z } else { return null } } else { return null } } else { return null }}

Page 87: OKC-FP 2016 - Introduction to Functional Programming

def foo(): Thing = { val x = DoAThing() if (x != null) { val y = DoAnotherThing(x) if (y != null) { val z = DoYetAnotherThing(y) if (z != null) { return z } else { return null } } else { return null } } else { return null }}

Yeah, I know this is bad.

But you know you’ve

seen this before.

Hang with me.

Page 88: OKC-FP 2016 - Introduction to Functional Programming

def foo(): Thing = { val x = DoAThing() if (x != null) { val y = DoAnotherThing(x) if (y != null) { val z = DoYetAnotherThing(y) if (z != null) { return z } else { return null } } else { return null } } else { return null }}

Pyramid of Doom

Page 89: OKC-FP 2016 - Introduction to Functional Programming

def foo(): Thing = { val x = DoAThing() if (x != null) { val y = DoAnotherThing(x) if (y != null) { val z = DoYetAnotherThing(y) if (z != null) { return z } else { return null } } else { return null } } else { return null }}

Pyramid of Doom

The Only Lines Doing

Work

That’s only 20%!

Page 90: OKC-FP 2016 - Introduction to Functional Programming

def foo(): Thing = { val x = DoAThing() if (x != null) { val y = DoAnotherThing(x) if (y != null) { val z = DoYetAnotherThing(y) if (z != null) { return z } else { return null } } else { return null } } else { return null }}

Pyramid of Doom

Look at all those nulls!

Half this code is null checking.

Nulls are a serious code

smell!

Page 91: OKC-FP 2016 - Introduction to Functional Programming

def foo(): Thing = { val x = DoAThing() if (x != null) { val y = DoAnotherThing(x) if (y != null) { val z = DoYetAnotherThing(y) if (z != null) { return z } else { return null } } else { return null } } else { return null }}

Pyramid of Doom

Look at all those nulls!

Half this code is null checking.

Nulls are a serious code

smell!

Null Pointer Exceptions Waiting to Happen

Page 92: OKC-FP 2016 - Introduction to Functional Programming

def foo(): Thing = { val x = DoAThing() if (x != null) { val y = DoAnotherThing(x) if (y != null) { val z = DoYetAnotherThing(y) if (z != null) { return z } else { return null } } else { return null } } else { return null }}

Pyramid of Doom

Throw in async operations, we can

create the same pyramid with

nested callbacks.

Page 93: OKC-FP 2016 - Introduction to Functional Programming

FP to the Rescue!

Page 94: OKC-FP 2016 - Introduction to Functional Programming

def foo(): Option[Int] = { for { x <- DoAThing() y <- DoAnotherThing(x) z <- DoYetAnotherThing(y) } yield z}

Page 95: OKC-FP 2016 - Introduction to Functional Programming

def foo(): Option[Int] = { for { x <- DoAThing() y <- DoAnotherThing(x) z <- DoYetAnotherThing(y) } yield z}

Every line is significant

Page 96: OKC-FP 2016 - Introduction to Functional Programming

def foo(): Option[Int] = { for { x <- DoAThing() y <- DoAnotherThing(x) z <- DoYetAnotherThing(y) } yield z} Boom!

Every line is significant

Page 97: OKC-FP 2016 - Introduction to Functional Programming

Success or Failure?

Page 98: OKC-FP 2016 - Introduction to Functional Programming

def foo(): Option[Int] = { for { x <- DoAThing() y <- DoAnotherThing(x) z <- DoYetAnotherThing(y) } yield z}

foo().map { fooResult => // do stuff with result of foo}

foo() match { case Some(x) => // result of foo case None => // problem case}OR

Page 99: OKC-FP 2016 - Introduction to Functional Programming

def foo(): Option[Int] = { for { x <- DoAThing() y <- DoAnotherThing(x) z <- DoYetAnotherThing(y) } yield z}

foo().map { fooResult => // do stuff with result of foo}

foo() match { case Some(x) => // result of foo case None => // problem case}OR

Map function will only apply when there is

something in the result

A Some[T]

This is not the same as a conditional. Compiler will warn if missing algebraic type checking.

Page 100: OKC-FP 2016 - Introduction to Functional Programming

def foo(): Option[Int] = { for { x <- DoAThing() y <- DoAnotherThing(x) z <- DoYetAnotherThing(y) } yield z}

foo() match { case Some(x) => // result of foo case None => // problem case}

Instead of None, we could use our own custom types to represent error states. Remember, types are enforced documentation!

Page 101: OKC-FP 2016 - Introduction to Functional Programming

sealed trait OperationResult[+T]final case class OperationSuccess(result: T) extends OperationResult[T]final case class OperationFailure(error: Throwable) extends OperationResult[Nothing]

def foo(): OperationResult[Int] = { for { x <- DoAThing() y <- DoAnotherThing(x) z <- DoYetAnotherThing(y) } yield z}

foo() match { case OperationSuccess(v) => // do something with v case OperationFailure(e) => // do something with error}

Compiler will enforce this as an algebraic proof.

We’ve encoded rich information in our API.

Chained workflow.

Page 102: OKC-FP 2016 - Introduction to Functional Programming

Application Becomes a Collection of Pure

Functions

Page 103: OKC-FP 2016 - Introduction to Functional Programming

Just Fold the Collection

Page 104: OKC-FP 2016 - Introduction to Functional Programming
Page 105: OKC-FP 2016 - Introduction to Functional Programming

ParallelizationFold All the Pieces!

Page 106: OKC-FP 2016 - Introduction to Functional Programming

MonadsThe Key to a Lot of Awesome

And confusion

Page 107: OKC-FP 2016 - Introduction to Functional Programming

Functors, Monoids, and Bears

Page 108: OKC-FP 2016 - Introduction to Functional Programming

Functor

A => B

Page 109: OKC-FP 2016 - Introduction to Functional Programming

Monoid

Type AIdentity Function

Binary Combinator

Page 110: OKC-FP 2016 - Introduction to Functional Programming

Monad

Type with a Functor + FlatMap

Page 111: OKC-FP 2016 - Introduction to Functional Programming

State

Page 112: OKC-FP 2016 - Introduction to Functional Programming

State

State stays in box

Page 113: OKC-FP 2016 - Introduction to Functional Programming

State

The box is a “monad”

Page 114: OKC-FP 2016 - Introduction to Functional Programming

State

Think of monad as

collection of at most one

item

Page 115: OKC-FP 2016 - Introduction to Functional Programming

State

You can do collection things to monads

.map(...)

.flatMap(...)

.fold(...)

.filter(...)

.collect(...)

.head

Page 116: OKC-FP 2016 - Introduction to Functional Programming

State

If Monad is “empty”, applied functions are ignored

.map(...)

.flatMap(...)

.fold(...)

.filter(...)

.collect(...)

.head

Page 117: OKC-FP 2016 - Introduction to Functional Programming

def foo(): Option[Int] = Some(100)

val myFoo = foo()

val result = myFoo .map(i => i + 100) .map(i => i.toString) .map(i => i + " is a bigger number") .getOrElse("didn't do anything")

// result = "200 is a bigger number"

Page 118: OKC-FP 2016 - Introduction to Functional Programming

def foo(): Option[Int] = None

val myFoo = foo()

val result = myFoo .map(i => i + 100) .map(i => i.toString) .map(i => i + " is a bigger number") .getOrElse("didn't do anything")

// result = "didn’t do anything"

Executed but not applied

Page 119: OKC-FP 2016 - Introduction to Functional Programming

Monads are so much more but let’s keep it

simple for now…

...another talk to come

Page 120: OKC-FP 2016 - Introduction to Functional Programming

2.

Common Applications

Page 121: OKC-FP 2016 - Introduction to Functional Programming

Trends in Functional Programming

Data Processing Streaming Parallelizatio

n

Machine Learning

Heavy Computation Attracting

Talent

Page 122: OKC-FP 2016 - Introduction to Functional Programming

3.

Disadvantages?

Page 123: OKC-FP 2016 - Introduction to Functional Programming
Page 124: OKC-FP 2016 - Introduction to Functional Programming

4.

Final Thoughts

Page 125: OKC-FP 2016 - Introduction to Functional Programming

Natural way to migrate To Functional

Programming?

Page 126: OKC-FP 2016 - Introduction to Functional Programming

thanks!Any questions?

You can find me at@ProfParmer