Functional principles for...

100
Functional principles for object-oriented development @jessitron

Transcript of Functional principles for...

Page 1: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

Functional principles for object-oriented development

@jessitron

Page 2: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,
Page 3: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

Imperative

Procedural

Object-Oriented Functional

Aspect-Oriented Logic

Page 4: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

Data In, Data Out

Immutability

Verbs Are People Too

Declarative Style

Specific Typing

Lazy Evaluation

Page 5: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

Data In, Data Out

Page 6: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

access global state

modify input

change the world

Page 7: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,
Page 8: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

Testable

Easier to understand

Page 9: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

Password password; Email email; !

private boolean invalidPassword() { return !password.contains(email); }

Page 10: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

private boolean invalidPassword( Password password, Email email) { return !password.contains(email); }

Page 11: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

(Email, Password) -> boolean

Page 12: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,
Page 13: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,
Page 14: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,
Page 15: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

the flow of data

Page 16: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

Get unused deposits

Get unused donations

Create link record

Mark donation done

Deposit used up?

Page 17: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

match

Get deposits

Get donations

Store matches

Mark donations

unused unused

Page 18: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,
Page 19: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

List<Deposit> List<Donation>

List<Match<Deposit,Donation>>

List<Donation>

Page 20: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,
Page 21: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

Problem easier, because we know each step of the way of data.

Page 22: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

Encapsulation

Page 23: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

z

Isolation

Page 24: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,
Page 25: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

!

Response createAccount(UserDbService svc, Request req, Config cfg) { … Account acc = constructAccount(…) AccountInsertResult r = svc.insert(acc) return respond(r); }

Page 26: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

Response createAccount( Function<Account, AccountInsertResult> svc, Request req, Config cfg) { … Account acc = constructAccount(…) AccountInsertResult r = svc.apply(acc) return respond(r); }

Page 27: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

Specific Typing

Page 28: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

The beginning of wisdom is to call things by their right names.

Page 29: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

Javapublic Customer(FirstName name, EmailAddress em)

public { public final String stringValue; public FirstName(final ) { this.stringValue = value; } public String toString() {...} public boolean equals() {...} public int hashCode() {...} }

FirstName

String value

class

Page 30: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

Scala

val friend = FirstName(“Simon”)

FirstName Stringvalueclasscase ( : )

Page 31: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

Scala

FirstName String=type

val friend: FirstName = “Simon”

Page 32: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

expressiveness

layers of thinking

Page 33: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,
Page 34: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

time => Costtime => Volume

(Volume, Cost) => Expenditure

time => Expenditure

Page 35: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

A => B

B => C

(Volume, Cost) => Expenditure(Volume, Cost) => Expenditure

A => C

Page 36: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,
Page 37: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

Account => AccountInsertResult

Page 38: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

Either[AccountCreationFailure, ]

Account =>

AccountInserted

Page 39: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

Either[AccountCreationFailure, ]

Account =>

AccountInserted

Page 40: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

Errors are data too

Page 41: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,
Page 42: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,
Page 43: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

access global state

modify input

change the world

Page 44: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

access global state

modify input

change the world

interrupt execution flow

Page 45: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

Either[AccountCreationFailure, ]

Account =>

AccountInserted

Page 46: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

this talk is brought to you by… the Option type!

NPE Thing !

doStuff()

NullThing !

doStuff() {}

SomeThing !

doStuff() {…}

Option<T>

NoneSome<T>

Page 47: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

… because null is not a valid object reference.

!

Optional<T>

!

FSharpOption<T>

Page 48: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

Verbs Are People Too

Page 49: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,
Page 50: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

