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.

Commercial Uses of Functional Programming

14,302 views

Published on

FLOLAC'14 talk on using Haskell in commercial settings.

Published in: Technology
  • Be the first to comment

Commercial Uses of Functional Programming

  1. 1. 2014-07-01 FLOLAC’14 Commercial Uses of Functional Programming Functional Programming as a means — not an end
  2. 2. 01
  3. 3. 01 ✤ ICFP 2014: September 1~3
  4. 4. 01 ✤ ICFP 2014: September 1~3 ✤ CUFP 2014: September 4~6
  5. 5. 01 ✤ ICFP 2014: September 1~3 ✤ CUFP 2014: September 4~6 ✤ 6-Hour Workday: July 1
  6. 6. 01 ✤ ICFP 2014: September 1~3 ✤ CUFP 2014: September 4~6 ✤ 6-Hour Workday: July 1
  7. 7. 01
  8. 8. 01
  9. 9. 01 Worse is Better
  10. 10. 01 Worse is Better
  11. 11. 01 Worse is Better Less is More!
  12. 12. Less is more! λ Closure ⊂ Value
  13. 13. Less is more! λ Closure ⊂ Value f . g =
  14. 14. Less is more! λ Closure ⊂ Value f . g = x -> f (g x)
  15. 15. Less is more! λ Closure ⊂ Value f . g = x -> f (g x) ((+1) . (*2)) 3
  16. 16. Less is more! λ Closure ⊂ Value function compose (f, g) { return function (x) { return f( g(x) ) } } f . g = x -> f (g x) ((+1) . (*2)) 3
  17. 17. ANSI C Ada Fortran Cobol
  18. 18. ANSI C Ada Fortran Cobol
  19. 19. ANSI C Ada Fortran Cobol
  20. 20. ANSI C Ada Fortran Cobol
  21. 21. ANSI C Ada Fortran Cobol
  22. 22. ANSI C Ada Fortran Cobol
  23. 23. ANSI C Ada Fortran Cobol
  24. 24. ANSI C Ada Fortran Cobol
  25. 25. ANSI C Ada Fortran Cobol
  26. 26. ANSI C Ada Fortran Cobol
  27. 27. ANSI C Ada Fortran Cobol
  28. 28. ANSI C Ada Fortran Cobol
  29. 29. ANSI C Ada Fortran Cobol
  30. 30. Generators: List Fusion
  31. 31. Generators: List Fusion fibs = 1:1:[ x+y
 | x <- fibs
 | y <- tail fibs ] take 6 (map (*10) fibs) [10,10,20,30,50,80]
  32. 32. Generators: List Fusion fibs = 1:1:[ x+y
 | x <- fibs
 | y <- tail fibs ] take 6 (map (*10) fibs) [10,10,20,30,50,80] take 6 (map (*5) (map (*2) fibs)) [10,10,20,30,50,80]
  33. 33. Generators: List Fusion fibs = 1:1:[ x+y
 | x <- fibs
 | y <- tail fibs ] take 6 (map (*10) fibs) [10,10,20,30,50,80] take 6 (map (*5) (map (*2) fibs)) [10,10,20,30,50,80] take 6 (map ((*5) . (*2)) fibs)
  34. 34. QuickCheck: PropertyTesting
  35. 35. QuickCheck: PropertyTesting import Test.QuickCheck prop :: [Int] -> [Int] -> Bool prop xs ys = reverse (xs ++ ys) == reverse xs ++ reverse ys quickCheck prop -- Failed!
  36. 36. QuickCheck: PropertyTesting import Test.QuickCheck prop :: [Int] -> [Int] -> Bool prop xs ys = reverse (xs ++ ys) == reverse xs ++ reverse ys quickCheck prop -- Failed! reverse xs ++ reverse ys
  37. 37. QuickCheck: PropertyTesting import Test.QuickCheck prop :: [Int] -> [Int] -> Bool prop xs ys = reverse (xs ++ ys) == reverse xs ++ reverse ys quickCheck prop -- Failed! reverse xs ++ reverse ys quickCheck prop -- Failed!
  38. 38. QuickCheck: PropertyTesting import Test.QuickCheck prop :: [Int] -> [Int] -> Bool prop xs ys = reverse (xs ++ ys) == reverse xs ++ reverse ys quickCheck prop -- Failed! reverse ys ++ reverse xs quickCheck prop -- Passed!
  39. 39. Macros: Multi-Stage Programming
  40. 40. Macros: Multi-Stage Programming import Text.InterpolatedString.Perl6 user = "world" putStrLn [qq| Hello, $user! Your lucky number: { 6*7 } |]
  41. 41. 2011 20142004
  42. 42. 2011 20142004 2005
  43. 43. 2011 20142004 2005 2012
  44. 44. ES/9000 R46 4CPU, 8GB RAM 50MTWD
  45. 45. RS/6000 H70 340MHz 1MTWD ES/9000 R46 4CPU, 8GB RAM 50MTWD
  46. 46. InfoPrint/4000 ID5 1000 PPM 15MTWD RS/6000 H70 340MHz 1MTWD ES/9000 R46 4CPU, 8GB RAM 50MTWD
  47. 47. InfoPrint/4000 ID5 1000 PPM 15MTWD RS/6000 H70 340MHz 1MTWD ES/9000 R46 4CPU, 8GB RAM 50MTWD
  48. 48. InfoPrint/4000 ID5 1000 PPM 15MTWD RS/6000 H70 340MHz 1MTWD ES/9000 R46 4CPU, 8GB RAM 50MTWD COBOL RPG PL/1 REXX SQL
  49. 49. InfoPrint/4000 ID5 1000 PPM 15MTWD RS/6000 H70 340MHz 1MTWD ES/9000 R46 4CPU, 8GB RAM 50MTWD COBOL RPG PL/1 REXX SQL
  50. 50. Content Manager OnDemand Feb 2004
  51. 51. Content Manager OnDemand Feb 2004
  52. 52. Content Manager OnDemand Encode::IBM Parse::AFP Feb 2004
  53. 53. Content Manager OnDemand Encode::IBM Parse::AFP Feb 2004
  54. 54. Content Manager OnDemand 
