commercial uses of functional programming

Post on 07-May-2015

5.208 Views

Category:

Technology

0 Downloads

Preview:

Click to see full reader

DESCRIPTION

FLOLAC'14 talk on using Haskell in commercial settings.

TRANSCRIPT

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

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%az4@rar1do04jkd1.agzy.org"

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>

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

✤ 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.

top related