Commercial Uses of Functional Programming
-
Upload
- -
Category
Technology
-
view
5.208 -
download
0
description
Transcript of Commercial Uses of Functional Programming
2014-07-01 FLOLAC’14
Commercial Uses of Functional ProgrammingFunctional Programming as a means — not an end
01
01
✤ ICFP 2014: September 1~3
01
✤ ICFP 2014: September 1~3
✤ CUFP 2014: September 4~6
01
✤ ICFP 2014: September 1~3
✤ CUFP 2014: September 4~6
✤ 6-Hour Workday: July 1
01
✤ ICFP 2014: September 1~3
✤ CUFP 2014: September 4~6
✤ 6-Hour Workday: July 1
01
01
01
Worse is Better
01
Worse is Better
01
Worse is Better
Less is More!
Less is more!
λClosure ⊂ Value
Less is more!
λClosure ⊂ Value f . g =
Less is more!
λClosure ⊂ Value f . g = \x -> f (g x)
Less is more!
λClosure ⊂ Value f . g = \x -> f (g x)
((+1) . (*2)) 3
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
ANSI C AdaFortran Cobol
ANSI C AdaFortran Cobol
ANSI C AdaFortran Cobol
ANSI C AdaFortran Cobol
ANSI C AdaFortran Cobol
ANSI C AdaFortran Cobol
ANSI C AdaFortran Cobol
ANSI C AdaFortran Cobol
ANSI C AdaFortran Cobol
ANSI C AdaFortran Cobol
ANSI C AdaFortran Cobol
ANSI C AdaFortran Cobol
ANSI C AdaFortran Cobol
Generators: List Fusion
Generators: List Fusion
fibs = 1:1:[ x+y | x <- fibs | y <- tail fibs ]
take 6 (map (*10) fibs) [10,10,20,30,50,80]
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]
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)
QuickCheck: Property Testing
QuickCheck: Property Testing
import Test.QuickCheck prop :: [Int] -> [Int] -> Bool prop xs ys = reverse (xs ++ ys) == reverse xs ++ reverse ys
quickCheck prop -- Failed!
QuickCheck: Property Testing
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: Property Testing
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!
QuickCheck: Property Testing
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!
Macros: Multi-Stage Programming
Macros: Multi-Stage Programming
import Text.InterpolatedString.Perl6 user = "world" putStrLn [qq| Hello, $user! Your lucky number: { 6*7 } |]
2011 20142004
2011 20142004
2005
2011 20142004
2005 2012
ES/9000 R46 4CPU, 8GB RAM
50MTWD
RS/6000 H70 340MHz 1MTWD
ES/9000 R46 4CPU, 8GB RAM
50MTWD
InfoPrint/4000 ID5 1000 PPM 15MTWD
RS/6000 H70 340MHz 1MTWD
ES/9000 R46 4CPU, 8GB RAM
50MTWD
InfoPrint/4000 ID5 1000 PPM 15MTWD
RS/6000 H70 340MHz 1MTWD
ES/9000 R46 4CPU, 8GB RAM
50MTWD
InfoPrint/4000 ID5 1000 PPM 15MTWD
RS/6000 H70 340MHz 1MTWD
ES/9000 R46 4CPU, 8GB RAM
50MTWDCOBOL RPG
PL/1 REXX SQL
InfoPrint/4000 ID5 1000 PPM 15MTWD
RS/6000 H70 340MHz 1MTWD
ES/9000 R46 4CPU, 8GB RAM
50MTWDCOBOL RPG
PL/1 REXX SQL
Content Manager OnDemand
Feb 2004
Content Manager OnDemand
Feb 2004
Content Manager OnDemand
Encode::IBM Parse::AFP
Feb 2004
Content Manager OnDemand
Encode::IBM Parse::AFP
Feb 2004
Content Manager OnDemand
Encode::IBM Parse::AFP
Feb 2004
September 2004
September 2004
September 2004
September 2004
September 2004
SAX-style iterators
September 2004
SAX-style iteratorsO(n) memory use
September 2004
SAX-style iteratorsO(n) memory use
300KB/sec (my laptop)
September 2004
SAX-style iteratorsO(n) memory use
300KB/sec (my laptop)30KB/sec (production)
September 2004
SAX-style iteratorsO(n) memory use
300KB/sec (my laptop)30KB/sec (production)
Input: 25GB/dayThroughput: 2.5GB/day
September 2004
SAX-style iteratorsO(n) memory use
300KB/sec (my laptop)30KB/sec (production)
Input: 25GB/dayThroughput: 2.5GB/day
Deadline:Feb 2005
October—November 2004
October—November 2004
October—November 2004
December 2004: Freenode
December 2004: Freenode
✤ “Yeah, CosmicRay recently ported GHC to AIX.”
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.”
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…”
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.”
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?”
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 :)”
January 2005
January 2005
✤ OpenAFP.hs delivered —
Input: 25GB/dayThroughput: 500GB/day
DOM-Style selectorsO(1) Memory Use!
January 2005
✤ OpenAFP.hs delivered —
Input: 25GB/dayThroughput: 500GB/day
DOM-Style selectorsO(1) Memory Use!
January 2005
✤ OpenAFP.hs delivered — ✤ NTD$3k/hr * 3 months
Input: 25GB/dayThroughput: 500GB/day
DOM-Style selectorsO(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’”
Input: 25GB/dayThroughput: 500GB/day
DOM-Style selectorsO(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’”
Input: 25GB/dayThroughput: 500GB/day
DOM-Style selectorsO(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 :)”
2005: PugsFeb 1: Started on Freenode #haskellLambdas & Camels joined in #perl6Specification revised, iterated, testedConcurrency, Coroutines, Commit Bits!
2006: Erdős ingYAPC: Worst is Best on targeting JSOOPSLA: Reconciling the IrreconcilableSucceeded by Moose & RakudoPerl 5 runtime became Modern PerlConcluding talk: Optimizing for Fun
楽⼟土
2007: S-TeamNew tech stack: Jifty, Moose, and GHCOpenAFP Utilities: Report Generation, Extraction, Management, Distribution, Conversion…Enhanced & eventually replaced IBM OnDemand with PDF-based workflow
2008: SocialtextMidlife 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)?
2009: SocialCalcWorked 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
2010: AppleCloud Service Localization
Everything under NDA……with one single exception
May 2011
May 2011
✤ “Can you write me some code that takes a regular expression and enumerates the domain it accepts?”
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.
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? :-)”
SMT Constraint Solving
SMT Constraint Solving
✤ Genex: Regex as predicates on integer variables
/([AB]C)\1/
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)
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)
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)
A Regular Crossword
(ND|ET|IN)[^X]*
(DI|NS|TH|OM)*
.*(IN|SE|HI)
[CHMNOR]*I[CHM
NOR]*
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*
.*(.)(.)(.)(.)\4\3\2\1.*
(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]|M
M|CC)*
.*(.)C\1X\1.*
F.*[AO].*[AO].*
[^M]*M[^M]*
.*H.*H.*
.*
.*
A Regular Crossword
✤ Source: MIT Mystery Hunt 2013
(ND|ET|IN)[^X]*
(DI|NS|TH|OM)*
.*(IN|SE|HI)
[CHMNOR]*I[CHM
NOR]*
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*
.*(.)(.)(.)(.)\4\3\2\1.*
(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]|M
M|CC)*
.*(.)C\1X\1.*
F.*[AO].*[AO].*
[^M]*M[^M]*
.*H.*H.*
.*
.*
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[CHM
NOR]*
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*
.*(.)(.)(.)(.)\4\3\2\1.*
(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]|M
M|CC)*
.*(.)C\1X\1.*
F.*[AO].*[AO].*
[^M]*M[^M]*
.*H.*H.*
.*
.*
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[CHM
NOR]*
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*
.*(.)(.)(.)(.)\4\3\2\1.*
(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]|M
M|CC)*
.*(.)C\1X\1.*
F.*[AO].*[AO].*
[^M]*M[^M]*
.*H.*H.*
.*
.*
N H P E H A SD I O M O M T H
F O X N X A X P HM M O M M M M R H H
M C X N M M C R X E MC M C C C C M M M M M MH R X R C M I I I H X L SO R E O R E O R E O R EV C X C C H H M X C CR R R R H H H R R UN C X D X E X L ER R D D M M M MG C C H H C C
SmallCheck: Enumerated Series
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]
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]
QuickCheck: Random Sampling
QuickCheck: Random Sampling
✤ Regular Expressions and XML Schemata:
generate (matching rfc2822) "9%[email protected]"
QuickCheck: Random Sampling
✤ Regular Expressions and XML Schemata:
generate (matching rfc2822) "9%[email protected]"
putStr . showXmlTree =<< generate . matchingRNG =<< loadRNG “book.rng”
<?xml version="1.0" encoding="UTF-8"?><book>
<author>[email protected]</author>
<author>[email protected]</author>
<author>[email protected]</author>
</book>
2012: LiveScriptFeb 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
2013: MoeDictFeb 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
萌典
May 2014: CUFP Program Committee
May 2014: CUFP Program Committee
✤ “I enjoyed @simonmar's slides The Haxl Project at Facebook and the related /r/haskell discussions.
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.
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?”
Fighting Spam with Pure Functions
Fighting Spam with Pure Functions
✤ Nov 2012: Simon Marlow joins Facebook
Fighting Spam with Pure Functions
✤ Nov 2012: Simon Marlow joins Facebook
✤ Jan 2013: FXL — Subset of ML, interpreted in C++
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 []
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
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
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
FXL on Haxl
If (Average(Map(Reputation, PreviousSharedUrls(User, 5))) < 0) Then [WarnUser, LogRequest] Else []
FXL on Haxl
If (Average(Map(Reputation, PreviousSharedUrls(User, 5))) < 0) Then [WarnUser, LogRequest] Else []
FXL on Haxl
If (Average(Map(Reputation, PreviousSharedUrls(User, 5))) < 0) Then [WarnUser, LogRequest] Else []
Marlow et al, The Haxl Project at Facebook
FXL on Haxl
If (Average(Map(Reputation, PreviousSharedUrls(User, 5))) < 0) Then [WarnUser, LogRequest] Else []
Marlow et al, The Haxl Project at Facebook
Concurrency & Caching
Concurrency & Caching
✤ With the Applicative Do macro:
fun :: Haxl String fun = [ado| x <- fetch “A” y <- fetch “B” z <- fetch y x ++ y ++ z |]
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”
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
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
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
Recap
Recap
✤ Generators: List Fusion
Recap
✤ Generators: List Fusion
✤ QuickCheck: Property Testing
Recap
✤ Generators: List Fusion
✤ QuickCheck: Property Testing
✤ Macros: Multi-Stage Programming
main :: IO ()Functional Programming as a means —
main :: IO aFunctional Programming as a means —
main :: IO aFunctional Programming as a means —
newtype IO a =
IO ( State# RealWorld
-> (# State# RealWorld, a #))
main :: IO aFunctional Programming as a means —
newtype IO a =
IO ( State# RealWorld
-> (# State# RealWorld, a #))
main :: State# RealWorld
-> (# State# RealWorld, a #)
main :: IO aFunctional Programming as a means —
newtype IO a =
IO ( State# RealWorld
-> (# State# RealWorld, a #))
main :: State# RealWorld
-> (# State# RealWorld, a #)
to observe the world,
main :: IO aFunctional 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.