Functional Programming and Haskell - TWBR Away Day 2011

Preview:

DESCRIPTION

Explains why functional programming is back and shows some features from Haskell that are being ported to other languages. Presented at ThoughtWorks Brazil Away Day 2011.

Citation preview

Functional Programming with Haskell

Adriano Bonatabonat@thoughtworks.com

@tanob

Why FP?

• Source of new ideas

• Expressiveness

• Multi-core CPUs

• Different paradigm

New ideas:Garbage collection (LISP)Type inference (simply typed lambda calculus)GenericsType classes

Expressiveness:DSLs

What is it?

• Different programming paradigm

• OO

• Logic

• Procedural

• Functions are the main element in the language

Function applications“Functional programming is so called because a program consists entirely of functions. [...]

Typically the main function is defined in terms of other functions, which in turn are defined in terms of still more functions, until at the bottom level the functions are language primitives.”

John Hughes, 1989 - Why functional programming matters

OriginAlonzo Church developed Lambda

Calculus as part of his investigations on Math foundations

on 1936.

Lambda Calculus

• Variables

• Expressions (e1 e2)

• Lambda abstractions (λx. e)

Lambda Calculus (I)

• true = λxy. x

• false = λxy. y

• NOT a = (a)(false)(true)

• a AND b = (a)(b)(false)

• a OR b = (a)(true)(b)

• a XOR b = (a)((b)(false)(true))(b)

Haskell

• Academic origin

• Named in honor of Haskell Curry

• Defined by a committee

• First version released on 98 (Haskell 98)

Features• Pureness

• Type Inference

• Algebraic datatypes (ADTs)

• Pattern Matching

• Lazyness

• High Order Functions

• Currification (aka Partial Application)

• Type Classes

• Monads

Pureness

• No side-effects

• A function call can have no effect other than to compute its result

• Expressions can be evaluated at any time

• Programs are “referentially transparent”

Good for:* reasoning* compiler optimization* concurrency

Type Inference

Let’s see the types for these declarations:four = 4add x y = x + yemphasize x = x ++ “!”

Algebraic datatypesEnumeration:data Season = Summer | Winter | Autumn | Spring

Product:data Pair = Pair Int Int

Sum:data Shape = Circle Float | Rect Float Float

Polymorfic & Recursive:data Tree a = Leaf a | Node (Tree a) (Tree a)

Algebraic datatypes (I)

data Maybe a = Nothing | Just adata Either a b = Left a | Right b

Pattern Matching

Definition:sum [] = 0sum (elem:rest) = elem + sum rest

Application:sum [1,2,3,10]

Pattern Matching (I)

area (Circle rad) = pi * rad ^ 2area (Rect width height) = width * height

first (Pair value _) = value

High Order Functions

Functions which at least:

• Receive functions as parameters

• Return functions (aka curried functions)

High Order Functions (I)

map :: (a -> b) -> [a] -> [b]map f [] = []map f (x:xs) = f x : map f xs

Currification

add :: Int -> Int -> Intadd x y = x + y

inc :: Int -> Intinc = add 1

Lazyness

• aka “call by need”

• Expressions can be evaluated when necessary

• Allows the use of infinite lists

Being pure helps here

Lazyness (I)

Definition:even_numbers :: [Int]even_numbers = filter even [1..]

Application:take 5 even_numbers

Lazyness (II)

fibs :: [Int]fibs = 0 : 1 : zipWith (+) fibs (tail fibs)

From: http://en.wikipedia.org/wiki/Lazy_evaluation

Type Classes

• Created to solve the problem with numeric operator overload and equality testing

• Some type classes defined by Haskell 98:

• Eq

• Read/Show

Type Classes (I)

class Eq a where(==), (/=) :: a -> a -> Boolx == y = not (x /= y)x /= y = not (x == y)

You can define what is called a “minimal implementation”.

Type Classes (II)data User = User { name :: String }

instance Eq User whereuser1 == user2 = name user1 == name user2

instance Show User whereshow user = name user

Automatic Derivation

data Season = Summer | Winter | Autumn | Springderiving (Show, Eq)

show Summer> “Summer”

Summer /= Winter> True

Monads

• Adds to the type system a way to describe actions

• The actions will happen in a certain order

Monads

• Common monads:

• IO

• State

• Reader

• Maybe

Monads

thing1 >>= \x ->func1 x >>= \y ->

thing2 >>= \_ ->func2 y >>= \z ->

return z

do x <- thing1 y <- func1 x thing2 z <- func2 y return z

sugar no-sugar

Monads

class Monad m where (>>=) :: m a -> (a -> m b) -> m b (>>) :: m a -> m b -> m b return :: a -> m a

“return” is a bad name, it actually injects a value into the monadic type.

Logger Monadtype Log = [String]

data Logger resultType = Logger (resultType, Log) deriving Show

record x = Logger ((), [x])

instance Monad Logger where return value = Logger (value, []) prevLogger >>= nextAction = let Logger (prevResult, prevLog) = prevLogger Logger (newResult, newLog) = nextAction prevResult in Logger (newResult, prevLog ++ newLog)

Testing?

• Go read about QuickCheck!

Want to learn more?

Freely available online:http://book.realworldhaskell.org/

Your Knowledge Portfolio

"Learn at least one new language every year. [...] Different languages solve the same problems in different ways. By learning several different approaches, you can help broaden your thinking and avoid getting stuck in a rut."

The Pragmatic Programmer

Functional Programming with Haskell

Adriano Bonatabonat@thoughtworks.com

@tanob

Recommended