pursuing the strong, not so silent type: a haskell story

46
Pursuing the strong, not so silent type A Haskell story by Katie Miller (@codemiller) Software Engineer at Facebook

Upload: katie-ots

Post on 10-Feb-2017

670 views

Category:

Software


0 download

TRANSCRIPT

Page 1: Pursuing the Strong, Not So Silent Type: A Haskell Story

Pursuing the strong, not so silent type

A Haskell story

by Katie Miller (@codemiller) Software Engineer at Facebook

Page 2: Pursuing the Strong, Not So Silent Type: A Haskell Story
Page 3: Pursuing the Strong, Not So Silent Type: A Haskell Story

"The limits of my language mean the limits of my world"

- Ludwig Wittgenstein

Page 4: Pursuing the Strong, Not So Silent Type: A Haskell Story

strong static types

Page 6: Pursuing the Strong, Not So Silent Type: A Haskell Story
Page 7: Pursuing the Strong, Not So Silent Type: A Haskell Story
Page 8: Pursuing the Strong, Not So Silent Type: A Haskell Story
Page 9: Pursuing the Strong, Not So Silent Type: A Haskell Story
Page 10: Pursuing the Strong, Not So Silent Type: A Haskell Story
Page 11: Pursuing the Strong, Not So Silent Type: A Haskell Story

more than 1 million requests/second

Page 12: Pursuing the Strong, Not So Silent Type: A Haskell Story

def  haskell_spammer(user,  friend,  post)      if  talking_about_haskell(post)  &&                num_common_friends(user,  friend)  <  5  &&                most_friends_like_ruby(friend)          block_post      else          do_nothing      end  end  

Page 13: Pursuing the Strong, Not So Silent Type: A Haskell Story

continuous deployment

Page 14: Pursuing the Strong, Not So Silent Type: A Haskell Story

FXL

Page 15: Pursuing the Strong, Not So Silent Type: A Haskell Story

functional

Page 16: Pursuing the Strong, Not So Silent Type: A Haskell Story

efficient data fetching

Page 17: Pursuing the Strong, Not So Silent Type: A Haskell Story

automatic batching and concurrency

Page 18: Pursuing the Strong, Not So Silent Type: A Haskell Story

HaskellSpammer  =      If  (TalkingAboutHaskell(postContent)  &&              NumCommonFriends(userId,  friendId)  <  5  &&              MostFriendsLikeRuby(friendId))          Then  BlockAction  Else  @[]  

NumCommonFriends(x,  y)  =      Length(Intersect(FriendsOf(x),  FriendsOf(y)))  

Page 19: Pursuing the Strong, Not So Silent Type: A Haskell Story

20x speedup

Page 20: Pursuing the Strong, Not So Silent Type: A Haskell Story
Page 21: Pursuing the Strong, Not So Silent Type: A Haskell Story

Haskell

Page 22: Pursuing the Strong, Not So Silent Type: A Haskell Story

Is Haskell academic?

Page 23: Pursuing the Strong, Not So Silent Type: A Haskell Story

Source: https://xkcd.com/1312

Page 24: Pursuing the Strong, Not So Silent Type: A Haskell Story

reasoning about code

Page 25: Pursuing the Strong, Not So Silent Type: A Haskell Story

haskellSpammer  ::  Haxl  Bool  haskellSpammer  =        talkingAboutHaskell  .&&      numCommonFriends  .<  5  .&&      mostFriendsLikeRuby  

   where      mostFriendsLikeRuby  =  do          friends  <-­‐  getFriends          rubyFriends  <-­‐  filterM  friendLikesRuby  friends          return  (length  rubyFriends  >=              length  friends  `div`  2)  

   friendLikesRuby  friend  =          hasAssoc  friend  likeAssoc  rubyPage

Page 26: Pursuing the Strong, Not So Silent Type: A Haskell Story

user-defined data types

Page 27: Pursuing the Strong, Not So Silent Type: A Haskell Story

hasAssoc  ::  Int  -­‐>  Int  -­‐>  Int  -­‐>  Bool  hasAssoc  id  assoc  target  =  ...

Page 28: Pursuing the Strong, Not So Silent Type: A Haskell Story

hasAssoc  ::  Int  -­‐>  Int  -­‐>  Int  -­‐>  Bool  hasAssoc  id  assoc  target  =  ...

newtype  Id  =  Id  Int  newtype  AssocId  =  AssocId  Int

Page 29: Pursuing the Strong, Not So Silent Type: A Haskell Story

hasAssoc  ::  Int  -­‐>  Int  -­‐>  Int  -­‐>  Bool  hasAssoc  id  assoc  target  =  ...

newtype  Id  =  Id  Int  newtype  AssocId  =  AssocId  Int

hasAssoc  ::  Id  -­‐>  AssocId  -­‐>  Id  -­‐>  Bool  hasAssoc  id  assoc  target  =  ...

Page 30: Pursuing the Strong, Not So Silent Type: A Haskell Story

data  Language  =  Ruby  |  Haskell  |  Php

Page 31: Pursuing the Strong, Not So Silent Type: A Haskell Story

data  Language  =  Ruby  |  Haskell  |  Php

likesLanguage  ::  Language  -­‐>  Id  -­‐>  Bool

Page 32: Pursuing the Strong, Not So Silent Type: A Haskell Story

data  Language  =  Ruby  |  Haskell  |  Php

likesLanguage  ::  Language  -­‐>  Id  -­‐>  BoollikesLanguage  Ruby  userId  =      hasAssoc  userId  likesAssoc  1995  ||      hasAssoc  userId  likesAssoc  2005

