haskell - a perspective
DESCRIPTION
Haskell - A Perspective. Presented by Gábor Lipták April 2011. Topics. Why? Functional Haskell highlights Development Concurrency approaches Q&A. Why should you be interested (as a Java, .Net, Ruby developer)?. - PowerPoint PPT PresentationTRANSCRIPT
![Page 1: Haskell - A Perspective](https://reader035.vdocument.in/reader035/viewer/2022062422/56813bd4550346895da4f903/html5/thumbnails/1.jpg)
Haskell - A Perspective
Presented by Gábor LiptákApril 2011
![Page 2: Haskell - A Perspective](https://reader035.vdocument.in/reader035/viewer/2022062422/56813bd4550346895da4f903/html5/thumbnails/2.jpg)
Topics
• Why?• Functional• Haskell highlights• Development• Concurrency approaches • Q&A
![Page 3: Haskell - A Perspective](https://reader035.vdocument.in/reader035/viewer/2022062422/56813bd4550346895da4f903/html5/thumbnails/3.jpg)
Why should you be interested (as a Java, .Net, Ruby developer)?• Knowing this different language will help you improve your
understanding and skills in your "main" language• Research proving ground for features coming to your
language some while later (or to languages hosted on your VM, F#, Scala, Clojure)
• Significant scaling (today)• Fun:)
![Page 4: Haskell - A Perspective](https://reader035.vdocument.in/reader035/viewer/2022062422/56813bd4550346895da4f903/html5/thumbnails/4.jpg)
Scalability
![Page 5: Haskell - A Perspective](https://reader035.vdocument.in/reader035/viewer/2022062422/56813bd4550346895da4f903/html5/thumbnails/5.jpg)
Functional?Programming with (mathematical) functions In functional programming, programs are executed by evaluating expressions, in contrast with imperative programming where programs are composed of statements which change global state when executed. Functional programming typically avoids using mutable state.Prelude> filter even [1..10] filter :: (a -> Bool) -> [a] -> [a]filter _ [] = []filter p (x:xs) | p x = x : filter p xs | otherwise = filter p xs
![Page 6: Haskell - A Perspective](https://reader035.vdocument.in/reader035/viewer/2022062422/56813bd4550346895da4f903/html5/thumbnails/6.jpg)
Functional??
Object oriented: object method args
Functional: function args
Lambdas:
add' = (+)test1add' = add' 3 5test2add' = 3 `add'` 5
add'' = \x -> (\y -> x + y)test1add'' = add'' 3 5
![Page 7: Haskell - A Perspective](https://reader035.vdocument.in/reader035/viewer/2022062422/56813bd4550346895da4f903/html5/thumbnails/7.jpg)
Purely Functional
• First class/Higher order functions• Pure functions (no side effects)
o Immutable datao Referential transparency (each call returns the same
result)o Lazy evaluationo Purity and effects (monads)
• Type system/Type inference• Tail recursion • Compositional/Declarative/Concise • Lazy (vs. eager) evaluation
![Page 8: Haskell - A Perspective](https://reader035.vdocument.in/reader035/viewer/2022062422/56813bd4550346895da4f903/html5/thumbnails/8.jpg)
Purity (adapted from Caging the effects monster)
![Page 9: Haskell - A Perspective](https://reader035.vdocument.in/reader035/viewer/2022062422/56813bd4550346895da4f903/html5/thumbnails/9.jpg)
IntroductionNamed after Haskell Brooks Curry, was an American mathematician and logician. Two programming languages named after him.
Lambda calculus is a formal system for function definition, function application and recursion.
Prelude> 2^2500375828023454801203683362418972386504867736551759258677056523839782231681498337708535732725752658844333702457749526057760309227891351617765651907310968780236464694043316236562146724416478591131832593729111221580180531749232777515579969899075142213969117994877343802049421624954402214529390781647563339535024772584901607666862982567918622849636160208877365834950163790188523026247440507390382032188892386109905869706753143243921198482212075444022433366554786856559389689585638126582377224037721702239991441466026185752651502936472280911018500320375496336749951569521541850441747925844066295279671872605285792552660130702047998218334749356321677469529682551765858267502715894007887727250070780350262952377214028842297486263597879792176338220932619489509376
![Page 10: Haskell - A Perspective](https://reader035.vdocument.in/reader035/viewer/2022062422/56813bd4550346895da4f903/html5/thumbnails/10.jpg)
Reserved Words
• case• class• data• deriving• do• else• if• import• in
• infix• infixl• infixr• instance• let• of• module• newtype• then• type• where
![Page 11: Haskell - A Perspective](https://reader035.vdocument.in/reader035/viewer/2022062422/56813bd4550346895da4f903/html5/thumbnails/11.jpg)
Polymorphically Statically Typed (type inference)Prelude> :t mapmap :: (a -> b) -> [a] -> [b] data Bool = False | True data Roulette = Black | Red | Zero | DoubleZero deriving (Eq, Ord, Show, Read, Bounded, Enum) type PhoneNumber = String type Name = Stringtype PhoneBook = [(Name,PhoneNumber)] Eliminating easy to make errors during compile time.
![Page 12: Haskell - A Perspective](https://reader035.vdocument.in/reader035/viewer/2022062422/56813bd4550346895da4f903/html5/thumbnails/12.jpg)
Type Classes
square :: Num a => a -> asquare x = x *x
class Num a where (*) :: a -> a -> ainstance Num Int where a * b = mulInt a b -- mulInt is a primitive
class Increment a where increment :: Num -> Numinstance Increment Int where increment n = n + 1
![Page 13: Haskell - A Perspective](https://reader035.vdocument.in/reader035/viewer/2022062422/56813bd4550346895da4f903/html5/thumbnails/13.jpg)
Lazy (thunks)
numsFrom n = n : numsFrom (n+1)squares = map (^2) (numsfrom 0)
take 5 squares => [0,1,4,9,16]
take 3 (sort xs) Thunk represents an unevaluated expression.Storing and evaluating thunks are costly.
![Page 14: Haskell - A Perspective](https://reader035.vdocument.in/reader035/viewer/2022062422/56813bd4550346895da4f903/html5/thumbnails/14.jpg)
Folds
foldr (+) 0 (1:2:3:[]) == 1 + foldr (+) 0 (2:3:[])
== 1 + (2 + foldr (+) 0 (3:[])== 1 + (2 + (3 + foldr (+) 0 []))== 1 + (2 + (3 + 0))
foldl (+) 0 (1:2:3:[]) == foldl (+) (0 + 1) (2:3:[])
== foldl (+) ((0 + 1) + 2) (3:[])== foldl (+) (((0 + 1) + 2) + 3) []== (((0 + 1) + 2) + 3)
![Page 15: Haskell - A Perspective](https://reader035.vdocument.in/reader035/viewer/2022062422/56813bd4550346895da4f903/html5/thumbnails/15.jpg)
Tail recursion (and accumulator)my_sum :: [ Integer ] -> Integermy_sum [] = 0my_sum (x:xs) = x + my_sum xs
main :: IO ()main = print (my_sum [1 .. 10000000])
my_sum :: [ Integer ] -> Integermy_sum xs = my_sum' 0 xs where my_sum' acc [] = acc my_sum' acc (x:xs) = my_sum' (acc+x) xs
main :: IO ()main = print (my_sum [1 .. 10000000])
![Page 16: Haskell - A Perspective](https://reader035.vdocument.in/reader035/viewer/2022062422/56813bd4550346895da4f903/html5/thumbnails/16.jpg)
Pattern Matching and Guards
lucky :: (Integral a) => a -> String lucky 3 = "Lucky Number!" lucky x = "Sorry, you're out of luck!" numberDesc :: (Integral) => a -> String numberDesc number | number < 0 = "negative" | number > 0 = "positive" | otherwise = "zero"
![Page 17: Haskell - A Perspective](https://reader035.vdocument.in/reader035/viewer/2022062422/56813bd4550346895da4f903/html5/thumbnails/17.jpg)
Higher order functions, currying
map :: (a -> b) -> [a] -> [b] map _ [] = [] map f (x:xs) = f x : map f xs mapM :: Monad m => (a -> m b) -> [a] -> m [b]mapM_ :: Monad m => (a -> m b) -> [a] -> m () map (+3) [1,5,3,1,6] map (\(a,b) -> a + b) [(1,2),(3,5),(6,3),(2,6),(2,5)] take5 :: [Char] -> [Char]take5 = take 5
![Page 18: Haskell - A Perspective](https://reader035.vdocument.in/reader035/viewer/2022062422/56813bd4550346895da4f903/html5/thumbnails/18.jpg)
Monads (1)
Monad is a computation returning result of type a Computations are pure during construction, and might have side effects when running (lazy)
![Page 19: Haskell - A Perspective](https://reader035.vdocument.in/reader035/viewer/2022062422/56813bd4550346895da4f903/html5/thumbnails/19.jpg)
Monads (2)
instance Monad Maybe where return x = Just x Nothing >>= f = Nothing Just x >>= f = f x fail _ = Nothing Prelude> Nothing >> Just 3 Nothing Prelude> Just 3 >> Just 4 Just 4 Prelude> Just 3 >> Nothing Nothing
![Page 20: Haskell - A Perspective](https://reader035.vdocument.in/reader035/viewer/2022062422/56813bd4550346895da4f903/html5/thumbnails/20.jpg)
Monads (3)main :: IO ()main = do putStrLn "Hello, what is your name?" name <- getLine putStrLn ("Hey " ++ name ++ "!")More than you care to read (just search for Monad tutorial :) In particular look for parsing examples.
You become a real Haskell programmer only after publishing your own Monad Tutorial :)
![Page 21: Haskell - A Perspective](https://reader035.vdocument.in/reader035/viewer/2022062422/56813bd4550346895da4f903/html5/thumbnails/21.jpg)
Development
Use your editor (vim,Emacs), Leksah, Eclipse, VisualStudio to developProject structures are detailed at haskell.org Use of types (and type signatures) helps to write correct code Profiling (for space "leakage" ...)Listing sparks/concurrency details when running
![Page 22: Haskell - A Perspective](https://reader035.vdocument.in/reader035/viewer/2022062422/56813bd4550346895da4f903/html5/thumbnails/22.jpg)
QuickCheckTesting invariants in the code Lots of "clones" for other languages
import Test.QuickChecktake5 :: [Char] -> [Char]take5 = take 5main = do quickCheck (\s -> length (take5 s) == 5) quickCheck (\s -> length (take5 s) <= 5)
*Main> main*** Failed! Falsifiable (after 1 test):""+++ OK, passed 100 tests.
![Page 23: Haskell - A Perspective](https://reader035.vdocument.in/reader035/viewer/2022062422/56813bd4550346895da4f903/html5/thumbnails/23.jpg)
Other tools
• Build system: Cabal • Package repository: Hackage• Code search engine Hoogle • Code search engine Hayoo!• Haddock documentation tool • HUnit (from xUnit series)
![Page 24: Haskell - A Perspective](https://reader035.vdocument.in/reader035/viewer/2022062422/56813bd4550346895da4f903/html5/thumbnails/24.jpg)
Concurrency Approaches
• Explicit (lightweight) threads and STM (software transactional memory)
• Semi-implicit (`par`, `pseq`) a "hint"• Data parallel
![Page 25: Haskell - A Perspective](https://reader035.vdocument.in/reader035/viewer/2022062422/56813bd4550346895da4f903/html5/thumbnails/25.jpg)
Explicit threads
Not dissimilar to threads found in other languages, with same benefits/drawbacks ...• Non-deterministic by design• Monadic: forkIO and STM• forkIO :: IO () −> IO ThreadId• forkOS :: IO () −> IO ThreadId
![Page 26: Haskell - A Perspective](https://reader035.vdocument.in/reader035/viewer/2022062422/56813bd4550346895da4f903/html5/thumbnails/26.jpg)
Software Transactional Memory
atomically :: STM a -> IO aretry :: STM aorElse :: STM a -> STM a -> STM a...
newTVar :: a -> STM (TVar a)readTVar :: TVar a -> STM awriteTVar :: TVar a -> a -> STM ()
Emphasis on compositionSimilar to database transactions
![Page 27: Haskell - A Perspective](https://reader035.vdocument.in/reader035/viewer/2022062422/56813bd4550346895da4f903/html5/thumbnails/27.jpg)
Semi-implicithard to ensure the right granularity• Deterministic• Pure: par and seq
infixr 0 `par`infixr 1 `pseq`par :: a -> b -> bpseq :: a -> b -> b equivalent to par a b = b pseq a b = _|_ if a = _|_ = b otherwise
_|_ (read "bottom", non terminating expression).
![Page 28: Haskell - A Perspective](https://reader035.vdocument.in/reader035/viewer/2022062422/56813bd4550346895da4f903/html5/thumbnails/28.jpg)
Example
import Control.Parallel
cutoff :: Intcutoff = 20
parFib :: Int -> IntparFib n | n < cutoff = fib nparFib n = p `par` q `pseq` (p + q) where p = parFib $ n - 1 q = parFib $ n - 2
fib :: Int -> Intfib 0 = 0fib 1 = 1fib n = fib (n - 1) + fib (n - 2)
main :: IO ()main = print $ parFib 40
![Page 29: Haskell - A Perspective](https://reader035.vdocument.in/reader035/viewer/2022062422/56813bd4550346895da4f903/html5/thumbnails/29.jpg)
Dual core$ time ./parfib.exe +RTS -N1102334155
real 0m1.998suser 0m0.015ssys 0m0.015s
$ time ./parfib.exe +RTS -N2102334155
real 0m1.337suser 0m0.015ssys 0m0.015s
![Page 30: Haskell - A Perspective](https://reader035.vdocument.in/reader035/viewer/2022062422/56813bd4550346895da4f903/html5/thumbnails/30.jpg)
Data parallel
(used in languages like High Performance Fortran)• Deterministic• Pure: parallel arrays• Shared memory initially; distributed memory eventually;
possibly even GPUs• mapP :: (a -> b) -> [:a:] -> [:b:]• zipWithP :: (a -> b -> c) -> [:a:] -> [:b:] -> [:c:]• filterP :: (a -> Bool) -> [:a:] -> [:a:] • sumP :: Num a => [:a:] -> a • import GHC.PArr
![Page 31: Haskell - A Perspective](https://reader035.vdocument.in/reader035/viewer/2022062422/56813bd4550346895da4f903/html5/thumbnails/31.jpg)
Final comments
• Very active community (Haskell Cafe and other mailing lists with very good info to noise ratio)
• Great support for algorithms• Lots of libraries (many of them are very specialised)• Very wide use in academia, less outside • Might be hard to find knowledgeable developers
![Page 32: Haskell - A Perspective](https://reader035.vdocument.in/reader035/viewer/2022062422/56813bd4550346895da4f903/html5/thumbnails/32.jpg)
Further informationhaskell.org Real World Haskell Yet Another Haskell TutorialLearn You a Haskell for a Great Good!http://tryhaskell.org/HEAT (Haskell Educational Advancement Tool) Haskell Cheat Sheet The Monad.Reader (if you want to bend your mind :)Simon Peyton-Jones (Principal Researcher at Microsoft) Philip WadlerGalois Multicore/Don StewartMicrosoft Channel9Going Deep Lectures Carnegie Mellon curriculum change
![Page 33: Haskell - A Perspective](https://reader035.vdocument.in/reader035/viewer/2022062422/56813bd4550346895da4f903/html5/thumbnails/33.jpg)
Q&A