functional programming and new teams · functional programming and new teams michael neale...

122
Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com

Upload: others

Post on 05-Jul-2020

9 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

Functional programming and new teams

Michael Neale@michaelneale

developer.cloudbees.com

Page 2: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

Background

Work @cloudbees: developer.cloudbees.comFP on and off since uni (first programming language was miranda)!github.com/michaelneale!polyglot - but mostly cussing at bash scripts nowadays **!

Page 3: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced
Page 4: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

Context

New CompanyNew TeamNew Product!You might not be this “lucky”But I hope you get some ideas or inspiration!

Page 5: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

History

2010 Started: JVM stack parts - Scala not controversial (I had experience) - working mostly “lone wolf”!2011 - another team added - brought Erlang!

Page 6: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

Erlang!Me

other team members

Page 7: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

More FP

Given “success” with Scala, another “FP language” was not a great risk. !

Page 8: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

Since then

More developers hired!Existing developers start to care about FP!I learned Erlang (avoiding the one person wolfpack)!Clojure & “micro services” introduced

Page 9: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

Observation

FP means one person can do more && People like me like to work alone!∴ risk of staying with one-person-per app(aside: is this a bad thing?)

Page 10: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

Maintainability objectionIt goes: - how will anyone be able to maintain this after you?!My Experience: - 2 projects featuring FP handed over successfully - new developers able to pick up FP easily - seasoned developers too!My anecdotes are clearly science!!

Page 11: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

Where we are today

Several systems involving: - Erlang (on every server and core services) - Scala (cloud controllers) - Clojure (micro services - talk to github api)

Page 12: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

Where we may differ

Small teams - many systems.!∴ Little overlap in jobs.

Page 13: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

What did we do with FPManage horrendous public cloud APIs!Server controlling (agent) - manage horrendously misbehaving apps!Automatic scaling!Github crawling!

Page 14: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

Surprisingly practical things

No real calculations, no explicit maths.!Just boring every day error prone stuff.

Page 15: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

For example (provisioning)

Page 16: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

Providore Evil cloud api

Build masters

build workers Workspace storage

Page 17: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

Every step involves failures, retries!Every step requires unknown wait times.

The problem:

Page 18: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

How can we solve this?TDD? problems only manifest under load/in-production. APIs are buggy, change over time.!Industry best practice: scripting: 60% of the time, it works every time.!How does FP help?

Page 19: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

YesTypes (providore is written in scala) - Specifically: Maybe/Option, Either - Closed Data Types (servers only in so many states)!The M word: Monads!Currying

Page 20: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

Cloud API

launch_server: Server!at best hopes to be: !launch_server: Maybe[Server]launch_server: Either[Server, OhGodWhyWhyWhy]!(not an actual pure function of course)!

Page 21: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

Cloud Monad

Cloud APIs are like IO!Slow, horrible, misbehaving IO!...and then the APIs other people write!All want to be monadic

Page 22: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

