intro to functional programming - confoo

64
Functional Programming [introduction] Félix-Étienne Trépanier

Upload: felixtrepanier

Post on 15-Jul-2015

95 views

Category:

Software


1 download

TRANSCRIPT

Page 1: Intro to functional programming - Confoo

Functional Programming

[introduction]

Félix-Étienne Trépanier

Page 2: Intro to functional programming - Confoo

Call me Félix- Software Engineer - Independant- Code Java / Scala (mainly)- Build Distributed Systems- Organizer of Scala-Montreal

Meetups

Page 3: Intro to functional programming - Confoo

Agenda- Motivations- Definitions and Examples

Page 4: Intro to functional programming - Confoo

Motivations

Page 5: Intro to functional programming - Confoo

What makes programming so hard?

Page 6: Intro to functional programming - Confoo

“Controlling complexity is the essence of computer programming.”- Brian Kernighan

Page 7: Intro to functional programming - Confoo

Complexity comes from input and state.

Possible Inputs

Possible States

Possible OutcomesX =

Page 8: Intro to functional programming - Confoo

We should aim at reducing the input and state space.

Possible Inputs

Possible States

Possible OutcomesX =

Page 9: Intro to functional programming - Confoo

In Object-Oriented programming, everything* is an object.

Page 10: Intro to functional programming - Confoo

Objects combine state and behavior.

Page 11: Intro to functional programming - Confoo

Objects are state machines.

A = xB = y

A = x’B = y’

A = x’B = y

A = xB = y’

Page 12: Intro to functional programming - Confoo

Most objects are badly designed state machines.

A = xB = y

A = x’B = y’

A = x’B = y

A = xB = y’

Page 13: Intro to functional programming - Confoo

Large state space are hard to reason about.

Page 14: Intro to functional programming - Confoo

Concurrency adds new visible states.

A = xB = y

A = x’B = y’

A = x’B = y

A = xB = y’

Page 15: Intro to functional programming - Confoo

How can we write correct code if we can’t reason about it?

Page 16: Intro to functional programming - Confoo

Let’s add more unit tests!

Page 17: Intro to functional programming - Confoo

Let’s add more unit tests!

Page 18: Intro to functional programming - Confoo

Definitionsand

Examples

Page 19: Intro to functional programming - Confoo

Functional Programming imposes constraints that eliminate states and ease reasoning.

Page 20: Intro to functional programming - Confoo

Functional Programming is about values, functions and types*.

Page 21: Intro to functional programming - Confoo

Values

Page 22: Intro to functional programming - Confoo

Values are immutable.

Page 23: Intro to functional programming - Confoo

Example - Javafinal String title = "functional programming";

final Person bob = new Person("bob", 34);

class Person {

private final String name;

private final int age;

private Person(String name, int age) {

this.name = name;

this.age = age;

}

...

}

Page 24: Intro to functional programming - Confoo

Example - Scalaval title = "functional programming"

val bob = User("bob", 34)

case class User(name: String, age: Int)

Page 25: Intro to functional programming - Confoo

What about data structures?Can they be values?

Page 26: Intro to functional programming - Confoo

Persistent data structures create a new updated version. They are immutable.

Page 27: Intro to functional programming - Confoo

Example - Java (1)// using functional java

import fj.data.List;

final List<String> canadianCities =

List.list("Montreal", "Ottawa", "Toronto");

final List<String> americanCities =

List.list("New York", "San Francisco");

final List<String> northAmericanCities =

canadianCities.append(americanCities);

Page 28: Intro to functional programming - Confoo

Example - Java (2)// using guava

final ImmutableList<String> canadianCities =

ImmutableList.of("Montreal", "Ottawa", "Toronto");

final ImmutableList<String> americanCities =

ImmutableList.of("New York", "San Francisco");

final ImmutableList<String> northAmericanCities =

ImmutableList.<String>builder().addAll(canadianCities)

.addAll(americanCities).build();

// or

final ImmutableList<String> northAmericanCities =

Stream.concat(canadianCities.stream(), americanCities.stream())

.collect(GuavaCollectors.immutableList());

Page 29: Intro to functional programming - Confoo

Example - Scalaval canadianCities = List("Montreal", "Ottawa", "Toronto")

val americanCities = List("New York", "San Francisco")

val northAmericanCities = canadianCities ++ americanCities

Page 30: Intro to functional programming - Confoo

Immutability eliminates state and means you can safely share the reference.

Page 31: Intro to functional programming - Confoo

Functions

Page 32: Intro to functional programming - Confoo

A function takes arguments and produces a result.

(Pure) Functionshave no side-effects.

Page 33: Intro to functional programming - Confoo

Side-effects examples:- write to disk- read from stdin- throw an exception- change a state

Page 34: Intro to functional programming - Confoo

Example - Java// pure function

public static String convert(String input) {

return new StringBuilder(input).reverse()

.toString().toUpperCase();

}

// unpure function

public static void printMessage(String message) {

if(message == null) {

throw new IllegalStateException("Should not be null");

}

System.out.println(message);

}

Page 35: Intro to functional programming - Confoo

Example - Scala// pure function

def convert(a: String): String = {

a.reverse.toUpperCase

}

// unpure function

