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.

Go Beyond Higher Order Functions: A Journey into Functional Programming

61 views

Published on

Here's an introduction to folks using FP in various programming languages (especially those with built-in support for first class functions).

Join Lex Shehan as he shares his journey into FP as a retrospective; it should be great introduction to folks to using FP in other languages (especially those with built-in support for first class functions).

Our journey will include:
* high order functions in javascript (lodash)
* functional programming in Ruby
* going deeper in FP with Scala
* learning Haskell to gain a broader understanding of FP
* the history of FP and what Category Theory has to do with FP
* challenges & opportunities of incorporating FP techniques in Go

Published in: Software
  • If you just broke up with your Ex,you have to follow these steps to get her back or risk ruining your chances. Click here  http://t.cn/R50e2MX
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • Be the first to like this

Go Beyond Higher Order Functions: A Journey into Functional Programming

  1. 1. Functional Programming Journey Beyond Higher Order Functions With “Tom the Happy Cat” By Lex Sheehan All Rights Reserved
  2. 2. Let’s learn about Functional Programming
  3. 3. Learning Functional Programming is not about tightening your ass. It’s about getting your head out of it.
  4. 4. high order functions in javascript
  5. 5. Cool! Tom discovers Lodash: A handy JS Utility library!
  6. 6. Map Examples var users = [ { 'user': alice }, { 'user': bob } ]; _.map(users, 'user'); // => [alice, bob] function square(n) { return n * n; } _.map([4, 8], square); // => [16, 64] Map array of users, by key Apply square fcn to array
  7. 7. No idea what “High Order Functions” are yet, but this Map function sure is handy!
  8. 8. Other Lodash goodies! var users = [ { 'user': alice, 'age': 38, 'active': true }, { 'user': bob, 'age': 43, 'active': false } ]; _.filter(users, function(o) { return !o.active; }); // => objects for [‘alice’] _.find(users, function(o) { return o.age < 40; }); // => object for 'bob' Show me!
  9. 9. Cool! JQuery’s got Map, too!
  10. 10. return names of checked items import $ from 'jquery'; export function getCheckedFilterNames() { var checkedFilters = $('.search__filters-box input:checkbox').filter(function () { var checkedPos = $.inArray('checked', $(this)[0].nextElementSibling.classList); return (checkedPos >= 0); }); var checkedFilterNames = $.map(checkedFilters, function (checkboxInput) { return ( $.trim(checkboxInput.nextElementSibling.nextSibling.textContent) ); }); return checkedFilterNames;
  11. 11. Now, watch me use some of these helpers!
  12. 12. My Map Function emailsWithPrimarySet = _.map(emails, function (email) { if (typeof email.primary != 'undefined') { email.primary = (email.email === MyAppState.newPrimaryEmailAddress); } return email; }); Now, emails array’s primary email is set.
  13. 13. What could possibly be wrong about my stateful function?
  14. 14. functional programming in Ruby
  15. 15. Data transformation Rails.cache.fetch(:app_categories_and_counts) do records = all(:include => [:app_cats]) records.map {|r| { :id => r.id, :name => r.name, :cat_count => r.app_cats.count, :cats => r.app_cats } } end
  16. 16. Map each with index class Event < MonitorInfo def self.json all.each_with_index.map do |m, index| { :id => index, :user => 'sensor', :date => Time.now, :policy => I18n.translate(m[:policyname])} end end end Grab each index value and assign ‘em to :id
  17. 17. Chain high order functions! def load_dest_addresses(addr) return if addr.blank? destination_addresses = DestinationAddressNode.new destination_addresses.network_object = addr.split(',').reject{|a| a.nil? }.map do |aid| leaf = RuleLeafNode.ne leaf.uuid = aid leaf end destination_addresses end Awesome! Too complicated!
  18. 18. We’re replacing Functional Programming and that “complicated” language (Ruby)
  19. 19. What will Tom do Now? a. Follow corporate cliff b. Take a contracting job paying 2X what he made working with cliff
  20. 20. Let’s Trash talk java!
  21. 21. If you like design patterns, use Java, not Go.
  22. 22. WHY? And WHAT are design patterns?
  23. 23. OO Design Patterns Creational ● Abstract ● Builder ● Factory ● Prototype ● Singleton Structural ● Adapter ● Bridge ● Composite ● Decorator ● Facade ● Flyweight ● Proxy Behavioral ● Chain ● Command ● Interpreter ● Iterator ● Mediator ● Memento ● Observer ● State ● Strategy ● Template ● Visitor See github.com/ go-goodies/go_oops
  24. 24. When I see patterns in my programs, I consider it a sign of trouble. The shape of a program should reflect only the problem it needs to solve. Design pattern sub-language It appears to me that stronger languages can more easily remove such duplication because sometimes one has to make a kind of sub-language to do it. - Paul Graham
  25. 25. Sounds reasonable… Got any examples?
  26. 26. Language Features that replace Design Patterns ● VisitorPattern <= Generics ● FactoryPattern <= Closures ● IteratorPattern <= Anonymous Functions ● StrategyPattern <= High Order Functions
  27. 27. But doesn’t the Go standard library have some design patterns … ?
  28. 28. Go std. library func printStats(d time.Duration) { fileCount := 0 lineCount := 0 fset.Iterate(func(f *token.File) bool { fileCount++ lineCount += f.LineCount() return true }) fmt.Printf( "%s (%d files, %d lines, %d lines/s)n", d, fileCount, lineCount, int64(float64(lineCount)/d.Seconds()), ) } Looks like that struct implements the Iterator Pattern
  29. 29. func main() { db, err := sql.Open("postgres", "postgres://user:pass@localhost/myapp") if err != nil { log.Fatal(err) } rows, err := db.Query("SELECT * FROM users") if err != nil { log.Fatal(err) } fmt.Printf("Users: %v", rows) defer rows.Close() } sql registers postgres driver via Register fcn! func Register(name string, driver driver.Driver) { driversMu.Lock() defer driversMu.Unlock() if driver == nil { panic("sql: Register driver is nil") } if _, dup := drivers[name]; dup { panic("sql: Register called twice for driver " + name) } drivers[name] = driver } Go std. Library - factory Pattern
  30. 30. Get back on track! Now, let’s bash Java’s infinite levels of inheritance and type hierarchies and JVM bloat.
  31. 31. ObjectRetrievalFailureException class from the Spring Framework
  32. 32. Cliff said Ruby an FP was complicated ??
  33. 33. Lies, Damn Lies, and what Cliff said!
  34. 34. Rob Pike says, "Less is exponentially more."
  35. 35. More FP in Ruby
  36. 36. @instance variable A mutable property that an object knows about itself.
  37. 37. class PayrollCalculator def self.calculate(payroll) new(payroll).calculate end def initialize(payroll) @payroll = payroll end private_class_method :new def calculate PayrollResult.new( payroll: payroll, paystubs: paystubs, taxes: taxes, debits: debits ) end def paystubs calculate_paystubs(taxes, ...) end def debits calculate_debits(taxes, ...) end def taxes @taxes ||= calculate_taxes(@payroll) end end Only 1 public interface! Look Ma! memoization
  38. 38. Now, we can replace a pure function call with its value. Our pure functions give us referential transparency.
  39. 39. Put some data in, assert result is what we expected. We only need to exercise one interface in our tests.
  40. 40. Using pure functions can improve performance and make testing a breeze.
  41. 41. going deeper in FP with Scala
  42. 42. What’s a diplomatic way to replace a team of average Java programmers ?
  43. 43. Replace the entire code base with Scala and Play!
  44. 44. A big complex programming language. Imperative, Object oriented, Concurrent, functional Gateway to large scale frameworks Machine Learning, data streaming: spark, FLINK, Kafka... Scala
  45. 45. First exposure to scala class SearchEntityPriceResponse( entitySearch: EntitySearch, entitys: List[EntityInfo], xmlLogHandler: XmlLogHandler) extends (Elem => Seq[EntityResult]) { private val entitysByGtaCode = entitys.map(h => ((h.gtaCityCode.get + h.gtaPropertyCode.get).hashCode, h)).toMap class … extends looks like Java Seq, map, toMap … that’s something different!
  46. 46. fp high order functions? def apply(responseXml: Elem): Seq[EntityResult] = { xmlLogHandler.logXml(responseXml) val resultList = (responseXml "Entity") map { entityEl => { } val filteredResultList = resultList.flatten.groupBy(_.entity.id).map(g => merge(g._2)).toSeq filteredResultList } entityEl => { val rateResultList = createEntityRateResult(entityEl) if (!rateResultList.isEmpty) { val entityKey = ((entityEl "Location" "@Code").text + (entityEl "Item" "@Code").text).hashCode val entityResult: EntityResult = new EntityResult() // ... rateResultList.foreach(_.result = entityResult) Some(entityResult) } else { None } } }
  47. 47. Scala’s functional programming stuff Currying Tail Recursion Higher Order Functions Anonymous Functions Lambda Functions Partial Functions Everything is an Expression Some? None? They’re different than high order functions
  48. 48. Mutation is the exception and not the rule. Functions r first class citizens. Learning FP is key to understanding Scala Use of recursion to produce results rather than iteration.
  49. 49. Tom gets discovered
  50. 50. I’ll share what I learn ...
  51. 51. Look Ma! … Map and Filter functions in Go!
  52. 52. Nice article. How would you like to write a book?
  53. 53. To understand a science, it is necessary to know its history. - Auguste comte
  54. 54. YIPEE! Research time!
  55. 55. A Journey into the history of FP (according to Tom the happy cat)
  56. 56. George Boole (1815 - 1864) Aristotle’s algebraic logic was in prose. I translated it to symbols! true = 1 false = 0 and = product (AxB) or = sum(A+B)
  57. 57. Augustus De Morgan (1806 - 1871) All logical operations can be expressed in terms of and, or, and not. a ∧ b = ¬ ( (¬ a) ∨ (¬ b) ) a ∨ b = ¬ ( (¬ a) ∧ (¬ b) )
  58. 58. Friedrich Frege (1848 – 1925) 1. If the tree is still on the power line, then we have no power. 2. The tree is still on the power line. 3. Therefore, we have no power. I created Predicate Logic, studied the use of functions in logic and was the first to use currying! Predicate Logic { a ⇒ b, b } ⊢ b
  59. 59. Lewis Carroll (1832 –1898) Some FP libraries reference Lewis Carroll’s work … ex: FantasyLand I wrote Alice in Wonderland! ...maintaining a balance between sense and nonsense, remaining logical, even though it appeared at times to be completely illogical.
  60. 60. Alfred Whitehead and Bertrand Russell (1903) ● Barbers Paradox ● Wrote a 450-page proof to show that 1 + 1 = 2 You’re Frege’n wrong! Get your head out of your ass!
  61. 61. Moses Schonfinkel (1889–1942) I invented combinatory logic. A combinator is a higher order function that uses only function application and earlier defined combinators to define a result from its arguments. This replacement technique reduced multiple function arguments to a single argument, and was later known as currying.
  62. 62. Haskell Curry - 1927 I formalized combinatory logic, creating The Lambda Calculus, where lambda expressions represent functional abstractions are replaced by a limited set of combinators. Is that where … comes from?
  63. 63. Gerhard Gentzen (1936) I used sequent calculus (a series of true statements) to build arguments according to rules and procedures of inference making zero or more assertions.
  64. 64. Alonzo Church (1930) Kleene & Rosser …I can improve upon Principia Mathematica with effectively computable functions It’s non-terminating Try again!
  65. 65. Kleene & Rosser Alonzo Church (1930) Simply Typed Lambda Calculus is a typed system with high order functions.
  66. 66. Alan Turing (1950) My Turing Machine can compute anything your Lambda Calculus can! ...using loop statements and goto statements, i.e., not recursion.
  67. 67. MacLane and Eilenberg (1945) We introduced the concepts of categories, functors, and natural transformations. …and composition of maps that preserves mathematical structure!
  68. 68. John McCarthy (1950) I created LISP … the first Functional Programming Language!
  69. 69. Curry-Howard-Lambek Correspondence (1969) We discovered the one-to-one correspondence between objects in category theory, propositions in logic, and types in programming languages.
  70. 70. Curry-Howard-Lambek Correspondence (1969) They are all deeply related?
  71. 71. Could this also be related to flow-based programming?
  72. 72. Discover the answer in my book!
  73. 73. What can we do with our flow based components?
  74. 74. We can COMPOSE!
  75. 75. Combine two smaller functions to create a new function that accomplishes the same goal as the two smaller ones. Function Composition!
  76. 76. Back to a Journey into the History of Functional Programming
  77. 77. Roger Godement (1958) I introduced the concept of Monads.
  78. 78. Moggi, Wadler, Jones (1991) We need a framework to understand how data flows in our apps. Given a category C and an endomorphic functor f with an object A … Let’s actually use Monads in Haskell to chain functions, handle side effects, concurrent processing, logging and more!
  79. 79. Gibbons, Oliveira (2006) We explored an FP solution to the OOP iterator pattern. Using imperative iterations patterns we can return transformed list of elements the same shape!
  80. 80. Multi-paradigm languages JS Languages we’ve discussed
  81. 81. Multi-paradigm languages JS Languages we will discuss...
  82. 82. Category theory in a nutshell
  83. 83. Category theory Sets of points and arrows that connect ‘em
  84. 84. Pure Function If f(x) = x+2 and we input 3 we’ll always get 5.
  85. 85. Fcn composition f(g(1)) equals 10 g(x) = x + 2 f(x) = x2 + 1
  86. 86. Does order matter? fcn composition
  87. 87. fcn composition Order matters! Not commutative!
  88. 88. function composition is associative Isn’t that a math thing?
  89. 89. Math… hmm … Can we combine our function compositions?
  90. 90. … Let’s … … add … cows and tigers
  91. 91. Let’s multiply cows and tigers
  92. 92. What would exponents of cows with tigers and elephants look like?
  93. 93. I want more math examples!
  94. 94. ISOmorphic Equations (C,A) x (C,B) = (C, AxB) (A,C) x (C,B) = (A+B, C) (C x A,B) = (C, [A⇒B]) Laws of exponents AC x BC = (AxB)C CA x CB = C(A+B) B(CxA) = (BA )C I see the correspondence!
  95. 95. √ Identity x Commutative √ Associative √ Distributive
  96. 96. Does FP have anything to do with logic?
  97. 97. Both f and g are required to produce AxB Both mean same thing!
  98. 98. Either f or g are required to produce A+B That’s an if/then block in code
  99. 99. Is go the best way to succinctly express fp? What can i study to be sure i didn’t miss anything? Haskell
  100. 100. learning Haskell to gain a broader understanding of FP
  101. 101. Haskell code humanize b = if b then "yes" else "no" emphasize str = str ++ "!" compose g f = x -> g (f x) emphasizeHumanize = compose emphasize humanize emphasizeHumanize True => "yes!" emphasizeHumanize False => "no!"
  102. 102. The Haskell REPL is like the Interactive Ruby Console.
  103. 103. Haskell type class hierarchy A Monad is a Monoid and an Applicative
  104. 104. What’s a Category?
  105. 105. A sets of points and arrows that connect ‘em
  106. 106. What’s a Functor?
  107. 107. Our category is closed under multiplication, has an identity element, and has a mapping function f(X) (times 10) A Functor maps types to types
  108. 108. data Maybe a = Just a | Nothing No more null pointer exceptions! Example functor Maybe is like an optional value
  109. 109. instance Functor Maybe where fmap f Nothing = Nothing fmap f (Just x) = Just (f x) How is Maybe defined?
  110. 110. What’s a Monoid?
  111. 111. Monoids allow us to combine values.
  112. 112. Monoids are closed under associative binary operation and has an identity element
  113. 113. We can think of a monoid as a design pattern that allows us to quickly reduce (or fold) on a collection of a single type in a parallel way.
  114. 114. Ouch! Thorium might be a good source of energy, but it’s not helping my yoga.
  115. 115. What? No diagrams?
  116. 116. We saw composition before... But that’s not a Monoid!
  117. 117. Now, that’s a Monoid -> It returns the same data type that it’s fed. It’s an endomorphism. ‘en’ means “same” ‘morphism’ means “function”
  118. 118. We can combine them in any order Which means we can run them in parallel !!
  119. 119. What’s a Monad?
  120. 120. A Monad is just a Monoid in the Category of Endofunctors.
  121. 121. Duh!
  122. 122. Show me!
  123. 123. First, you must answer a few Q’s
  124. 124. Are you a good person?
  125. 125. What changed you?
  126. 126. Where will you end up?
  127. 127. Let’s look at the Mother Theresa Monad
  128. 128. IN nurtured as a baby IN extreme poverty OUT help others Monad provides structure
  129. 129. Show me another example!
  130. 130. How ‘bout the Marriage Monad?
  131. 131. OH SHIT! Sorry I asked!
  132. 132. No worries. Glad you did. Thanks! to the people that helped me through that journey.
  133. 133. I used to think I was entitled... Then I studied the life of Charlie Munger.
  134. 134. Back to Monads!
  135. 135. Explain that chain of boxes.
  136. 136. Move the errors arrow to the back side
  137. 137. What’s going on with the 2 arrows? Isn’t there only one input?
  138. 138. We want to create pluggable lego’s
  139. 139. Then, we could decompose into a toolbox of components.
  140. 140. What’s up with that purple arrow?
  141. 141. Which fits better?
  142. 142. How can we go from a 1 input thing to a 2 input thing?
  143. 143. With the Monad’s bind operation
  144. 144. What happens if we get an error in the middle of our flow?
  145. 145. Errors are fast-tracked down the Failure pipe.
  146. 146. Does Golang have Monads?
  147. 147. Not OOTB but you can write your own.
  148. 148. Or copy the Lexical Workflow Solution code from my book.
  149. 149. Finally… Let’s write some functional go code! Go
  150. 150. FP in Go
  151. 151. Why doesn’t everyone use FP in Go?
  152. 152. Imperative go func SumLoop(nums []int) int { sum := 0 for _, num := range nums { sum += num } return sum } Recursive go func SumRecursive(nums []int) int { if len(nums) == 0 { return 0 } return nums[0] + … SumRecursive(nums[1:]) }
  153. 153. Imperative go func loop(s []int, … b *testing.B) { for n := 0; n < b.N; n++ { SumLoop(s) } } Results: It took 46 ns/op. Recursive go func recursion(s []int, … b *testing.B) { for n := 0; n < b.N; n++ { SumRecursive(s) } } Results: It took 178 ns/op. Too slow!
  154. 154. What options do we have now?
  155. 155. Use FP for Monadic workflow control. Also checkout Gleam.
  156. 156. References Revenge of the Nerds http://www.paulgraham.com/icad.html Are Design Patterns Missing Language Features http://wiki.c2.com/?AreDesignPatternsMissingLanguageFeatures Embracing Functional Programming in Ruby https://kellysutton.com/2017/09/13/embracing-functional-prog ramming-in-ruby.html
  157. 157. References go_oops https://github.com/go-goodies/go_oops Builder design pattern in Go Std Library https://blog.golang.org/go-imagedraw-package
  158. 158. Available on amazon.com
  159. 159. What’s the hottest technology?
  160. 160. Interested in Blockchain Development?
  161. 161. We’ll learn about cryptocurrencies.
  162. 162. Cryptoeconomics…
  163. 163. And implementing Smart Contracts on the Ethereum blockchain.
  164. 164. Register at https://cryptocurrencies .developersclass.com
  165. 165. Thanks for hanging around til the end! Lex Sheehan LinkedIn: lexsheehan Twitter: @lex_sheehan Github: l3x
  166. 166. Video available at: https://www.youtube.com/watch?v=HRrP_P0PwFU Give it a LIKE. Thanks! - Tom
  167. 167. This is the first presentation I’ve done in a while.
  168. 168. If I could edit this video, I’d mention that today, depending on the application, matrix computations are likely to be much faster using an imperative language like C. However, if we are ever fortunate enough to see Tail Call Optimization (TCO) in Go, then Go might be a viable option, especially given its concurrent programming features. TCO would open up a lot of opportunities for Go programmers; that way, we wouldn’t have to pay such a high price for recursion in Go. - Tom I’ll smile more in future presentations :-)

×