simon peyton jones microsoft research
play

Simon Peyton Jones (Microsoft Research) JAOO 2009 A statically - PowerPoint PPT Presentation

Simon Peyton Jones (Microsoft Research) JAOO 2009 A statically typed, purely functional language... designed 20 years ago... by a committee... of pointy-headed academics... as a research language. Doesnt sound promising


  1. Simon Peyton Jones (Microsoft Research) JAOO 2009

  2.  A statically typed,  purely functional language...  designed 20 years ago...  by a committee...  of pointy-headed academics...  as a research language. Doesn‟t sound promising

  3. Practitioners 1,000,000 10,000 100 Geeks The quick death 1 1yr 5yr 10yr 15yr

  4. Practitioners 1,000,000 10,000 100 The slow death Geeks 1 1yr 5yr 10yr 15yr

  5. Threshold of immortality Practitioners 1,000,000 10,000 The complete absence of death 100 Geeks 1 1yr 5yr 10yr 15yr

  6. Practitioners 1,000,000 10,000 100 The committee Geeks language 1 15yr 1yr 5yr 10yr

  7. “Learning Haskell is a great way of training yourself to think functionally so you are ready to take full advantage “I'm already looking at of C# 3.0 when it comes out” Practitioners coding problems and my (blog Apr 2007) mental perspective is now 1,000,000 shifting back and forth between purely OO and more FP styled solutions” (blog Mar 2007) 10,000 100 The second life? Geeks 1 1990 1995 2000 2005 2010

  8. langpop.com Oct 2008 langpop.com

  9. langpop.com Oct 2008

  10. Ideas • Purely functional (immutable values) • Controlling effects (monads) • Laziness • Concurrency and parallelism • Domain specific embedded languages • Sexy types in general • Type classes in particular

  11.  Keith Braithwaite in “Techniques that still work no matter how hard we try to forget them”: “I learned this from a guy who now makes his living writing Haskell programs – he‟s that smart”

  12. Let‟s write code

  13. Polymorphism Higher order Type signature (works for any type a) filter :: (a->Bool) -> [a] -> [a] filter p [] = [] filter p (x:xs) | p x = x : filter p xs | otherwise = filter p xs

  14. Polymorphism Higher order Type signature (works for any type a) filter :: (a->Bool) -> [a] -> [a] filter p [] = [] filter p (x:xs) | p x = x : filter p xs | otherwise = filter p xs Functions defined f x y Guards by pattern rather than distinguish matching f(x,y) sub-cases

  15. Polymorphism Higher order Type signature (works for any type a) filter :: (a->Bool) -> [a] -> [a] filter p [] = [] filter p (x:xs) | p x = x : filter p xs | otherwise = filter p xs data Bool = False | True data [a] = [] | a:[a] Declare new data types

  16. member :: a -> [a] -> Bool member x [] = False member x (y:ys) | x==y = True | otherwise = member x ys Test for equality  Can this really work FOR ANY type a?  E.g. what about functions? member negate [increment, \x.0-x, negate]

  17.  Similar problems  sort :: [a] -> [a]  (+) :: a -> a -> a  show :: a -> String  serialise :: a -> BitString  hash :: a -> Int  Unsatisfactory solutions  Local choice  Provide equality, serialisation for everything, with runtime error for (say) functions

  18.  Local choice  Write (a + b) to mean (a `plusFloat` b) or (a `plusInt` b) depending on type of a,b  Loss of abstraction; eg member is monomorphic  Provide equality, serialisation for everything, with runtime error for (say) functions  Not extensible: just a baked-in solution for certain baked-in functions  Run-time errors

  19. Works for any type „a‟, provided ‘a’ is an instance of class Num square :: Num a => a -> a square x = x*x Similarly: sort :: Ord a => [a] -> [a] serialise :: Show a => a -> String member :: Eq a => a -> [a] -> Bool

  20. Works for any type „n‟ FORGET all that supports the you know Num operations about OO classes! square :: Num n => n -> n square x = x*x The class declaration says what the Num class Num a where operations are (+) :: a -> a -> a (*) :: a -> a -> a negate :: a -> a An instance ...etc.. declaration for a type T says how the instance Num Int where Num operations are a + b = plusInt a b implemented on T‟s a * b = mulInt a b negate a = negInt a ...etc.. plusInt :: Int -> Int -> Int mulInt :: Int -> Int -> Int etc, defined as primitives

  21. ...the compiler generates this When you write this... square :: Num n -> n -> n square :: Num n => n -> n square d x = (*) d x x square x = x*x The “ Num n => ” turns into an extra value argument to the function. It is a value of data type Num n A value of type (Num T) is a vector of the Num operations for type T

  22. ...the compiler generates this When you write this... square :: Num n -> n -> n square :: Num n => n -> n square d x = (*) d x x square x = x*x data Num a class Num a where = MkNum (a->a->a) (+) :: a -> a -> a (a->a->a) (*) :: a -> a -> a (a->a) negate :: a -> a ...etc... ...etc.. (*) :: Num a -> a -> a -> a (*) (MkNum _ m _ ...) = m The class decl translates to: A data type decl for Num • A selector function for A value of type (Num T) is a • each class operation vector of the Num operations for type T

  23. ...the compiler generates this When you write this... square :: Num n -> n -> n square :: Num n => n -> n square d x = (*) d x x square x = x*x dNumInt :: Num Int instance Num Int where dNumInt = MkNum plusInt a + b = plusInt a b mulInt a * b = mulInt a b negInt negate a = negInt a ... ...etc.. An instance decl for type T translates to a value A value of type (Num T) is a declaration for the Num vector of the Num operations for dictionary for T type T

  24. ...the compiler generates this When you write this... f :: Int -> Int f :: Int -> Int f x = negate dNumInt f x = negate (square x) (square dNumInt x) dNumInt :: Num Int instance Num Int where dNumInt = MkNum plusInt a + b = plusInt a b mulInt a * b = mulInt a b negInt negate a = negInt a ... ...etc.. An instance decl for type T translates to a value A value of type (Num T) is a declaration for the Num vector of the Num operations for dictionary for T type T

  25.  You can build big overloaded functions by calling smaller overloaded functions sumSq :: Num n => n -> n -> n sumSq x y = square x + square y sumSq :: Num n -> n -> n -> n sumSq d x y = (+) d (square d x) (square d y) Extract addition Pass on d to square operation from d

  26.  You can build big instances by building on smaller instances class Eq a where (==) :: a -> a -> Bool instance Eq a => Eq [a] where (==) [] [] = True (==) (x:xs) (y:ys) = x==y && xs == ys (==) _ _ = False data Eq = MkEq (a->a->Bool) (==) (MkEq eq) = eq dEqList :: Eq a -> Eq [a] dEqList d = MkEq eql where eql [] [] = True eql (x:xs) (y:ys) = (==) d x y && eql xs ys eql _ _ = False

  27. Even literals are class Num a where overloaded (+) :: a -> a -> a (-) :: a -> a -> a fromInteger :: Integer -> a .... “1” means “ fromInteger 1” inc :: Num a => a -> a inc x = x + 1 inc :: Num a -> a -> a inc d x = (+) d x (fromInteger d 1)

  28. propRev :: [Int] -> Bool propRev xs = reverse (reverse xs) == xs propRevApp :: [Int] -> [Int] -> Bool propRevApp xs ys = reverse (xs++ys) == reverse ys ++ reverse xs Quickcheck (which is just a Haskell 98 library) Works out how many arguments  Generates suitable  test data ghci> quickCheck propRev Runs tests  OK: passed 100 tests ghci> quickCheck propRevApp OK: passed 100 tests

  29. quickCheck :: Testable a => a -> IO () class Testable a where test :: a -> RandSupply -> Bool class Arbitrary a where arby :: RandSupply -> a instance Testable Bool where test b r = b instance (Arbitrary a, Testable b) => Testable (a->b) where test f r = test (f (arby r1)) r2 where (r1,r2) = split r split :: RandSupply -> (RandSupply, RandSupply)

  30. propRev :: [Int] -> Bool Using instance for (->) test propRev r = test (propRev (arby r1)) r2 Using instance for Bool where (r1,r2) = split r = propRev (arby r1)

  31.  Equality, ordering, serialisation  Numerical operations. Even numeric constants are overloaded  Monadic operations class Monad m where return :: a -> m a (>>=) :: m a -> (a -> m b) -> m b  And on and on....time-varying values, pretty-printing, collections, Note the higher-kinded reflection, generic programming, type variable, m marshalling, monad transformers....

  32.  Type classes are the most unusual feature of Haskell‟s type system Hey, what’s the big deal? Wild enthusiasm Despair Hack, Incomprehension hack, hack 1987 1989 1993 1997 Implementation begins

  33. Higher kinded Implicit type variables parameters (2000) (1995) Extensible Wadler/ Computation Multi- records (1996) Blott at the type parameter type level type classes classes Functional (1991) (1989) dependencies Generic (2000) Overlapping programming instances “ newtype Testing deriving” Associated types (2005) Derivable Applications type classes Variations

  34. Type classes and object-oriented programming 1. Type-based dispatch, not value- based dispatch

  35.  A bit like OOP, except that method suite passed separately? class Show where show :: a -> String f :: Show a => a -> ...  No!! Type classes implement type-based dispatch , not value-based dispatch

Recommend


More recommend