def print(message: String): Unit = {

if (message == null) {

throw new IllegalStateException("Should not be null!")

}

println(message)

}

Page 36: Intro to functional programming - Confoo

Having no side-effecthelps reasoning about code.

Page 37: Intro to functional programming - Confoo

Having no side-effect simplifies testing.

Page 38: Intro to functional programming - Confoo

Errors are handled by returning them as results.

Page 39: Intro to functional programming - Confoo

Example - Javapublic static Optional<Integer> parseInt(String s) {...}

// using functional java

public static Either<Exception, Integer> parse(String s) {...}

// Use combinators to avoid branching

final double discount = parseInt(ageAsString)

.map(a -> a * 0.01).orElse(0.10);

// Assume Optional<Integer> age1, age2;

final Optional<Integer> sum = age1.flatMap(a1 ->

age2.map(a2 ->

a1 + a2));

Page 40: Intro to functional programming - Confoo

Example - Scaladef parseInt(s: String): Option[Int] = {...}

val sum: Option[Int] = for {

a <- parseInt("2")

b <- parseInt("3")

} yield a + b

Page 41: Intro to functional programming - Confoo

Updating a state is done by creating a new instance with the updated state.

Page 42: Intro to functional programming - Confoo

For other necessary side-effects, push them on the boundaries.

Page 43: Intro to functional programming - Confoo

Looping can be implemented with recursion*.

Page 44: Intro to functional programming - Confoo

Example - Scaladef sumAllFrom(value: Int): Int = {

// always use the @tailrec annotation

// tail recursive functions can be optimized to a loop

@tailrec

def internalSum(value: Int, currentSum: Int): Int = {

if (value == 0) {

currentSum

} else {

internalSum(value - 1, currentSum + value)

}

}

internalSum(value, 0)

}

Page 45: Intro to functional programming - Confoo

A high-order functions takes functions as parameters and/or produces a function.

Page 46: Intro to functional programming - Confoo

Example - Javafinal ImmutableList<Integer> l = ImmutableList.of(1, 2, 3, 4);

final ImmutableList<Integer> mapped = l.stream()

.filter(e -> (e % 2) == 0)

.map(e -> e * 2)

.collect(GuavaCollectors.immutableList());

Page 47: Intro to functional programming - Confoo

Example - Scalaval l = List(1, 2, 3, 4)

val mapped = l.filter(e => e % 2 == 0).map(_ * 2)

val mappedStream = l.toStream

.filter(e => e % 2 == 0)

.map(_ * 2)

.toList

Page 48: Intro to functional programming - Confoo

Example - Javafinal Function<Integer, Integer> doubled = e -> e * 2;

final Function<Integer, Integer> increment = e -> e + 1;

final Function<Integer, Integer> doubleAndIncrement =

doubled.andThen(increment);

Page 49: Intro to functional programming - Confoo

Types

Page 50: Intro to functional programming - Confoo

Types define classifications of values.

Page 51: Intro to functional programming - Confoo

With types, the compilercan verify some aspects of correctness.

Page 52: Intro to functional programming - Confoo

Example - Scalacase class User(name: String, city: String, phoneNumber: String)

// ?!

val user = User("Montreal", "John", "New York")

// These types could include validation

// so any object successfully created is valid.

// Check value classes to avoid garbage

trait Name {...}

trait City {...}

trait PhoneNumber {...}

case class User(name: Name, city: City, phoneNumber:PhoneNumber)

Page 53: Intro to functional programming - Confoo

Meta

Page 54: Intro to functional programming - Confoo

Object-Oriented is about semantic.

Functional Programming is about shape.

Page 55: Intro to functional programming - Confoo

Example - Javainterface Process

interface ProcessConfig

interface ProcessFactory {

Process createProcess(ProcessConfig config)

}

interface Machine

interface MachineConfig

interface MachineFactory {

Machine createMachine(MachineConfig config)

}

Page 56: Intro to functional programming - Confoo

Example - Javainterface Process

interface ProcessConfig

interface Machine

interface MachineConfig

interface Factory<T, C> {

T create(C config)

}

interface ProcessFactory extends Factory<Process, ProcessConfig>

interface MachineFactory extends Factory<Machine, MachineConfig>

Page 57: Intro to functional programming - Confoo

Example - Javainterface Process

interface ProcessConfig

interface Machine

interface MachineConfig

interface Factory<T, C> {

T create(C config)

}

interface ProcessFactory extends Factory<Process, ProcessConfig>

interface MachineFactory extends Factory<Machine, MachineConfig>

Page 58: Intro to functional programming - Confoo

Function<C, T>

Page 59: Intro to functional programming - Confoo

Reuse by shape is more powerful than reuse by semantic.

Page 60: Intro to functional programming - Confoo

BUT understanding shape is harder than understanding semantic.

Page 61: Intro to functional programming - Confoo

Summary

Page 62: Intro to functional programming - Confoo

Summary

- Functional programing: immutable values, pure functions and precise types*.

- Benefits are:- Simple code- Concurrency and Parallelism for free- Easy to reason about- Reusable

Page 63: Intro to functional programming - Confoo

ContactFélix-Étienne Trépanier

Twitter - @felixtrepanierGithub - @coderunner

unconfoo session @ 2pm!