val validation: String \/ Subscription = (for {! account <- extractAccount! _ <- validateSubscription(account)! callback <- extractCallBack! plan <- validatePlan ! billing_day <- extractBillingDay! subscription <- createSub(account, plan, callback, ...! } yield subscription).run(req.body)!

(scala) ReaderT to help you compose !

http://debasishg.blogspot.com.au/2011/07/monad-transformers-in-scala.html

!

Need to “organise code in monadic way”

Page 23: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

!!!Infrastructure devs, “devops”: pay attention!!Correct code matters here: hard to test -> correctness can help!We can do better

Page 24: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

TypesSo hard to catch things without them!Monadic IO + types mean you catch things before you try!Trying/experimenting can be $$ expensive...!!!!

Page 25: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

Types helped with

Ignored messagesBad pattern matchingMisconfiguration/timing of server creationAvoiding “stringly typed” messages!

Page 26: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

Types didn’t help with...

Page 27: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

! !zombies = ec2.servers.select { |i| i.tags.empty? && tenured?(i) && alive?(i) }!Parallel.each(zombies, :in_threads => 15) do |zombie|! begin! puts "Terminating zombie node #{zombie.id}"! ec2.servers.get(zombie.id).destroy! end!end!

Page 28: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

CurryingServer lifecycle: Reserved->Launching->Update (user data)->Volume Create->Volume Attach->initialise/start!Accumulate setup data via partial application!Instead of an object that has mutating state, a function you partially apply to accumulate data.!Good “beginner” FP concept (powerful, simple)

Page 29: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

Another example (autoscale)

Page 30: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

Message Bus Autoscale

Controller

Servers/

Page 31: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

Auto scalingF(last minute stats, previous data window) -> “Suggestion” to scale up, or down (or in or out)!Fundamentally calculation, fundamentally functional.!Built in Erlang.

Page 32: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

Side effects

Push out side effects to other side of the message bus!Let a nasty app handle the side effects!Messages are signals, suggestions, idempotent!!

Page 33: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

Developers Developers

Don’t “sell” to your developers by: - saying monad too often - saying “it’s easy” - showing that it can be just as easy/familiar as what they have!Instead...

Page 34: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

Find the functionsFind the functions in what they doFind the calculations (eg core of autoscaling)!Intermediate: Currying, Higher order functions, Types (good ones)!Advanced:Monadic

Page 35: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

Unlearning OO

Erlang and Clojure: both excellent at teaching people to forget about OO. !Scala: challenge. Temptation always there. ∴ Use object/package as namespace/modules!

Page 36: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

Advocating FP ...

Page 37: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

Ruby Slippers

Concept from _why!You can’t wear anything you want, but you can wear ruby slippers!http://viewsourcecode.org/why/hacking/wearingRubySlippersToWork.html!Use ruby for small, but necessary, tools/scripts!

Page 38: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

Introducing ...

Page 39: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

Lambda Underpants

Page 40: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

Lambda Underpantshttp://lambdaunderpants.com!Use FP for small, but necessary services, scripts!Disposable, possibly forgettable, sneaky. !example: Kit by @nkpartme: small clojure services that deal with github api

Page 41: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

Micro ServicesSmall http services (typically) - REST!perfect for FP: F(request) -> response!Examples: - github crawling - monitoring cloud usage (instances) - admin interfaces and utilities

Page 42: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

Micro ServicesPick ones that are “transforming” data from one service to a client!Low risk, uncontroversial!Ask forgiveness later.

Page 43: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

ALT:Mixed language projects

Good idea??Relevant to JVM (and .net) environs only(?)!Ease-into-itJury is out...

Page 44: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

Final ObservationDevelopers who have fondness for emacs/vim (over IDE) find things easier!FP invites “change this small bit, see what happens” exploration!

Page 45: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

Thank you

Michael Nealehttps://twitter.com/michaelnealehttps://developer.cloudbees.com

Page 46: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

Adop%ng  

Func%onal  Programming  at  IOOF  

 -­‐  an  experimental  approach  

Kornelis  Sietsma  -­‐  @kornys  

Page 47: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

The  Project  

!"#$

%&'()*+&,

!"#$ !"#$

-"./&0!"#$

-"./&0!"#$

-"./&0!"#$

-"./&0!"#$

Page 48: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

Constraints  ...DecNovOctSepAugJulJunMayAprFebAug Oct MarSep JanDecNov

Phase&1

Phase&2

Deadline

3

4

and&on...

Deadline

Deadline

Page 49: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

Phase  One  private final GuavaHelpers.ReduceFunction<List<Pair<TransactFile,! Transformer.Payload>>, TransactFile> fileTransformer! = new GuavaHelpers.ReduceFunction<List<Pair<TransactFile,! Transformer.Payload>>, TransactFile>() {! @Override! public List<Pair<TransactFile, Transformer.Payload>> ! apply(List<Pair<TransactFile, Transformer.Payload>> memo,! TransactFile file) {! Transformer.Payload transformedContent                      = findTransformer(file.getTransactionType())! .transform(file.getContents(),! file.getCreationTime().toDate());! memo.add(! new ImmutablePair<TransactFile, Transformer.Payload>! (file, transformedContent));! return memo;! }!};  

Page 50: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced
Page 51: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

Why  not  FP?  

(defn file-­‐transform! [memo, file]! (let [transformer (find-transformer (:type file))! new-contents! (transform (:contents file) (to-date (:creation file)))]! (conj memo [file new-contents])))  

Page 52: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

“But…”  

!"#$"$%%

&'()$

*+%%+"#%+,-$.

/'%0$12

Page 53: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

“But…”  

Page 54: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

Why  not  try  it?  

“Concurrent  set-­‐based  engineering”  

Page 55: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

“OK  -­‐  You  have  three  weeks”  

...DecNovOctSepAugJulJunMayAprFebAug Oct MarSep JanDecNov

Phase&1

Phase&2

Deadline

3

4

and&on...

Deadline

Deadline

!

Page 56: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

The  Plan  

!"#$

%&'()*+&,

!"#$ !"#$

-"./&0!"#$

-"./&0!"#$

-"./&0!"#$

-"./&0!"#$

Page 57: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

Evalua%on  Criteria  

•  Testability  •  Speed  of  development  •  Ease  of  change  •  Ease  of  maintenance  •  Learning  curve  •  Community  and  support  •  Libraries  and  tools  

Page 58: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

Methodology  

Page 59: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

Methodology  

Page 60: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

Methodology  

Page 61: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

Methodology  

Page 62: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

Methodology  

Page 63: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

Metrics  -­‐  Objec%ve  

•  Speed  of  development  •  Time  use  breakdown  – Wri%ng  code  – Wri%ng  tests  – Dealing  with  tooling  – Adding  libraries  

•  Quality  of  tools  and  libraries  

Page 64: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

Metrics  –  Subjec%ve  

•  Coding  •  Tes%ng  •  Problem  solving  •  Changing  requirements  •  Tools  and  libraries  •  Overall  “gut  feel”  

Page 65: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

A  note  on  context  

“It  Depends…”  

Page 66: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

The  first  two  weeks  (defn –main  []! (println "hello  world"))  

object HelloWorld {! def main(args: Array[String]) {! println("Hello,  world!")! }!}  

public class HelloWorld {! public static void main(String[] args) {! System.out.println("Hello,  World");! }!}  

Page 67: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

Objec%ve  %me  usage  

0  

500  

1000  

1500  

2000  

2500  

3000  

1   2   3   4   5   6   7   8  

Scala  

tools  

libs  

test  

code  

0  

500  

1000  

1500  

2000  

2500  

3000  

1   2   3   4   5   6   7   8  

Clojure  

tools  

libs  

test  

code  

0  

500  

1000  

1500  

2000  

2500  

1   2   3   4   5   6   7   8  

Java  

tools  

libs  

test  

code  

Page 68: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

Subjec%ve  -­‐  Clojure  Overall

tests

code

tools/libs

!2#

!1#

0#

1#

2#

0# 1# 2# 3# 4# 5# 6# 7# 8# 9#

Page 69: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

Subjec%ve  -­‐  Scala  Overall

tests

code

tools/libs

!2#

!1#

0#

1#

2#

0# 1# 2# 3# 4# 5# 6# 7# 8# 9#

Page 70: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

Subjec%ve  -­‐  Java  Overall

tests

code

tools/libs

!2#

!1#

0#

1#

2#

0# 1# 2# 3# 4# 5# 6# 7# 8# 9#

Page 71: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

A_er  two  weeks  

!"#$%

!2#

!1#

0#

1#

2#

0# 1# 2# 3# 4# 5# 6# 7# 8# 9#Java

Scala

Clojure

Page 72: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

Clojure  technical  feasibility  

•  Database  access  •  XML  read/write  •  REST  API  •  SOAP  API  •  Handling  large  data  sets  •  Message  queues  •  Task  scheduling  •  Sta%c/Dynamic  web  •  …  and  many  more  

Page 73: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

Clojure  technical  feasibility  

•  Database  access  •  XML  read/write  •  REST  API  •  SOAP  API  •  Handling  large  data  sets  •  Message  queues  •  Task  scheduling  •  Sta%c/Dynamic  web  •  …  and  many  more  

Yes  Yes  Yes  Via  Java  Yes  Yes  Yes  Yes  Yes,  yes,  yes  

Page 74: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

So  that’s  it  –  Clojure  FTW?  

Page 75: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

Experiment  review  Criteria   Subjec6ve  Ra6ngs  

Project    

Long  term  

 

Total     Bad   Poor   Ok   Good   Awesome  

Testability  -­‐  Unit   5   5   10   0   1   3   2   1  

Speed  of  development   8   1   9   1   1   1   2   2  

Testability  –  int/accept.   2   7   9   1   1   2   3   0  

Ease  of  change   3   5   8   1   2   2   2   0  

Ease  of  Maintenance   0   7   7   1   4   2   0   0  

Learning  Curve   2   4   6   1   2   2   1   1  

Community  /  Support   1   5   6   1   2   0   1   2  

Page 76: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

Change  is  hard.  

Page 77: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

So,  what  was  the  decision?  

“No.”  

Page 78: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

So,  what  was  the  decision?  

“No.”  “Yes!”  

Page 79: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

So  we  built  it  in  Clojure!  

Stuff Stuff Stuff

Stuff%System%B

Stuff%System%A

OtherSystems

Page 80: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

What  about  those  deadlines?  

...DecNovOctSepAugJulJunMayAprFebAug Oct MarSep JanDecNov

Phase&1

Phase&2

Early!

3 4

Enhance

Early! Early!

and&on...

!

Page 81: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

Lines  of  code  

0  

1000  

2000  

3000  

4000  

5000  

6000  

7000  

9/01/13   9/02/13   9/03/13   9/04/13   9/05/13   9/06/13   9/07/13   9/08/13   9/09/13   9/10/13  

lines  of  cod

e  

Clojure  code  

Clojure  test  

Java  code  

Java  test  

Javascript  code  

Javascript  test  

Clojure  ms  code  

Clojure  ms  test  

Page 82: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

Lines  of  code  

0  

20  

40  

60  

80  

100  

120  

0  

1000  

2000  

3000  

4000  

5000  

6000  

7000  

9/01/13   9/02/13   9/03/13   9/04/13   9/05/13   9/06/13   9/07/13   9/08/13   9/09/13   9/10/13  

Busine

ss  Storie

s  (black  lin

e)  

lines  of  cod

e  

Clojure  code  

Clojure  test  

Java  code  

Java  test  

Javascript  code  

Javascript  test  

Clojure  ms  code  

Clojure  ms  test  

business  stories  

Page 83: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

New  hires  

Page 84: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

And  awesome  code.  (defn-­‐ dec-­‐first-­‐digit [digits]! (conj (rest digits) (dec (first digits))))!!(defn-­‐ apply-­‐weighting [weights values]! (map * values weights))!!(defn-­‐ abn [value]! (let [weighted-sum! (-­‐>> (map #(Integer/parseInt (str %)) value)! (dec-first-digit)! (apply-weighting [10 1 3 5 7 9 11 13 15 17 19])! (apply +))]! (if-­‐not (= (rem weighted-sum 89) 0) "Not  a  valid  ABN")))!!(defn-­‐ tfn [value]! (let [weighted-sum! (-­‐>> (map #(Integer/parseInt (str %)) value)! (apply-weighting (if (= (count value) 8)! [10 7 8 4 6 3 5 1]! [10 7 8 4 6 3 5 2 1]))! (apply +))]! (if-­‐not (= (rem weighted-sum 11) 0) "Not  a  valid  TFN")))  

Page 85: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

Conclusions  

•  Experiments  are  awesome  •  Change  is  hard  •  Metrics  are  hard  •  Plan  ahead  •  Remember,  it’s  all  about  your  own  context.  

Page 86: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

Thank  you!  

Kornelis  Sietsma  -­‐  @kornys  

Credits:  “classic  text  editor  learning  curve”  –  [email protected]  (apparently)  “distraught  func%onal  programmer”  -­‐  @oorom    

Page 87: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

adopting fp

Page 88: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

who am I?

2.04Nebuchadnezzar

Page 89: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

Jed Wesley-Smith

@jedws

concurrency performance bass player

Page 90: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

7.13The Tardis

what is fp?

Page 91: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

purethey don’t change anything

totalthey accept all values in the domain, no exceptions!

referentially transparenta call can be replaced by its result without changing the meaning of the program

we can change the number of times something is called and the order in which they are called without affecting the result of the program – fearless refactoring!

programming with functions

Page 92: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

immutablethey don’t change

comparablecan be considered equal, or ordered against each other;cannot compare things that change

sharablethread-safe, don’t need to worry about locks, or ownership, or resource management

functions are values too!

programming with values

Page 93: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

Rich Hickey, Are We There Yet JVM Language Summit 2009 Keynote

“we invented mutable values, we must uninvent them.”

Page 94: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

Tony Morris adapted from @fogus

“we must immutilate them.”

Page 95: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

why fp?

2.09Rapture

Page 96: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

simple

functional programming is fundamentally simple

programming is hard

concurrency is really hard

a simple a model as possible makes it easier to reason about our programs

Page 97: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

reliable

programs that are reasonable

where invariants cannot be arbitrarily violated by non-deterministic ordering of changes to the state of the running program

yield to logical proofs that certain pathological states cannot happen!

Page 98: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

3.04The Derek Zoolander Centre for

Kids Who Can’t Read Goodand Wanna Learn to Do Other Stuff Good Too

how did we get there?

Page 99: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

bugs

large old Java code-base, lots of accidental sharing of JavaBeans. Strange, unrepeatable, customer support cases

assigned engineer (often eventually me) would need to spend a large amount of time analysing the code,bending it, testing it and eventually coming up with a theory as to why it broke and how to fix it

surely, there’s a better way…

Page 100: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

performance

when all your objects are mutable, you need to protect against accidental or malicious change to the references you pass out, locks and defensive copying are common

what is the cost of:

project.getAvatar().getAvatarId()

is it just a dereference? maybe a chain of dereferencing?

maybe it calls to the database? to a remote system?

how would you know?

Page 101: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

immutability to the rescue

for many cases, simply making sure all objects that are passed in between classes and stored in caches are immutable is a big win

less copying

no thread-safety issues

no need for locks (lock contention can destroy performance in nasty ways)

Page 102: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

big wins!we have used these very simple and basic techniques effectivelyto tame complexity in our products and libraries

\o/

6.01Avengers Mansion

Page 103: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

but, there’s more…

7.07Discworld

Page 104: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

2.01Black Mesa

digging into the fp toolkit

Page 105: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

higher-order functions

higher-order functions take functions as inputs

Java (yet) doesn’t have language support for functions service.post(payload).map(new Function<Either<Failure, Key>, String>() { public String apply(Either<Failure, Key> input) { return input.fold(new Function<Failure, String>() { @Override public String apply(Failure fail) { log.error("Could not write. Error was {}", fail); return fail.toString(); } }, new Function<Key, String>() { public String apply(Key key) { log.warn("Successfully wrote to {}. Key is {}", BASE_LOCATION, key); return key.toString(); } }); } }).claim();

Page 106: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

use a language that supports functions

for instance Scala service.put(payload).map { _.fold( fail => { log.error("Could not write. Error was {}", fail) fail.toString }, key => { log.warn("Successfully wrote to {}. Key is {}", BASE_LOCATION, key) key.toString } ) }.claim

Page 107: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

what about functional architectures?

Page 108: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

extend the idea to all parts of the system

don’t mutate anything

event sourcing, CQRS

git

lucene

datomic

Page 109: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

case studies

FRAK7.11Galactica

Page 110: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced
Page 111: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

marketplace.atlassian.com

business-critical application

80k LOC Java/Groovy/grails app

rife with performance & reliability issues

rewrite… with enormous time-pressure

started “traditional” service layer, DI etc.

but… prefer pure FP from start

only 2 in team with any Scala or FP experience

Page 112: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

“hardcore” fp

Dependency Injection => functions with Reader monad

immutable domain model

updates with Lenses and State monad

straight-forward philosophy:push purity and type-safety to every corner of the system

Page 113: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

result

a far more reliable system

4x faster than the original site

concise 4x functionality and 1/2 the code of the Grails app

and a pleasure to develop on, once you know what a Kleisli is

Page 114: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced
Page 115: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

data analysis platform

data storage is content addressable

meta-data storage in datomic

architecture is pure FP

APIs expressed as in a monadic style, and executed using interpreters that run either in memory for testing or inside IO for file-system/network access

Page 116: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

6.06Isengard

challenges

Page 117: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

overcoming fear

unfamiliarity is deeply discomforting

fear and discomfort erode rationality, it is hard to rationalise about things that you don’t understand

some advanced functional programming topics such as category theory (monads, functors, applicatives) sound really scary

they aren’t really, they are just very general tools

Page 118: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

education

continuous improvement read, study and practice, practice, practice!

you must unlearn, what you have learned shifting from abstraction over domain to abstraction over concepts takes a while to really appreciate

learning curve (especially with regard to IO)takes a while for benefits to materialise

invest wiselyfocus on the people who are interested, don’t spend too much time trying to win over the nay-sayers

Page 119: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

teachingfind mentorsteams get great leg up from importing experience

allow innovation to distillaggressive and hard deadlines demand conservative approaches, and are fundamentally anti-agile

test everythingfunctional architectures lend themselves to testing, investigate and use property-based testing, avoid mock frameworks.

Page 120: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

lessons

don’t do a bit functional you lose the benefits at a high level, with additional integration pain

compound effect of (in-)correctnesssmall hacks in the foundation can have large effects later on

embrace fearyou will be bewildered, and it is ok, it is only temporary

Page 121: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

thanks!

Page 122: Functional programming and new teams · Functional programming and new teams Michael Neale @michaelneale developer.cloudbees.com. Background ... Clojure & “micro services” introduced

images Sam Thebridge & Henry Tapia

The Empire doesn’tunderstand how security is supposedto work

7.09Death Star