Save 37% off PRO during our Black Friday Sale! »

The Next Step is Functional

2ad20e87f55ce79b113a12c516ec9d09?s=47 anildigital
February 27, 2015

The Next Step is Functional




February 27, 2015


  1. Anil Wadghule
 @anildigital λ The Next Step is Functional February,

  2. • Object oriented developer for 7+ years
 • In the

    transformation to Functional Programming world
 • Loves to solve problems with clean & simple solutions
 • Always looks to solve core problem not symptoms
 • ♥ traveling & listening music About me
  3. • Walkthrough of SOLID design principles
 • SOLID to Functional

 • Why Functional Programming matters
 • SOLID vs FP comparison
 • Functional Principles for the object oriented developer
 • Where are we heading? Structure
  4. Change is only CONSTANT Your application will change

  5. • Rigid - Difficult to change • Fragile - Easily

    breakable • Immobile - Reuse is impossible • Viscous - Toughness in preserving design Smells of bad design
  6. SOLID principles

  7. • Basic Object Oriented Programming principles
 • Makes programs easier

    to maintain & extend over time
 • Guidelines to remove code smells SOLID principles
  8. Single Responsibility Open Closed Liskov’s Substitution Interface Segregation Dependency Inversion

  9. Single Responsibility • Each class or method should have single

    responsibility • There should be never more than one reason for a class to change • The responsibility should be encapsulated • Separation of concerns
  10. • Software entities (classes, modules, methods) should be open for

    extension, but closed for modification Open Closed Principle
  11. • Subtypes must be substitutable for their base types Liskov’s

  12. • Many client specific interfaces are better than one general

    purpose interface
 • Clients should not be forced on methods that they do not use Interface Segregation
  13. • Depend on abstractions. Do not depend on concretions Dependency

  14. Programming paradigms Imperative Procedural Object Oriented Functional Aspect Oriented Logic

    ? ? ? ? Symbolic
  15. If you take the SOLID principles to their extremes, you

    arrive at something that makes Functional Programming look quite attractive.
  16. If you take the SOLID principles to their extremes, you

    arrive at something that makes Functional Programming look quite attractive.
  17. Objects are merely a poor mans’ closures.

  18. A parable

  19. The venerable master Qc Na was walking with his student,

 Hoping to prompt the master into a discussion, Anton said "Master, I have heard that objects are a very good thing - is this true?" 
 Qc Na looked pityingly at his student and replied, "Foolish pupil - objects are merely a poor man's closures."
  20. Chastised, Anton took his leave from his master and returned

    to his cell, intent on studying closures. 
 He carefully read the entire "Lambda: The Ultimate..." series of papers and its cousins, and implemented a small Scheme interpreter with a closure-based object system. 
 He learned much, and looked forward to informing his master of his progress.
  21. On his next walk with Qc Na, Anton attempted to

    impress his master by saying "Master, I have diligently studied the matter, and now understand that objects are truly a poor man's closures." 
 Qc Na responded by hitting Anton with his stick, saying "When will you learn? Closures are a poor man's object." At that moment, Anton became enlightened. - Anton van Straaten
  22. Closures are poor man’s object.

  23. Single Responsibility → Smaller classes

  24. Interface Segregation → Favour Role Interfaces over Header Interface

  25. Lets see an example of such extreme object oriented code

 public interface IMessageQuery { string Read(int id); }

  27. Objects as data with behaviour

 public class FileStore : IMessageQuery { private readonly

    DirectoryInfo workingDirectory; public FileStore(DirectoryInfo workingDirectory) { this.workingDirectory = workingDirectory; } public string Read(int id) { var path = Path.Combine( this.workingDirectory.FullName, id + ".txt"); return File.ReadAllText(path); } }

  29. FileStore class is a simple example of data with behaviour

    • The behaviour is Read method • The data (also sometimes known as state) is workingDirectory
  30. Functions as pure behaviour Closures wrap data

  31. Before we see Closures, lets see Functions

  32. C# Func

 Func<DirectoryInfo, int, string> read = (workingDirectory, id) =>

    { var path = Path.Combine(workingDirectory.FullName, id + ".txt"); return File.ReadAllText(path); };
  34. There is no data and you pass workingDirectory to it.

 This doesn’t look like object. And is just a simple function.
  35. Closures as behaviour with data

  36. C# Closure

 var workingDirectory = new DirectoryInfo(Environment.CurrentDirectory);
 Func<int, string>

    read = id => { var path = Path.Combine(workingDirectory.FullName, id + ".txt"); return File.ReadAllText(path); };
  38. It’s closure, because function closes over the outer variable workingDirectory.

 Effectively, the function captures the value of the outer variable.
  39. What does that compile to?

 [CompilerGenerated] private sealed class <>c__DisplayClass3 { public DirectoryInfo

    workingDirectory; public string <UseClosure>b__2(int id) { return File.ReadAllText( Path.Combine(this.workingDirectory.FullName, id + ".txt")); } }
  41. Closures are behaviour with data Objects are data with behaviour

  42. Partial function application

 Func<DirectoryInfo, int, string> read = (workingDirectory, id) =>

    { var path = Path.Combine(workingDirectory.FullName, id + ".txt"); return File.ReadAllText(path); }; var wd = new DirectoryInfo(Environment.CurrentDirectory); Func<int, string> r = id => read(wd, id); // Returns partial function r(42); r(99);

  44. F# Closure

 let workingDirectory = DirectoryInfo(Environment.CurrentDirectory) let read id =

    let path = Path.Combine(workingDirectory.FullName, id.ToString() + ".txt") File.ReadAllText(path)

  46. Pure function and partial application

  47. Notice how much less ceremony is involved. 

    read (workingDirectory : DirectoryInfo) id = let path = Path.Combine(workingDirectory.FullName, id.ToString() + ".txt") File.ReadAllText(path) let wd = DirectoryInfo(Environment.CurrentDirectory) let r = read wd
  48. Enlightenment

  49. Why Functional programming?

  50. Object Oriented Style Client Component operation() add(Component) remove(Component) getChild(int) Leaf

    Composite operation() add(Component) remove(Component) getChild(int) Children operation() Problem broken into Object Oriented Parts
  51. Object Oriented Style Client Component operation() add(Component) remove(Component) getChild(int) operation()

    add(Component) remove(Component) getChild(int) Children Component show() Component show() Composite Button show()
  52. Object Oriented Interaction ShowButton click() HiddenPanel show() InfoPanel show() display()

  53. Object Oriented Style Too many objects, too many states, mutations

    and hence s
  54. None
  55. Functional Style md toHTML modifyDOM postProcess Problem broken into Functional

  56. Functional Style md toHTML postProcess modifyDOM Functions are also composed

    together to form more behaviours. visit post addId genID composed of
  57. Functional Style md toHTML postProcess modifyDOM text html decorated html

  58. Functional Style A functional program is a machine for transforming

  59. Paper talks about how higher order functions and lazy evaluations

    contribute significantly to modularity
  60. Why Functional programming? • Elegance • Purity • Avoid mistakes

    and easy debugging • Facilitates multithreaded programming / concurrency • Programming with values
  61. • Reduces code duplication • Allows better reuse • Improves

    code readability • Eliminates ugly programming by side-effects • It’s easy to maintain complex systems with singly responsible functions Why Functional programming?
  62. SOLID vs FP

  63. SOLID vs FP • Single Responsibility - A function which

    has no side effect. Values in Value out • A function therefore is by default can only have a single responsibility
  64. SOLID vs FP • Open Closed - A function can

    be extended using higher order functions. Functional composition. • Immutable object cannot be modified under creation • Safe to add additional behaviour • New pure functions can’t break existing functionality because it can’t change state. • Type classes
  65. SOLID vs FP • Liskov’s substitution principle (design by contract)

    • Doesn’t make much sense in FP • Type classes (co-variance contra-variance) kind of solve this.
  66. SOLID vs FP • Interface Segregation - What could be

    smaller interface than a function? • Structural subtyping (Ruby, OCaml, Go) • Java 8 Functional Interfaces • Use higher order functions instead of interfaces. • Type classes
  67. SOLID vs FP • Dependency Inversion - What easier to

    invert a dependency than higher order function • Higher order functions provide inversion of control • Passing typed parameters, rather than hardcoding a function to get value
  68. SOLID vs FP

  69. SOLID vs FP So what it boils down to. •

    Just use functions and higher order functions • SOLID Principles followed by default in FP
  70. Function Properties • Functions are deterministic • You always get

    same result for same inputs • Functions are encapsulated • Interface / function name tells you about behaviour • Functions are commutative • Order doesn’t matter • Data is immutable • You have to create another copy to change object
  71. Patterns invisible in FP • Peter Norvig discussed how most

    of the GoF patterns are invisible or simpler in LISP • Norvig says patterns “programming language bug reports” • Why OO Sucks by Joe Armstrong (Some bashing)
  72. Patterns invisible in FP

  73. Patterns invisible in FP

  74. Functional Principles for an 
 Object Oriented Programmer

  75. Functional Principles • Data in, data out • Declarative style

    • Immutability • Prefer verbs instead of nouns • Strong typing (if possible in your lang) • No nulls (use libraries to use ‘Option’ like) • Lazy evaluation • Composition
  76. Data in, data out • Only purpose should be data

    in and data out. Should not do anything else. • Easily tastable
 def add(a: Int, b: Int): Int = { return

    a + b }
 add(31, 11) It can be as simple like that
  78. Declarative Style • Say what are you doing, instead of

    how you are doing it. • Many small functions • E.g. one line collection processing with map, filter etc
 def printArgs(args: Array[String]): Unit = { var i =

    0 while (i < args.length) { println(args(i)) i += 1 } }
 def printArgs(args: Array[String]): Unit = { for (arg <-

    args) println(arg) }
  81. Declarative Style 
 def printArgs(args: Array[String]): Unit = { args.foreach(println)

  82. Declarative Style 
 def formatArgs(args: Array[String]) = args.mkString("\n")

  83. Immutability • The value of an identifier never changes. •

    Objects never change.
  84. Immutability • Like Strings in Java or C# • ‘Effective

    Java’ & ‘Effective C#’ have sections on how to do it.
  85. Immutability • Concurrency • Parallelism

  86. Immutability In functional languages
 • Pure: Everything is immutable •

    Hybrid: Immutable by default
  87. Prefer verbs to nouns In FP langs, functions are values.

    They can be passed just like data.
  88. Strong typing Goal is to find errors at compile time.

 type FirstName = String // type alias in Scala
 User(name: FirstName, email: EmailAddress)
 case class Customer(name: FirstName)

  89. No nulls Use Optional in Java 8 or using Guava

  90. Lazy Evaluation Delay evaluation of an expression until the last

    responsible moment
  91. Composition • Objects don’t compose easily • Objects that represent

    data structures with little behaviour usually do compose
 • Functions can be easily composed. • FP composition is mathematical notion of function composition
  92. val input = "Live as if you were to die

    tomorrow Learn as if you were to live forever" val grammerMap = Map("as" -> "adverb", "live" -> "verb", "if" -> "conjunction", "you" -> "pronoun", "were" -> "verb", "to" -> "preposition", "die" -> "verb", "tomorrow" -> "noun", "learn" -> "verb", "forever" -> "adverb") val highlight = (s: String) => { s.toUpperCase() } val grammarify = (word: String) => { val code = grammerMap(word.toLowerCase()) "<" + code + ">" + word + "<" + code + "/>" } val fComposeG = grammarify.compose(highlight) val partOfSpeechDetector = (str: String) => { str.split(" ").map(fComposeG).mkString(" ") } partOfSpeechDetector(input)
 <verb>LIVE<verb/> <adverb>AS<adverb/> <conjunction>IF<conjunction/> <pronoun>YOU<pronoun/> <verb>WERE<verb/> <preposition>TO<preposition/> <verb>DIE<verb/> <noun>TOMORROW<noun/> <verb>LEARN<verb/> <adverb>AS<adverb/> <conjunction>IF<conjunction/> <pronoun>YOU<pronoun/> <verb>WERE<verb/> <preposition>TO<preposition/> <verb>LIVE<verb/> <adverb>FOREVER<adverb/>
  93. 80s, 90s, Now

  94. 80s • Multi paradigm languages • Smalltalk 80 had lambda

    expressions • Common Lisp Object System • Polyglot programmers • Fertile language research • Implementation Progress - GC, JITs, etc.
  95. 90s and 2000s • 90s ruined everything • Huge Java

    popularity ramp • Servlets, J2EE then Spring • Virtual death of Smalltalk, LISP then Perl • Object Oriented Dominance
  96. Now • Increasingly multi paradigms languages are now dominating •

    Established languages are going multi paradigm • Java 8 - Generics + Lambdas • C++ Templates • Newer Languages are multi paradigm • F#, OCaml • Ruby / Python / Groovy • New JVM languages - Scala, Ceylon, Kotlin
  97. Go Functional • Write declarative code • Focus on what

    and not how • Avoid mutations, prefer immutability • Write more functions • Use functional composition λ
  98. Thank you @anildigital λ

  99. References • • • Functional JavaScript - Michael

    Fogus • • • • • • • • is-all-about-composition/ • Getting started Developing with Scala - Kelsey Gilmore - Innis & Jason Swartz