2 years of real world fp at rea
play

2 Years of Real World FP at REA @KenScambler Scala Developer at - PowerPoint PPT Presentation

2 Years of Real World FP at REA @KenScambler Scala Developer at Me 14 years 5 years 5 years when possible when bored when forced - 3 teams @ - 17 codebases - 43K LOC Jul 13 Jan 14 Jul 14 Jan 15 Why Functional Programming?


  1. λ 2 Years of Real World FP at REA @KenScambler Scala Developer at

  2. Me 14 years 5 years 5 years when possible when bored when forced

  3. - 3 teams @ - 17 codebases - 43K LOC Jul 13 Jan 14 Jul 14 Jan 15

  4. Why Functional Programming?

  5. Compelling, tangible software engineering benefits

  6. Modularity Abstraction Composability

  7. Modular, abstract, composable programs are simple programs

  8. Modularity

  9. Can you reason about something in isolation?

  10. Or do you need to fit everything in your head at once?

  11. A B C K Is the cost of replacing B with K just writing K ?

  12. A K B C Is the cost of replacing B with K just writing K ?

  13. A K glue K B C K glue …or rewriting half the program?

  14. A pure function is just input  output; no side effects You can tell what it does without Looking at surrounding context.

  15. Consider: Let’s parse a string like “Richmond, VIC 3121” def def parseLocation(str: String): Location = { val val parts = str.split( “,” ) val val secondStr = parts(1) val val parts2 = secondStr.split( “ “ ) Location( parts(0), parts2(0), parts(1).toInt) }

  16. Possible errors: 1 def def parseLocation(str: String): Location = { val val parts = str.split( “,” ) val val secondStr = parts(1) val val parts2 = secondStr.split( “ “ ) Location( parts(0), parts2(0), parts(1).toInt) } Could be null

  17. Possible errors: 2 def def parseLocation(str: String): Location = { val val parts = str.split( “,” ) val val secondStr = parts(1) val val parts2 = secondStr.split( “ “ ) Location( parts(0), parts2(0), parts(1).toInt) } Might not have enough elements

  18. Possible errors: 3 def def parseLocation(str: String): Location = { val val parts = str.split( “,” ) val val secondStr = parts(1) val val parts2 = secondStr.split( “ “ ) Location( parts(0), parts2(0), parts(1).toInt) } Might not have enough elements

  19. Possible errors: 4 def def parseLocation(str: String): Location = { val val parts = str.split( “,” ) val val secondStr = parts(1) val val parts2 = secondStr.split( “ “ ) Location( parts(0), parts2(0), parts(1).toInt) } Might not have enough elements

  20. Possible errors: 5 def def parseLocation(str: String): Location = { val val parts = str.split( “,” ) val val secondStr = parts(1) val val parts2 = secondStr.split( “ “ ) Location( parts(0), parts2(0), parts(1).toInt) } Might not have enough elements

  21. Possible errors: 6 def def parseLocation(str: String): Location = { val val parts = str.split( “,” ) val val secondStr = parts(1) val val parts2 = secondStr.split( “ “ ) Location( parts(0), parts2(0), parts(1).toInt) } Might not be an int

  22. Possible errors: 6 + 3 = 9 def ef doSomethingElse(): Unit = { 3 // // . ...Do ..Do o oth ther s er stu tuff ff 6 parseLocation (“Melbourne, VIC 3000”) }

  23. Possible errors: 9 + 4 = 13 def ef anotherThing(): Unit = { 4 // // . ...Do ..Do e eve ven mo n more re s stuff tuff 9 doSomethingElse() }

  24. Code inherits all the errors and side-effects of code it calls. Local reasoning becomes impossible; modularity is lost.

  25. Possible errors: 0 def parseLocation(str: String): def Option[Location] = { val val parts = str.split( ”," ) for for { locality <- parts.optGet(0) theRestStr <- parts.optGet(1) theRest = theRestStr.split(" ") subdivision <- theRest.optGet(0) postcodeStr <- theRest.optGet(1) postcode <- postcodeStr.optToInt } yield yield Location(locality, subdivision, postcode) }

  26. All possibilities have been elevated into the type system Local reasoning is possible! Local reasoning is possible about things that call it, etc…

  27. Abstraction

  28. Know as little as you need

  29. Know as little as you need Produce as little as you can

  30. def def sumInts( list: List[Int]): Int = { var var result = 0 for for (x <- list) { result = result + x } return return result }

  31. def def flatten[A]( list: List[List[A]]): List[A] = { var var result = List() for for (x <- list) { result = result ++ x } return return result }

  32. def def all[A]( list: List[Boolean]): Boolean = { var var result = tru rue for for (x <- list) { result = result && x } return return result }

  33. def def sumInts( list: List[Int]): Int = { var var result = 0 for for (x <- list) { result = result + x } return return result }

  34. def def flatten[A]( list: List[List[A]]): List[A] = { var var result = List() for for (x <- list) { result = result ++ x } return return result }

  35. def def all[A]( list: List[Boolean]): Boolean = { var var result = tru rue for for (x <- list) { result = result && x } return return result }

  36. Extract the essence! trait trait Monoid[M] { def zero: M def append(m1: M, m2: M): M }

  37. def def fold[M](list: List[M]) (im impl plic icit it m: Monoid[M]): M = { var result = m.z var .zer ero for for (x <- list) { result = m.append(result,x) } result }

  38. def def fold[M](list: List[M]) (im impl plic icit it m: Monoid[M]): M = list.foldLeft(m.zero)(m.append)

  39. fold(List(1, 2, 3, 4))  10 fold(List(List("a", "b"), List("c")))  List("a", "b", "c") fold(List(true, true, false, true))  false

  40. Abstraction is always a good thing! Less repetition More reuse Less decay, because code can’t grow tumours around unnecessary detail

  41. Composability

  42. Functions compose. A => B A => B B => C B => C C => D C => D D => E D => E

  43. Functions compose. A => E A => E

  44. Sideways too. A => E A => E X => Y X => Y

  45. Sideways too. (A,X) => (E,Y) (A,X) => (E,Y)

  46. This works in the large, as well as the small! Entire systems can be composable like functions…. without side effects

  47. Truly composable systems can accrue more and more stuff without getting more complex!

  48. Simplicity • Modularity – Reason locally • Abstraction – say only what you need, hide everything you don’t • Composability – scale without accruing complexity

  49. The human process

  50. Software GSD Coffee Tea Quiet time development is a human process Ponies Reconsider! Technical excellence isn’t enough!

  51. Xi’an offshore team Team Team Team Team

  52. Xi’an offshore team • Many teams are partly based in Xi’an. • They’re very good, but… • Communication is hard! • It works, but requires great investment of time and money

  53. Bottom-up tech decisions

  54. POST {"partyTime": "5:00"} GET /buzz/5/ GET /foo/bar PUT {"mode": "banana"}

  55. Architect Mountain

  56. Architect Mountain

  57. Architect Mountain

  58. NO Just needs more Agile No no no no no no no no no no no no no no Architect no no no no no no no Mountain no no no no no no no no no no no not like this. Wake up it’s a school day Don’t forget More your meetings, velocity but littler

  59. Bottom-up tech decisions You have to win

  60. Bottom-up tech decisions You have to win

  61. Bottom-up tech decisions You have to win

  62. Software Paleontology Everyone’s got a history…

  63. Scriptozoic era 1995 – 2010 Mostly Perl

  64. Monolithocene epoch 2010 – 2012 Ruby, Java Scriptozoic era 1995 – 2010 Mostly Perl

  65. Microservices AWS 2012 – Ruby, Scala, JS Monolithocene epoch 2010 – 2012 Ruby, Java Scriptozoic era 1995 – 2010 Mostly Perl

  66. Adoption

  67. June, 2013

  68. λ

  69. λ λ

  70. λ λ λ

  71. λ λ λ

  72. λ λ

  73. λ λ

  74. λ

  75. Language choice Functional Object Oriented Powerful static types JVM

  76. Functional Object Oriented Powerful static types JVM

  77. Functional JVM

  78. Functional JVM

  79. Functional JVM

  80. Functional JVM

  81. Whatever works for you!

  82. The journey

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend