Parallel and Functional Programming

Robin Bate Boerop

Fredericton Developer User Group, 22 February 2012

Agenda Preface

The agenda includes the standard talk (search for “The Free Lunch Is Over”) to motivate learning to program with concurrency and parallelism.

Apologies if you have heard it before.

Estimated talk time: 1h15m.

Agenda

About this talk

This highly technical talk will explain the problems encountered by imperative programming languages (C/C++, Java), and will explain how functional programming languages and frameworks (Erlang, Node, Haskell) have created elegant solutions. The task of writing a high performance IRC server will serve as an example.

I am ditching the running example mentioned in the abstract.

About this talk

Goal 1: To explain why understanding parallel and concurrent programming is more important than ever.

Goal 2: To point you to “ahead-of-the-curve” software development tools and techniques for including parallelism and concurrency in the software that you make.

About The Speaker

(D&D joke appropriate for pre-WoW crowd.)

Moore's Law

Vocabulary 1

Concurrency: something to do with your problem.

Parallelism: seeking performance with repeated (or simply more) hardware.

Vocabulary 2

Data parallelism:

Vocabulary 3

Task parallelism:

Vocabulary 4

Semi-implicit parallelism:

Example of Semi-Implicit Parallelism

f list =
   sum (map blah list)
   --   ^^^

becomes

f list =
   sum (parMap blah list)
   --   ^^^^^^

Parallelism in Traditional PLs 1

Parallelism in Traditional PLs 2

Problems with Locks

High Intellectual Overhead of Traditional Concurrent Programming

Functional Parallel Programming

Node

Erlang

Haskell - What Is It?

Haskell

Advantages of Functional Programming for writing correct programs which include concurrency or parallelism.

Task Parallelism in Haskell

Example of Task Parallel Programming in Haskell Using STM

module Main where
import Control.Monad
import Control.Concurrent
import Control.Concurrent.STM

atomRead = atomically . readTVar
dispVar x = atomRead x >>= print
appV fn x = atomically $ readTVar x >>= writeTVar x . fn
milliSleep = threadDelay . (*) 1000

main = do
   shared <- atomically $ newTVar 0
   before <- atomRead shared
   putStrLn $ "Before: " ++ show before
   forkIO $ 25 `timesDo`
      (dispVar shared >> milliSleep 20)
   forkIO $ 10 `timesDo`
      (appV ((+) 2) shared >> milliSleep 50)
   forkIO $ 20 `timesDo`
      (appV pred shared >> milliSleep 25)
   milliSleep 800
   after <- atomRead shared
   putStrLn $ "After: " ++ show after
   where timesDo = replicateM_

Output

Before: 0
0
1
0
1
0
1
1
0
1
0
1
1
0
1
0
1
1
0
1
0
1
1
0
1
0
After: 0

Functional Programming for Parallelism and Concurrency: Summary