Page 33: Pursuing the Strong, Not So Silent Type: A Haskell Story

data  Language  =  Ruby  |  Haskell  |  Php

likesLanguage  ::  Language  -­‐>  Id  -­‐>  BoollikesLanguage  Ruby  userId  =      hasAssoc  userId  likesAssoc  1995  ||      hasAssoc  userId  likesAssoc  2005likesLanguage  Haskell  userId  =      hasAssoc  userId  likesAssoc  42

Page 34: Pursuing the Strong, Not So Silent Type: A Haskell Story

data  Language  =  Ruby  |  Haskell  |  Php

likesLanguage  ::  Language  -­‐>  Id  -­‐>  BoollikesLanguage  Ruby  userId  =      hasAssoc  userId  likesAssoc  1995  ||      hasAssoc  userId  likesAssoc  2005likesLanguage  Haskell  userId  =      hasAssoc  userId  likesAssoc  42likesLanguage  Php  _  =      False

Page 35: Pursuing the Strong, Not So Silent Type: A Haskell Story

Is Haskell difficult to learn?

Page 36: Pursuing the Strong, Not So Silent Type: A Haskell Story

expectations

Page 37: Pursuing the Strong, Not So Silent Type: A Haskell Story
Page 38: Pursuing the Strong, Not So Silent Type: A Haskell Story

Is Haskell a panacea?

Page 39: Pursuing the Strong, Not So Silent Type: A Haskell Story

blockAustralians  ::  Haxl  SyncResponses  blockAustralians  =  do      textMap  <-­‐  textArr      let  text  =  HashMap.lookupDefault  ""  "main_text"  textMap              numBadWords      =  length  $  filter  (`Text.isInfixOf`  text)  aussieTerms              numBadPhrases  =  length  $  filter  (`Text.isInfixOf`  text)  aussieSayings      if  numBadWords  <  2  &&  numBadPhrases  <=  0      then  return  noResponses      else              if  numBadWords  <  4  &&  numBadPhrases  <  2              then  return  requireCaptcha              else                      if  numBadWords  <  5  &&  numBadPhrases  <  3                      then  return  $  responses  [warnUser,  requireCaptcha]                      else                              if  numBadWords  <  7  &&  numBadPhrases  <  4                              then  return  warnUser                              else                                      if  numBadWords  <  8  &&  numBadPhrases  <  5                                      then  return  $  responses  [warnUser,  blockAccess]                                      else                                              if  numBadWords  <  10  &&  numBadPhrases  <  6                                              then  return  blockAccess                                              else                                                      if  numBadWords  <  13  &&  numBadPhrases  <  7                                                      then  return  $  responses                                                                        [  blockAccess                                                                        ,  enrollInFakeAccountCheckpoint                                                                        ]                                                      else  return  $  responses                                                                        [  blockAccess                                                                        ,  enrollInFakeAccountCheckpoint                                                                        ,  requireCaptcha                                                                        ]  

       where              aussieTerms  =                      [  "Acca  Dacca"                      ,  "ambo"                      ,  "arvo"                      ,  "Aussie"                      ,  "bangaroo"

Page 40: Pursuing the Strong, Not So Silent Type: A Haskell Story

blockAustralians  ::  Haxl  SyncResponses  blockAustralians  =  do      textMap  <-­‐  textArr      let  text  =  HashMap.lookupDefault  ""  "main_text"  textMap              numBadWords      =  length  $  filter  (`Text.isInfixOf`  text)  aussieTerms              numBadPhrases  =  length  $  filter  (`Text.isInfixOf`  text)  aussieSayings      if  numBadWords  <  2  &&  numBadPhrases  <=  0      then  return  noResponses      else              if  numBadWords  <  4  &&  numBadPhrases  <  2              then  return  requireCaptcha              else                      if  numBadWords  <  5  &&  numBadPhrases  <  3                      then  return  $  responses  [warnUser,  requireCaptcha]                      else                              if  numBadWords  <  7  &&  numBadPhrases  <  4                              then  return  warnUser                              else                                      if  numBadWords  <  8  &&  numBadPhrases  <  5                                      then  return  $  responses  [warnUser,  blockAccess]                                      else                                              if  numBadWords  <  10  &&  numBadPhrases  <  6                                              then  return  blockAccess                                              else                                                      if  numBadWords  <  13  &&  numBadPhrases  <  7                                                      then  return  $  responses                                                                        [  blockAccess                                                                        ,  enrollInFakeAccountCheckpoint                                                                        ]                                                      else  return  $  responses                                                                        [  blockAccess                                                                        ,  enrollInFakeAccountCheckpoint                                                                        ,  requireCaptcha                                                                        ]  

       where              aussieTerms  =                      [  "Acca  Dacca"                      ,  "ambo"                      ,  "arvo"                      ,  "Aussie"                      ,  "bangaroo"

Page 41: Pursuing the Strong, Not So Silent Type: A Haskell Story

results

Page 42: Pursuing the Strong, Not So Silent Type: A Haskell Story

ideas worth pursuing

Page 43: Pursuing the Strong, Not So Silent Type: A Haskell Story

community

Page 44: Pursuing the Strong, Not So Silent Type: A Haskell Story

Haxl team past and present

Louis Brandy

Jonathan Coens

Andrew Farmer

Kubo Kováč

Jake Lengyel

Simon Marlow

Katie Miller

Bartosz Nitka

Jon Purdy

Aaron Roth

Zejun Wu

Noam Zilberstein

Page 46: Pursuing the Strong, Not So Silent Type: A Haskell Story

The End

by Katie Miller (@codemiller) Software Engineer at Facebook