Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Functional Principles for OO Developers

5,146 views

Published on

as presented at GOTO Chicago 2014.

Six lessons I took from functional programming that are totally useful in object-oriented programming.

Published in: Software

Functional Principles for OO Developers

  1. 1. Functional principles for object-oriented development @jessitron
  2. 2. Imperative Procedural Object-Oriented Functional Aspect-Oriented Logic
  3. 3. Data In, Data Out Specific Typing Verbs Are People Too Immutability Declarative Style Lazy Evaluation
  4. 4. Data In, Data Out
  5. 5. access global state modify input change the world
  6. 6. Testable Easier to understand
  7. 7. Password password; Email email; ! private boolean invalidPassword() { return !password.contains(email); }
  8. 8. private boolean invalidPassword( Password password, Email email) { return !password.contains(email); }
  9. 9. (Email, Password) -> boolean
  10. 10. the flow of data
  11. 11. Get unused deposits Get unused donations Create link record Mark donation done Deposit used up?
  12. 12. unused unused match Get deposits Get donations Store matches Mark donations
  13. 13. List<Deposit> List<Donation> List<Match<Deposit,Donation>> List<Donation>
  14. 14. Problem easier, because we know each step of the way of data.
  15. 15. Encapsulation
  16. 16. Isolation z
  17. 17. ! Response createAccount(UserDbService svc, Request req, Config cfg) { … Account acc = constructAccount(…) AccountInsertResult r = svc.insert(acc) return respond(r); }
  18. 18. Response createAccount( Function<Account, AccountInsertResult> svc, Request req, Config cfg) { … Account acc = constructAccount(…) AccountInsertResult r = svc.apply(acc) return respond(r); }
  19. 19. Specific Typing
  20. 20. The beginning of wisdom is to call things by their right names.
  21. 21. Java public 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
  22. 22. Scala case c l a s s F i r s t N a m e( v a l u e : S t r i n g) val friend = FirstName(“Simon”)
  23. 23. Scala type FirstName = String val friend: FirstName = “Simon”
  24. 24. expressiveness layers of thinking
  25. 25. time => Cost time => Volume (Volume, Cost) => Expenditure ∴ time => Expenditure
  26. 26. A => B B => C ∴ A => C ((VVoolluummee,, CCoosstt)) ==>> EExxppeennddiittuurree
  27. 27. Account => AccountInsertResult
  28. 28. Either[AccountCreationFailure, ] Account => AccountInserted
  29. 29. Either[AccountCreationFailure, ] Account => AccountInserted
  30. 30. Errors are data too
  31. 31. access global state modify input change the world
  32. 32. access global state modify input change the world interrupt execution flow
  33. 33. Either[AccountCreationFailure, ] Account => AccountInserted
  34. 34. this talk is brought to you by… the Option type! NPE Thing ! doStuff() NullThing ! doStuff() {} Option<T> SomeThing ! doStuff() {…} Some<T> None
  35. 35. FSharpOption<T> ! ! Optional<T> … because null is not a valid object reference.
  36. 36. Verbs Are People Too
  37. 37. class Inflation implements FunctionOverTime { public float valueAt(int t) { return // some calculated value; } } Java
  38. 38. Java class Variable implements FunctionOverTime { private final Function<Int, Double> vals; … public float valueAt(int t) { return vals.apply(t); } }
  39. 39. Java Variable inflation = new Variable( “Cost Inflation”, t -> Math.Pow(1.15,t)); ! inflation.valueAt(3);
  40. 40. Java 6 Variable inflation = new Variable(“Inflation”, ! ! ! ! ! new Function<Integer, Double>() { @Override public Double apply(Integer input) { return ; } }); Math.pow(1.15, input)
  41. 41. Command Strategy OnClick() release ( )
  42. 42. Imperative Procedural Object-Oriented != Functional Aspect-Oriented Logic
  43. 43. withTransaction( ) // start // end
  44. 44. Response r = createAccount( (acc) -> userDB.insertAccount(acc), req, cfg);
  45. 45. Response r = createAccount( acc -> withTransaction(userDB.insertAccount(acc)), req, cfg);
  46. 46. Response r = createAccount( acc -> retrying( withTransaction(userDB.insertAccount(acc))), req, cfg);
  47. 47. retrying( ) Code Code
  48. 48. Idempotence
  49. 49. OnClick() release ( )
  50. 50. Immutability
  51. 51. String Effective Java Effective C#
  52. 52. Scala val qty = 4 // immutable var n = 2 // mutable
  53. 53. F# let qty = 4 // immutable let mutable n = 2 // mutable n = 4 // false n <- 4 // destructive update
  54. 54. Concurrency fewer possibilities
  55. 55. Java: easy public class Address { public final String city; ! public Address(String city) { this.city = city } ! ...}
  56. 56. Java: defensive copy private final ImmutableList<Phone> phones; ! public Customer (Iterable<Phone> phones) { this.phones = ImmutableList.copyOf(phones); }
  57. 57. Java: copy on mod public Customer addPhone(Phone newPhone) { Iterable<Phone> morePhones = ImmutableList.builder() .addAll(phones) .add(newPhone).build(); return new Customer(morePhones); }
  58. 58. F#: copy on mod member this.AddPhone (newPhone : Phone) { new Customer(newPhone :: phones) }
  59. 59. fruit fruit.add(tomato)
  60. 60. persistent data structure
  61. 61. persistent data structure
  62. 62. C#: shallow copy public Customer AddPhone(Phone newPhone) { IEnumerable<Phone> morePhones = // create list return new Customer(morePhones, name, address, birthday , cousins); }
  63. 63. this talk is brought to you by… the Tuple type! function new Tuple<string,int>(“You win!”, 1000000)
  64. 64. Tuple<T1,T2,…> When one return value is not enough!
  65. 65. Declarative Style
  66. 66. say what you’re doing, not how you’re doing it
  67. 67. Never tell people how to do things. Tell them what to do and they will surprise you with their ingenuity.
  68. 68. select ROLE_NAME, UPDATE_DATE from USER_ROLES where USER_ID = :userId
  69. 69. readable code only the essentials
  70. 70. Java public List<String> findBugReports(List<String> lines) { List<String> output = new LinkedList(); for(String s : lines) { if(s.startsWith(“BUG”)) { output.add(s); } } return output; }
  71. 71. familiar != readable
  72. 72. Java lines.stream() .filter(s -> s.startsWith(“BUG”)) .collect(Collectors.toList)
  73. 73. Java lines.stream().parallel() .filter(s -> s.startsWith(“BUG”)) .collect(Collectors.toList)
  74. 74. C# lines.Where(s => s.StartsWith(“BUG”)).ToList
  75. 75. Lazy Evaluation
  76. 76. delay evaluation until the last responsible moment
  77. 77. save work let go of when
  78. 78. separate what to do from when to stop
  79. 79. Java 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(); }
  80. 80. for (String s : FluentIterable.of(new RandomFileIterable(br)) .filter(STARTS_WITH_BUG_PREDICATE) .transform(TRANSFORM_BUG_FUNCTION) .limit(40) .asImmutableList()) { report(s); } Java 6
  81. 81. Data In, Data Out Specific Typing Verbs Are People Too Immutability Declarative Style Lazy Evaluation
  82. 82. 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.
  83. 83. by Faqqotic http://www.sketchport.com/drawing/6606411756732416/aeiou
  84. 84. Jessica Kerr blog.jessitron.com @jessitron github.com/jessitron/fp4ood

×