Encode::IBM Parse::AFP Feb 2004
  55. 55. September 2004
  56. 56. September 2004
  57. 57. September 2004
  58. 58. 
 September 2004
  59. 59. 
 September 2004 SAX-style iterators
  60. 60. 
 September 2004 SAX-style iterators O(n) memory use
  61. 61. 
 September 2004 SAX-style iterators O(n) memory use 300KB/sec (my laptop)
  62. 62. 
 September 2004 SAX-style iterators O(n) memory use 300KB/sec (my laptop) 30KB/sec (production)
  63. 63. 
 September 2004 SAX-style iterators O(n) memory use 300KB/sec (my laptop) 30KB/sec (production) Input: 25GB/day Throughput: 2.5GB/day
  64. 64. 
 September 2004 SAX-style iterators O(n) memory use 300KB/sec (my laptop) 30KB/sec (production) Input: 25GB/day Throughput: 2.5GB/day Deadline: Feb 2005
  65. 65. October—November 2004
  66. 66. October—November 2004
  67. 67. October—November 2004
  68. 68. December 2004: Freenode
  69. 69. December 2004: Freenode ✤ “Yeah, CosmicRay recently ported GHC to AIX.”
  70. 70. December 2004: Freenode ✤ “Yeah, CosmicRay recently ported GHC to AIX.” ✤ “Defining a functor instance as liftM works I'm pretty sure, so… all Monads are Functors (theoretically), instance Monad a => Functor a where fmap = liftM would cover all monads.”
  71. 71. December 2004: Freenode ✤ “Yeah, CosmicRay recently ported GHC to AIX.” ✤ “Defining a functor instance as liftM works I'm pretty sure, so… all Monads are Functors (theoretically), instance Monad a => Functor a where fmap = liftM would cover all monads.” ✤ “Elaborate please? <- have only learned haskell for 5 days…”
  72. 72. December 2004: Freenode ✤ “Yeah, CosmicRay recently ported GHC to AIX.” ✤ “Defining a functor instance as liftM works I'm pretty sure, so… all Monads are Functors (theoretically), instance Monad a => Functor a where fmap = liftM would cover all monads.” ✤ “Elaborate please? <- have only learned haskell for 5 days…” ✤ “unsafeInterleaveIO is the best thing since sliced bread.”
  73. 73. December 2004: Freenode ✤ “Yeah, CosmicRay recently ported GHC to AIX.” ✤ “Defining a functor instance as liftM works I'm pretty sure, so… all Monads are Functors (theoretically), instance Monad a => Functor a where fmap = liftM would cover all monads.” ✤ “Elaborate please? <- have only learned haskell for 5 days…” ✤ “unsafeInterleaveIO is the best thing since sliced bread.” ✤ “What do I do with a compiler with exploding brains?”
  74. 74. December 2004: Freenode ✤ “Yeah, CosmicRay recently ported GHC to AIX.” ✤ “Defining a functor instance as liftM works I'm pretty sure, so… all Monads are Functors (theoretically), instance Monad a => Functor a where fmap = liftM would cover all monads.” ✤ “Elaborate please? <- have only learned haskell for 5 days…” ✤ “unsafeInterleaveIO is the best thing since sliced bread.” ✤ “What do I do with a compiler with exploding brains?” ✤ “Haskell has a solid niche as a PhD generator :)”
  75. 75. January 2005
  76. 76. January 2005 ✤ OpenAFP.hs delivered —
  77. 77. Input: 25GB/day Throughput: 500GB/day DOM-Style selectors O(1) Memory Use! January 2005 ✤ OpenAFP.hs delivered —
  78. 78. Input: 25GB/day Throughput: 500GB/day DOM-Style selectors O(1) Memory Use! January 2005 ✤ OpenAFP.hs delivered — ✤ NTD$3k/hr * 3 months
  79. 79. Input: 25GB/day Throughput: 500GB/day DOM-Style selectors O(1) Memory Use! January 2005 ✤ OpenAFP.hs delivered — ✤ NTD$3k/hr * 3 months ✤ “You don't need category theory, you need BC Pierce's 'Types and Programming Languages’”
 
 

  80. 80. Input: 25GB/day Throughput: 500GB/day DOM-Style selectors O(1) Memory Use! January 2005 ✤ OpenAFP.hs delivered — ✤ NTD$3k/hr * 3 months ✤ “You don't need category theory, you need BC Pierce's 'Types and Programming Languages’”
 
 

  81. 81. Input: 25GB/day Throughput: 500GB/day DOM-Style selectors O(1) Memory Use! January 2005 ✤ OpenAFP.hs delivered — ✤ NTD$3k/hr * 3 months ✤ “You don't need category theory, you need BC Pierce's 'Types and Programming Languages’”
 
 
 ✤ “My target language is huge. I need all the help I can get :)”
  82. 82. 2005: Pugs Feb 1: Started on Freenode #haskell Lambdas & Camels joined in #perl6 Specification revised, iterated, tested Concurrency, Coroutines, Commit Bits!
  83. 83. 2006: Erdősing YAPC: Worst is Best on targeting JS OOPSLA: Reconciling the Irreconcilable Succeeded by Moose & Rakudo Perl 5 runtime became Modern Perl Concluding talk: Optimizing for Fun 楽 ⼟土
  84. 84. 2007: S-Team New tech stack: Jifty, Moose, and GHC OpenAFP Utilities: Report Generation, Extraction, Management, Distribution, Conversion… Enhanced & eventually replaced IBM OnDemand with PDF-based workflow
  85. 85. 2008: Socialtext Midlife crisis — Becoming a PHB? Hierarchical organization & culture — can we change that with technology? Decided to telecommute full time:
 - ST (social workplace), or
 - FB (social media)?
  86. 86. 2009: SocialCalc Worked with Dan Bricklin & friends Summarized into three book chapters:
 - Architecture of Open Source Applications
 - Performance of Open Source Applications
 - 500 lines or less (in progress) EtherCalc: Backend of g0v.today
  87. 87. 2010:Apple Cloud Service Localization Everything under NDA… …with one single exception
  88. 88. May 2011
  89. 89. May 2011 ✤ “Can you write me some code that takes a regular expression and enumerates the domain it accepts?”
  90. 90. May 2011 ✤ “Can you write me some code that takes a regular expression and enumerates the domain it accepts?” ✤ “I think I can do this with the yices2 SMT solver and the SBV Haskell library to turn regexes into satisfiability problems, and so we can get all examples.
  91. 91. May 2011 ✤ “Can you write me some code that takes a regular expression and enumerates the domain it accepts?” ✤ “I think I can do this with the yices2 SMT solver and the SBV Haskell library to turn regexes into satisfiability problems, and so we can get all examples. ✤ But this is too much fun for an one-off script…
 Would you mind if I do this pro bono so I can release it into public domain? :-)”
  92. 92. SMT Constraint Solving
  93. 93. SMT Constraint Solving ✤ Genex: Regex as predicates on integer variables /([AB]C)1/
  94. 94. SMT Constraint Solving ✤ Genex: Regex as predicates on integer variables ✤ Solve for [x, y, z, w]: /([AB]C)1/ (x=‘A’ ∨ x=‘B’) ∧ (y=‘C’) ∧ (z=x) ∧ (w=y)
  95. 95. SMT Constraint Solving ✤ Genex: Regex as predicates on integer variables ✤ Solve for [x, y, z, w]: ✤ “ACAC”
 “BCBC” /([AB]C)1/ (x=‘A’ ∨ x=‘B’) ∧ (y=‘C’) ∧ (z=x) ∧ (w=y)
  96. 96. SMT Constraint Solving ✤ Genex: Regex as predicates on integer variables ✤ Solve for [x, y, z, w]: ✤ “ACAC”
 “BCBC” ✤ Supports b 1 ^ $ /([AB]C)1/ (x=‘A’ ∨ x=‘B’) ∧ (y=‘C’) ∧ (z=x) ∧ (w=y)
  97. 97. A Regular Crossword (ND|ET|IN)[^X]* (DI|NS|TH|OM)* .*(IN|SE|HI) [CHMNOR]*I[CHMNOR]* C*MC(CCC|MM)* ([^EMC]|EM)* [CEIMU]*OH[AEMOR]* [AM]*CM(RC)*R? N.*X.X.X.*E .*XHCR.*X.* (RR|HHH)*.? (...?)1* .*XEXM* [CR]* [^C]*MMM[^C]* (E|CR|MN)* ([^X]|XCC)* .*OXR.* .*PRR.*DDC.* R*D*M* .*(.)(.)(.)(.)4321.* (RX|[^R])* .*SE.*UE.* .*LR.*RL.* (S|MM|HHH)* .*G.*V.*H.* [^C]*[^R]*III.* (HHX|[^HX])* .(C|HH)* .*DD.*CCM.* P+(..)1.* (O|RHH|MM)* ([^MC]|MM|CC)* .*(.)C1X1.* F.*[AO].*[AO].* [^M]*M[^M]* .*H.*H.* .* .*
  98. 98. A Regular Crossword ✤ Source: MIT Mystery Hunt 2013 (ND|ET|IN)[^X]* (DI|NS|TH|OM)* .*(IN|SE|HI) [CHMNOR]*I[CHMNOR]* C*MC(CCC|MM)* ([^EMC]|EM)* [CEIMU]*OH[AEMOR]* [AM]*CM(RC)*R? N.*X.X.X.*E .*XHCR.*X.* (RR|HHH)*.? (...?)1* .*XEXM* [CR]* [^C]*MMM[^C]* (E|CR|MN)* ([^X]|XCC)* .*OXR.* .*PRR.*DDC.* R*D*M* .*(.)(.)(.)(.)4321.* (RX|[^R])* .*SE.*UE.* .*LR.*RL.* (S|MM|HHH)* .*G.*V.*H.* [^C]*[^R]*III.* (HHX|[^HX])* .(C|HH)* .*DD.*CCM.* P+(..)1.* (O|RHH|MM)* ([^MC]|MM|CC)* .*(.)C1X1.* F.*[AO].*[AO].* [^M]*M[^M]* .*H.*H.* .* .*
  99. 99. A Regular Crossword ✤ Source: MIT Mystery Hunt 2013 ✤ Solved in ~40 lines of Haskell with Genex!(ND|ET|IN)[^X]* (DI|NS|TH|OM)* .*(IN|SE|HI) [CHMNOR]*I[CHMNOR]* C*MC(CCC|MM)* ([^EMC]|EM)* [CEIMU]*OH[AEMOR]* [AM]*CM(RC)*R? N.*X.X.X.*E .*XHCR.*X.* (RR|HHH)*.? (...?)1* .*XEXM* [CR]* [^C]*MMM[^C]* (E|CR|MN)* ([^X]|XCC)* .*OXR.* .*PRR.*DDC.* R*D*M* .*(.)(.)(.)(.)4321.* (RX|[^R])* .*SE.*UE.* .*LR.*RL.* (S|MM|HHH)* .*G.*V.*H.* [^C]*[^R]*III.* (HHX|[^HX])* .(C|HH)* .*DD.*CCM.* P+(..)1.* (O|RHH|MM)* ([^MC]|MM|CC)* .*(.)C1X1.* F.*[AO].*[AO].* [^M]*M[^M]* .*H.*H.* .* .*
  100. 100. A Regular Crossword ✤ Source: MIT Mystery Hunt 2013 ✤ Solved in ~40 lines of Haskell with Genex!(ND|ET|IN)[^X]* (DI|NS|TH|OM)* .*(IN|SE|HI) [CHMNOR]*I[CHMNOR]* C*MC(CCC|MM)* ([^EMC]|EM)* [CEIMU]*OH[AEMOR]* [AM]*CM(RC)*R? N.*X.X.X.*E .*XHCR.*X.* (RR|HHH)*.? (...?)1* .*XEXM* [CR]* [^C]*MMM[^C]* (E|CR|MN)* ([^X]|XCC)* .*OXR.* .*PRR.*DDC.* R*D*M* .*(.)(.)(.)(.)4321.* (RX|[^R])* .*SE.*UE.* .*LR.*RL.* (S|MM|HHH)* .*G.*V.*H.* [^C]*[^R]*III.* (HHX|[^HX])* .(C|HH)* .*DD.*CCM.* P+(..)1.* (O|RHH|MM)* ([^MC]|MM|CC)* .*(.)C1X1.* F.*[AO].*[AO].* [^M]*M[^M]* .*H.*H.* .* .* N H P E H A S D I O M O M T H F O X N X A X P H M M O M M M M R H H M C X N M M C R X E M C M C C C C M M M M M M H R X R C M I I I H X L S O R E O R E O R E O R E V C X C C H H M X C C R R R R H H H R R U N C X D X E X L E R R D D M M M M G C C H H C C
  101. 101. SmallCheck: Enumerated Series
  102. 102. SmallCheck: Enumerated Series ✤ Type-Level Literals: Numbers and Symbols
 
 
 
 
 
 xs :: [Matching "a?b?c?"] xs = list 100 series [,a,b,ab,c,ac,bc,abc]
  103. 103. SmallCheck: Enumerated Series ✤ Type-Level Literals: Numbers and Symbols
 
 
 
 
 
 ✤ Check properties for all strings matching a regex xs :: [Matching "a?b?c?"] xs = list 100 series [,a,b,ab,c,ac,bc,abc]
  104. 104. QuickCheck: Random Sampling
  105. 105. QuickCheck: Random Sampling ✤ Regular Expressions and XML Schemata: generate (matching rfc2822) "9%az4@rar1do04jkd1.agzy.org"
  106. 106. QuickCheck: Random Sampling ✤ Regular Expressions and XML Schemata: generate (matching rfc2822) "9%az4@rar1do04jkd1.agzy.org" putStr . showXmlTree =<<
 generate . matchingRNG =<<
 loadRNG “book.rng” <?xml version="1.0" encoding="UTF-8"?><book> <author>o09a-_6w@tnj.qom.today</author> <author>3qd9g02xlu@swbr.kmly.eu</author> <author>z6ckxi8@jtm.cbopios.asia</author> </book>
  107. 107. 2012: LiveScript Feb 1: @gkz forked @satyr’s fork of .coffee “Like a smaller language within Perl 6, struggling to get out…” May 1: ST joined PeopleFluent at Bedford June 1: CoffeeRedux by @michaelficarra Launched JS2LS: @clkao, @gkz, @mpgutta Coco
  108. 108. 2013: MoeDict Feb 1: Revised MoE Dictionary in HTML5 - Every word linked to its definition - Fair Use and CC0 as legal frameworks moedict.tw: Android, iOS, Firefox OS Holo, Hakka, Cross-Strait Language DB 萌典
  109. 109. May 2014: CUFP Program Committee
  110. 110. May 2014: CUFP Program Committee ✤ “I enjoyed @simonmar's slides The Haxl Project at Facebook and the related /r/haskell discussions.
  111. 111. May 2014: CUFP Program Committee ✤ “I enjoyed @simonmar's slides The Haxl Project at Facebook and the related /r/haskell discussions. ✤ It’s a reasonably easy-to-understand Commercial Use of Functional Programming that I plan to talk about in my FLOLAC’14 talk.
  112. 112. May 2014: CUFP Program Committee ✤ “I enjoyed @simonmar's slides The Haxl Project at Facebook and the related /r/haskell discussions. ✤ It’s a reasonably easy-to-understand Commercial Use of Functional Programming that I plan to talk about in my FLOLAC’14 talk. ✤ Would it make sense to invite @simonmar to the CUFP keynote?”
  113. 113. Fighting Spam with Pure Functions
  114. 114. Fighting Spam with Pure Functions ✤ Nov 2012: Simon Marlow joins Facebook
  115. 115. Fighting Spam with Pure Functions ✤ Nov 2012: Simon Marlow joins Facebook ✤ Jan 2013: FXL — Subset of ML, interpreted in C++
  116. 116. Fighting Spam with Pure Functions ✤ Nov 2012: Simon Marlow joins Facebook ✤ Jan 2013: FXL — Subset of ML, interpreted in C++ If (Average(Map(Reputation, 
 PreviousSharedUrls(User, 5))) < 0) Then [WarnUser, LogRequest] Else []
  117. 117. Fighting Spam with Pure Functions ✤ Nov 2012: Simon Marlow joins Facebook ✤ Jan 2013: FXL — Subset of ML, interpreted in C++ ✤ Aug 2013: Haxl compiler implemented in GHC
  118. 118. Fighting Spam with Pure Functions ✤ Nov 2012: Simon Marlow joins Facebook ✤ Jan 2013: FXL — Subset of ML, interpreted in C++ ✤ Aug 2013: Haxl compiler implemented in GHC ✤ Jun 2014: Deployed and Open Sourced
  119. 119. Fighting Spam with Pure Functions ✤ Nov 2012: Simon Marlow joins Facebook ✤ Jan 2013: FXL — Subset of ML, interpreted in C++ ✤ Aug 2013: Haxl compiler implemented in GHC ✤ Jun 2014: Deployed and Open Sourced ✤ Sep 2014: There is no fork @ ICFP
  120. 120. FXL on Haxl If (Average(Map(Reputation, 
 PreviousSharedUrls(User, 5))) < 0) Then [WarnUser, LogRequest] Else []
  121. 121. FXL on Haxl If (Average(Map(Reputation, 
 PreviousSharedUrls(User, 5))) < 0) Then [WarnUser, LogRequest] Else []
  122. 122. FXL on Haxl If (Average(Map(Reputation, 
 PreviousSharedUrls(User, 5))) < 0) Then [WarnUser, LogRequest] Else [] Marlow et al, The Haxl Project at Facebook
  123. 123. FXL on Haxl If (Average(Map(Reputation, 
 PreviousSharedUrls(User, 5))) < 0) Then [WarnUser, LogRequest] Else [] Marlow et al, The Haxl Project at Facebook
  124. 124. Concurrency & Caching
  125. 125. Concurrency & Caching ✤ With the Applicative Do macro: fun :: Haxl String fun = [ado| x <- fetch “A” y <- fetch “B” z <- fetch y x ++ y ++ z |]
  126. 126. Concurrency & Caching ✤ With the Applicative Do macro: fun :: Haxl String fun = [ado| x <- fetch “A” y <- fetch “B” z <- fetch y x ++ y ++ z |] fetch “A” fetch “B”
  127. 127. Concurrency & Caching ✤ With the Applicative Do macro: fun :: Haxl String fun = [ado| x <- fetch “A” y <- fetch “B” z <- fetch y x ++ y ++ z |] fetch “A” fetch “B” H A
  128. 128. Concurrency & Caching ✤ With the Applicative Do macro: fun :: Haxl String fun = [ado| x <- fetch “A” y <- fetch “B” z <- fetch y x ++ y ++ z |] fetch “A” fetch “B” H A fetch “A” H cached
  129. 129. Concurrency & Caching ✤ With the Applicative Do macro: fun :: Haxl String fun = [ado| x <- fetch “A” y <- fetch “B” z <- fetch y x ++ y ++ z |] fetch “A” fetch “B” H A++ fetch “A” H cached ++ HAH
  130. 130. Recap
  131. 131. Recap ✤ Generators: List Fusion

  132. 132. Recap ✤ Generators: List Fusion
 ✤ QuickCheck: Property Testing

  133. 133. Recap ✤ Generators: List Fusion
 ✤ QuickCheck: Property Testing
 ✤ Macros: Multi-Stage Programming
  134. 134. main :: IO () Functional Programming as a means —
  135. 135. main :: IO a Functional Programming as a means —
  136. 136. main :: IO a Functional Programming as a means — newtype IO a = IO ( State# RealWorld -> (# State# RealWorld, a #))
  137. 137. main :: IO a Functional Programming as a means — newtype IO a = IO ( State# RealWorld -> (# State# RealWorld, a #)) main :: State# RealWorld -> (# State# RealWorld, a #)
  138. 138. main :: IO a Functional Programming as a means — newtype IO a = IO ( State# RealWorld -> (# State# RealWorld, a #)) main :: State# RealWorld -> (# State# RealWorld, a #) to observe the world,
  139. 139. main :: IO a Functional Programming as a means — newtype IO a = IO ( State# RealWorld -> (# State# RealWorld, a #)) main :: State# RealWorld -> (# State# RealWorld, a #) to observe the world, to change it, and to create a new value.

×