class Inflation implements FunctionOverTime { public float valueAt(int t) { return // some calculated value; } }

Java

Page 51: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

Javaclass Variable implements FunctionOverTime { private final Function<Int, Double> vals; … public float valueAt(int t) { return vals.apply(t); } }

Page 52: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

Java

Variable inflation = new Variable( “Cost Inflation”, t -> Math.Pow(1.15,t)); !

inflation.valueAt(3);

Page 53: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

Java 6

Variable inflation = new Variable(“Inflation”, !

!

!

!

!

});

new Function<Integer, Double>() { @Override public Double apply(Integer input) { return ; }

Math.pow(1.15, input)

Page 54: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

StrategyCommand

OnClick() release ( )

Page 55: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

Imperative

Procedural

Object-Oriented

Functional

Aspect-Oriented Logic

!=

Page 56: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

withTransaction( )

// start

// end

Page 57: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

Response r = createAccount( (acc) -> userDB.insertAccount(acc), req, cfg);

Page 58: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

Response r = createAccount( acc -> withTransaction(userDB.insertAccount(acc)), req, cfg);

Page 59: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

Response r = createAccount( acc -> retrying( withTransaction(userDB.insertAccount(acc))), req, cfg);

Page 60: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

retrying( )

Code

Code

Page 61: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

Idempotence

Page 62: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

OnClick() release ( )

Page 63: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

Immutability

Page 64: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

String

Effective Java Effective C#

Page 65: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

Scala

val qty = 4 // immutable

var n = 2 // mutable

Page 66: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

let qty = 4 // immutable

let mutable n = 2 // mutable

n = 4 // false

n <- 4 // destructive update

F#

Page 67: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

Concurrency

fewer possibilities

Page 68: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

Java: easypublic class Address { public final String city; !

public Address(String city) { this.city = city } !

...}

Page 69: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

Java: defensive copyprivate final ImmutableList<Phone> phones; !

public Customer (Iterable<Phone> phones) { this.phones = ImmutableList.copyOf(phones); }

Page 70: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

Java: copy on modpublic Customer addPhone(Phone newPhone) { Iterable<Phone> morePhones = ImmutableList.builder() .addAll(phones) .add(newPhone).build(); return new Customer(morePhones); }

Page 71: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

F#: copy on mod

member this.AddPhone (newPhone : Phone) { new Customer(newPhone :: phones) }

Page 72: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

fruit

fruit.add(tomato)

Page 73: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

persistent data structure

Page 74: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

persistent data structure

Page 75: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

C#: shallow copy

public Customer AddPhone(Phone newPhone) { IEnumerable<Phone> morePhones = // create list return new Customer(morePhones, name, address, birthday , cousins); }

Page 76: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,
Page 77: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

this talk is brought to you by… the Tuple type!

function

new Tuple<string,int>(“You win!”, 1000000)

Page 78: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

When one return value is not enough!

Tuple<T1,T2,…>

Page 79: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

Declarative Style

Page 80: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

say what you’re doing,

not how you’re doing it

Page 81: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

Never tell people how to do things. Tell them what to do and they will surprise you with their ingenuity.

Page 82: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

select ROLE_NAME, UPDATE_DATE from USER_ROLES where USER_ID = :userId

Page 83: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

only the essentials

readable code

Page 84: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

Javapublic List<String> findBugReports(List<String> lines) { List<String> output = new LinkedList(); for(String s : lines) { if(s.startsWith(“BUG”)) { output.add(s); } } return output; }

Page 85: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

familiar != readable

Page 86: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

Java

lines.stream() .filter(s -> s.startsWith(“BUG”)) .collect(Collectors.toList)

Page 87: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

Java

lines.stream().parallel() .filter(s -> s.startsWith(“BUG”)) .collect(Collectors.toList)

Page 88: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

C#

lines.Where(s => s.StartsWith(“BUG”)).ToList

Page 89: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

Lazy Evaluation

Page 90: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

delay evaluation until the last responsible moment

Page 91: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

save work

let go of when

Page 92: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

separate what to do from when to stop

Page 93: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

int bugCount = 0; String nextLine = file.readLine(); while (bugCount < 40) { if (nextLine.startsWith("BUG")) { String[] words = nextLine.split(" "); report("Saw "+words[0]+" on "+words[1]); bugCount++; } waitUntilFileHasMoreData(file); nextLine = file.readLine(); }

Java

Page 94: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

for (String s : FluentIterable.of(new RandomFileIterable(br)) .filter(STARTS_WITH_BUG_PREDICATE) .transform(TRANSFORM_BUG_FUNCTION) .limit(40) .asImmutableList()) { report(s); }

Java 6

Page 95: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,
Page 96: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

Data In, Data Out

Immutability

Verbs Are People Too

Declarative Style

Specific Typing

Lazy Evaluation

Page 97: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

I promise not to exclude from consideration any idea

based on its source, but to consider ideas across schools and heritages

in order to find the ones that best suit the current situation.

Page 98: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,
Page 99: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

http://www.sketchport.com/drawing/6606411756732416/aeiou

by Faqqotic

Page 100: Functional principles for object-orientedgotocon.com/dl/goto-chicago-2014/slides/JessicaKerr...Response createAccount( Function svc, Request req,

@jessitron

Jessica Kerr blog.jessitron.com

github.com/jessitron/fp4ood