I would like to how can we implement producer/consumer in a functional programming language like Haskell? and how it will be different from an Imperative language? My understanding of functional programming language is primitive. Any help will be appreciated.
A producer/consumer abstraction using preemptive threads and messages passed through a channel:
import Data.Char
import Control.Concurrent
import Control.Concurrent.Chan
main = do
c <- newChan
cs <- getChanContents c -- a lazy stream of events from eventReader
forkIO (producer c) -- char producer
consumer cs
where
-- thread one: the event producer
producer c = forever $ do
key <- getChar
writeChan c key
-- thread two: the lazy consumer
consumer = mapM_ print . map shift
where shift c | isAlpha c = chr (ord c + 1)
| otherwise = c
You would use a similar model in Erlang. Threads to represent the consumer and producer, and a shared pipe of messages between them, each acting asynchronously.
I will add to dons
's excellent answer that the underlying mechanism here is something called an MVar
, and it is an imperative, parallel container for a value. You "put" and "get" into and out of an MVar. Getting an empty MVar blocks, as does putting a full one. It's simultaneously a communication mechanism and a synchronization mechanism. I believe it was invented by Arvind as part of the Monsoon/*t project. There is a beautiful book by Nikhil and Arvind which explains their pH dialect of parallel Haskell. Many of the ideas have been adopted into GHC, and the book is well worth reading.
Besides the stateful approaches mentioned by Norman and Don, you can also think of normal function application and laziness as producer and consumer.
Here is a producer for the natural numbers:
nats = [1..]
And here is a consumer that computes the squares of those numbers:
squares = map (\x -> x * x) nats
Producers such as yield return
in C# or generators in Python can often be expressed like this: as simple lazy lists in Haskell.