Commercial Uses of Functional Programming

12,727 views

Published on

FLOLAC'14 talk on using Haskell in commercial settings.

Published in: Technology
0 Comments
18 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
12,727
On SlideShare
0
From Embeds
0
Number of Embeds
8,160
Actions
Shares
0
Downloads
38
Comments
0
Likes
18
Embeds 0
No embeds

No notes for slide

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.

×