<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-5914548803542669731</id><updated>2011-07-31T04:25:08.787-07:00</updated><title type='text'>Adventures in Functional Programming</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://advfp.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5914548803542669731/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://advfp.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Barend Venter</name><uri>http://www.blogger.com/profile/09627180080427883334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>2</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-5914548803542669731.post-3337204088606774610</id><published>2010-05-19T10:53:00.000-07:00</published><updated>2010-05-24T21:07:14.027-07:00</updated><title type='text'>Parallel Programming in Haskell</title><content type='html'>&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Verdana,sans-serif; font-size: x-large;"&gt;A Parallel Programming Tutorial&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Times,'Times New Roman',serif;"&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Times,'Times New Roman',serif;"&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;What is parallel programming?&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Times,'Times New Roman',serif;"&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Times,'Times New Roman',serif;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style="font-size: small;"&gt;Parallel programming is a technique by which computations can be executed simultaneously on more than one processor to save time. These processors could be working together on the same machine, or could be distributed across a network. Parallel programming will never allow asymptotic gains in efficiency, a quadratic algorithm will still be quadratic, but you can improve computation time by a constant factor. When you have a combination of a computationally difficult task, a highly parallel machine to work on, and a parallel approach to solving the problem, the gain in efficiency from parallelism can be enormous. The gain is still limited, however: adding more processors yields diminishing returns as the improvement in computational efficiency begins to become asymptotic. Parallel programming also generally comes with a non-trivial cost in extra complexity.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Times,'Times New Roman',serif; font-size: x-large;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Times,'Times New Roman',serif; font-size: large;"&gt;&lt;span class="Apple-style-span"&gt;If it's so great, why am I not using parallel programming already?&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Times,'Times New Roman',serif; font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span style="font-size: small;"&gt;Parallel programming does incur a cost, and most people's machines are still single-processor machines which cannot directly benefit from parallel programming. This is changing rapidly, but most machines still do not offer enough parallelism to make parallel programming truly compelling. In addition to these hardware obstacles, programmers have not generally had access to good tools for parallel programming. Fortunately, Haskell with the Glasgow Haskell Compiler makes this easy. The arguments for learning parallel programming in Haskell can be listed as follows:&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-size: small;"&gt;It is easy to learn to write parallel algorithms in the Haskell Programming Language &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size: small;"&gt;The Haskell Programming Language makes parallel annotations cheap&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size: small;"&gt;Hardware manufacturers have been improving parallelism instead of clock speed&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size: small;"&gt;Distributed and highly parallel computers have long been available in academic and industrial settings&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-size: large;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'times new roman'; font-size: large;"&gt;&lt;span class="Apple-style-span"&gt;Operational semantics: &lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;seq&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Times,'Times New Roman',serif;"&gt; and friends&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'times new roman';"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'times new roman'; font-size: small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; Take a look at the following type signatures:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace; font-size: small;"&gt;const :: b&amp;nbsp;-&amp;gt;&amp;nbsp;a&amp;nbsp;-&amp;gt;&amp;nbsp;b&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace; font-size: small;"&gt;seq &amp;nbsp; :: a&amp;nbsp;-&amp;gt;&amp;nbsp;b&amp;nbsp;-&amp;gt;&amp;nbsp;b&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace; font-size: small;"&gt;pseq &amp;nbsp;:: a&amp;nbsp;-&amp;gt;&amp;nbsp;b&amp;nbsp;-&amp;gt;&amp;nbsp;b&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace; font-size: small;"&gt;par &amp;nbsp; :: a -&amp;gt; b&amp;nbsp;-&amp;gt;&amp;nbsp;b&lt;/span&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;blockquote&gt;&lt;span style="font-size: small;"&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue',Arial,Helvetica,sans-serif;"&gt;Note:&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue',Arial,Helvetica,sans-serif; font-size: small;"&gt; &lt;/span&gt;&lt;span style="font-size: small;"&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue',Arial,Helvetica,sans-serif;"&gt;These type signatures may look slightly different from what shows up in GHCi. &lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;a&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue',Arial,Helvetica,sans-serif;"&gt; and &lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;b&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue',Arial,Helvetica,sans-serif;"&gt; are used to illustrate the similarity of these functions.&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;span class="Apple-style-span" style="font-family: Times,'Times New Roman',serif; font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;What's going on here? From the type signatures, you should be suspecting that these functions don't actually do anything at all to their arguments. You would be absolutely right. Here is how we could implement them:&lt;/span&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace; font-size: small;"&gt;const a b = a&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace; font-size: small;"&gt;seq &amp;nbsp; a b = b&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace; font-size: small;"&gt;pseq &amp;nbsp;a b = b&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace; font-size: small;"&gt;par &amp;nbsp; a b = b&lt;/span&gt;&lt;/blockquote&gt;&lt;span class="Apple-style-span" style="font-family: Times,'Times New Roman',serif; font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; None of these functions appear to do anything useful with these definitions. However,&lt;span class="Apple-style-span" style="font-family: 'Times New Roman';"&gt;&lt;span class="Apple-style-span" style="font-family: Times,'Times New Roman',serif;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;seq&lt;/span&gt;,&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;pseq&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Times,'Times New Roman',serif;"&gt;, and&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;par&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Times,'Times New Roman',serif;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;all give information about the how the code should be evaluated. This is important: parallelism doesn't say anything about &lt;b&gt;what&lt;/b&gt;&amp;nbsp;is being evaluated, just about &lt;b&gt;how&lt;/b&gt;&amp;nbsp;it is being evaluated. To maintain this behavioral difference as to how things are evaluated,&amp;nbsp;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;seq&lt;/span&gt;, &lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace; font-size: small;"&gt;pseq&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Times,'Times New Roman',serif; font-size: small;"&gt;, and &lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace; font-size: small;"&gt;par&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Times,'Times New Roman',serif; font-size: small;"&gt; cannot be defined like this: they each have different &lt;b&gt;operational semantics&lt;/b&gt; from each other, even though they have the same &lt;b&gt;denotational semantics&lt;/b&gt;. Parallelism is &lt;b&gt;operational semantics&lt;/b&gt;, not &lt;b&gt;denotational semantics&lt;/b&gt;, because (reiterating our earlier observation) computing a value in parallel does not&lt;b&gt; &lt;/b&gt;change &lt;b&gt;what&lt;/b&gt; the result of the computation is, only &lt;b&gt;how&lt;/b&gt; it is arrived at. Let's look at the operational semantics of these functions one by one:&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Times,'Times New Roman',serif; font-size: small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;const&lt;/span&gt; does not have any special operational semantics. It is evaluated normally.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Times,'Times New Roman',serif; font-size: small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;seq&lt;/span&gt; ensures that if the right side is evaluated, the left side is also evaluated.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Times,'Times New Roman',serif; font-size: small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;pseq&lt;/span&gt; is like &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;seq&lt;/span&gt;, but additionally ensures that the left side is evaluated before the right side.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Times,'Times New Roman',serif; font-size: small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;par&lt;/span&gt; is like &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;seq&lt;/span&gt;, but allows the right side to be evaluated while the left side is still evaluating.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'times new roman'; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia,serif;"&gt;&lt;span class="Apple-style-span" style="font-family: 'times new roman';"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;b style="font-family: Verdana,sans-serif;"&gt;Hint: &lt;/b&gt;&lt;i style="font-family: Verdana,sans-serif;"&gt;An easy way to understand difference between &lt;/i&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;seq&lt;/span&gt;&lt;i style="font-family: Verdana,sans-serif;"&gt; and &lt;/i&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;pseq&lt;/span&gt;&lt;i style="font-family: Verdana,sans-serif;"&gt; is that note that the expression "&lt;/i&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;b `seq` a `seq` b&lt;/span&gt;&lt;i style="font-family: Verdana,sans-serif;"&gt;" has the same operational semantics as the expression "&lt;/i&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;a `seq` b&lt;/span&gt;&lt;i style="font-family: Verdana,sans-serif;"&gt;"&lt;/i&gt;&lt;i style="font-family: Verdana,sans-serif;"&gt;, while the same property does not hold for &lt;/i&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;pseq&lt;/span&gt;&lt;i&gt;. &lt;/i&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'times new roman'; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia,serif;"&gt;&lt;span class="Apple-style-span" style="font-family: 'times new roman';"&gt;&lt;span class="Apple-style-span"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Apple-style-span"&gt;Note that, because the first arguments to &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;seq&lt;/span&gt;, &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;pseq&lt;/span&gt;, and &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;par&lt;/span&gt; are ignored, they can be of any type, including the unit type &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;()&lt;/span&gt;. However, because this argument will be evaluated, it cannot be &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;undefined&lt;/span&gt; (try this in GHCi! Note that you may hear &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;undefined&lt;/span&gt; referred to as bottom and see it written as &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: small;"&gt;⊥&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'times new roman'; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia,serif;"&gt;&lt;span class="Apple-style-span" style="font-family: 'times new roman';"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;). &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;par&lt;/span&gt; is particularly interesting because it does not guarantee that the evaluation will actually happen in parallel, it only hints that it could happen in parallel, only guaranteeing that both will be evaluated, like &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;seq&lt;/span&gt;. The fact that you aren't guaranteed a parallel evaluation is a good thing, it means you can safely use &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;par&lt;/span&gt; wherever it seems you may benefit without needing to worry about the overhead of real parallelism. &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;pseq&lt;/span&gt; is important because if the left hand operand is your complicated parallel evaluation strategy, you will want that to complete all its work before you start evaluating the right operand (remember, &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;seq&lt;/span&gt; does not guarantee this).&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'times new roman'; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia,serif;"&gt;&lt;span class="Apple-style-span" style="font-family: 'times new roman';"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; You now know enough to start writing parallel algorithms in Haskell. There are easier ways to do this than to explicitly use &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;par&lt;/span&gt; and &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;pseq&lt;/span&gt;, and we will be covering those later when we cover parallel strategies (recall that &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;pseq&lt;/span&gt; can use a left hand operand of type &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;()&lt;/span&gt;, this will be important later). However, for the purposes of example, let's implement a simple parallel algorithm right now:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'times new roman'; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia,serif;"&gt;&lt;span class="Apple-style-span" style="font-family: 'times new roman';"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;br /&gt;pmap :: (a -&amp;gt; b) -&amp;gt; [a] -&amp;gt; [b]&lt;br /&gt;pmap _ [] = []&lt;br /&gt;pmap f (x:xs) = hd `par` tl `pseq` hd:tl&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; where&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;            hd = f x&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;            tl = pmap f xs&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span style="font-size: small;"&gt;&lt;b style="font-family: Verdana,sans-serif;"&gt;Note:&lt;/b&gt;&lt;/span&gt;&lt;span style="font-family: Verdana,sans-serif; font-size: small;"&gt; &lt;/span&gt;&lt;span style="font-size: small;"&gt;&lt;i&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;It is not enough to simply annotate your code to get your program to actually run in parallel! You will first need to pass the Glasgow Haskell Compiler the&lt;/span&gt; "&lt;/i&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;-threaded&lt;/span&gt;&lt;span style="font-size: small;"&gt;&lt;i&gt;" &lt;span style="font-family: Verdana,sans-serif;"&gt;option on the command line when compiling your program. You will also need a multi-core machine to observe any parallelism.&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; This is a strict map over a list (don't try this on an infinite list!). hd and tl are calculated before &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;pmap&lt;/span&gt; returns, and they are allowed to be calculated in parallel. No parallelism is guaranteed for &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;pmap&lt;/span&gt;&lt;span style="font-size: small;"&gt;, but you have told the compiler that you think it would be a good idea to evaluate &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;hd&lt;/span&gt;&lt;span style="font-size: small;"&gt; and &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;tl&lt;/span&gt;&lt;span style="font-size: small;"&gt; in parallel.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Trebuchet MS&amp;quot;,sans-serif;"&gt;&lt;b&gt;If you have any doubts, this would be a good point to stop and read before continuing.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;span style="font-size: large;"&gt;&lt;span style="font-family: Times,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Parallel programming with Strategies&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; So far we have only talked about parallel programming with the parallel annotation. Although these parallel annotations are already at a high level of abstraction, we still need to explicitly structure our annotations to get the evaluation order we want. Functions over commonly used data structures are often annotated for parallelism in the same ways; why not create special functions which have the sole purpose of evaluating the members of a data structure? These strategies live in &lt;a href="http://www.haskell.org/ghc/docs/6.8.3/html/libraries/parallel/Control-Parallel-Strategies.html"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Control.Parallel.Strategies&lt;/span&gt;&lt;/a&gt; and two type synonyms live in this module's source code:&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;Done&lt;/span&gt;&lt;span style="font-size: small;"&gt;, a synonym for &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;()&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;Strategy a&lt;/span&gt;&lt;span style="font-size: small;"&gt;, a synonym for &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;a -&amp;gt; ()&lt;/span&gt;&lt;span style="font-size: small;"&gt;, defined with the &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;Done&lt;/span&gt;&lt;span style="font-size: small;"&gt; synonym above.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; As you may already realize, a &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;Strategy&lt;/span&gt;&lt;span style="font-size: small;"&gt; returns nothing and any &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;Strategy&lt;/span&gt;&lt;span style="font-size: small;"&gt; can be written in the form &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;f _ = ()&lt;/span&gt;&lt;span style="font-size: small;"&gt; without any change of denotational semantics. A &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;Strategy&lt;/span&gt;&lt;span style="font-size: small;"&gt; encodes operational semantics over an input type; you will generally define them in terms of the functions covered in the previous chapter. The &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;Strategy&lt;/span&gt;&lt;span style="font-size: small;"&gt; type constructor takes a single type parameter: the type which it can evaluate using its evaluation strategy (its operational semantics). &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;Control.Parallel.Strategies&lt;span style="font-family: Times,&amp;quot;Times New Roman&amp;quot;,serif;"&gt; deserves an article to itself, but for now, &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: small;"&gt;let's take a look at some of the functions defined in &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;Control.Parallel.Strategies&lt;span style="font-family: Times,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;, some of which will be needed to understand a new implementation of &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;pmap&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: small;"&gt;:&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;using&lt;/span&gt;&lt;span style="font-size: small;"&gt;: applies its left hand argument, an &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;a&lt;/span&gt;&lt;span style="font-size: small;"&gt;, to its right hand argument, a &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;Strategy a&lt;span style="font-family: Times,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;,&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: small;"&gt; then returns its left hand argument. This guarantees that the left hand will be evaluated strictly using the given strategy when &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;using&lt;/span&gt;&lt;span style="font-size: small;"&gt; itself is evaluated.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;demanding&lt;/span&gt;&lt;span style="font-size: small;"&gt;: evaluates its right hand argument, a &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;Done&lt;/span&gt;&lt;span style="font-size: small;"&gt; (intended to be a fully applied strategy), then returns its left hand argument. You'd generally use it if the left hand argument can be computed more quickly after the evaluation of the fully applied parallel strategy on the right.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;r0&lt;/span&gt;&lt;span style="font-size: small;"&gt; &lt;/span&gt;&lt;span style="font-family: Times,&amp;quot;Times New Roman&amp;quot;,serif; font-size: small;"&gt;is a strategy that does not do anything at all.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;rwhnf&lt;/span&gt;&lt;span style="font-size: small;"&gt; is a strategy that strictly evaluates its argument&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;parList&lt;/span&gt;&lt;span style="font-size: small;"&gt; applies a strategy to every element of a list&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;parMap&lt;span style="font-family: Times,&amp;quot;Times New Roman&amp;quot;,serif;"&gt; maps over a list, then applies a strategy to every element of the list using &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;parList&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;blockquote&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;&lt;span style="font-family: Times,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;b style="font-family: Verdana,sans-serif;"&gt;Hint:&lt;/b&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt; &lt;/span&gt;&lt;i style="font-family: Verdana,sans-serif;"&gt;You may be wondering about how &lt;/i&gt;&lt;span style="font-family: Times,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;parMap&lt;/span&gt;&lt;/span&gt;&lt;i style="font-family: Verdana,sans-serif;"&gt; works. Won't the mapped function be applied sequentially before there is a chance to use the parallel strategy &lt;/i&gt;&lt;span style="font-family: Times,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;parList&lt;/span&gt;&lt;/span&gt;&lt;i&gt;&lt;span style="font-family: Times,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;? Recall that Haskell is a non-strict, or lazy language, and the list type is also lazy. When&lt;/span&gt; "&lt;/span&gt;&lt;/i&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;map f&lt;/span&gt;&lt;i style="font-family: Verdana,sans-serif;"&gt;" is applied to the list, no evaluation is actually done, all that happens is that a list &lt;/i&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;xs&lt;/span&gt;&lt;i style="font-family: Verdana,sans-serif;"&gt; is now a list "&lt;/i&gt;&lt;span style="font-family: Times,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;map f xs&lt;/span&gt;&lt;/span&gt;&lt;i&gt;&lt;span style="font-family: Times,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;". &lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;&lt;span style="font-family: Times,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; We can now re-implement our earlier pmap function using some of these terms:&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;&lt;span style="font-family: Times,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;pmap = parMap rwhnf&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;span style="font-family: Times,&amp;quot;Times New Roman&amp;quot;,serif; font-size: small;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; As you can see, this definition&amp;nbsp;&lt;/span&gt;&lt;span style="font-size: small;"&gt; is much simpler and higher level. It simply says that our parallel map strictly evaluates each application of its given argument, in parallel. More on Control.Parallel.Strategies will be coming. For now, I highly recommend you take a look at the &lt;a href="http://www.haskell.org/ghc/docs/6.8.3/html/libraries/parallel/src/Control-Parallel-Strategies.html"&gt;source code&lt;/a&gt;, as you can learn a lot from reading it. Good luck, and have fun!&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;PS: Seems like "WYSIWYG" does not quite hold for Blogspot. Sorry about the formatting hiccups. &lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'times new roman';"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia,serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5914548803542669731-3337204088606774610?l=advfp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://advfp.blogspot.com/feeds/3337204088606774610/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://advfp.blogspot.com/2010/05/parallel-programming-in-haskell.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5914548803542669731/posts/default/3337204088606774610'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5914548803542669731/posts/default/3337204088606774610'/><link rel='alternate' type='text/html' href='http://advfp.blogspot.com/2010/05/parallel-programming-in-haskell.html' title='Parallel Programming in Haskell'/><author><name>Barend Venter</name><uri>http://www.blogger.com/profile/09627180080427883334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5914548803542669731.post-4880704954958201564</id><published>2010-05-10T13:18:00.000-07:00</published><updated>2010-05-10T16:59:27.526-07:00</updated><title type='text'>Who I am, and why I am starting this blog</title><content type='html'>Hello reader,&lt;br /&gt;&lt;br /&gt;My name is Barend Venter. As of writing this, I am an undergraduate studying Computer Science at Central Washington University at Ellensburg WA. I am writing this blog to document my experiences using functional programming on Windows, so that others may benefit from my solutions or contribute their own. The second purpose of this blog is to advocate functional programming.&lt;br /&gt;&lt;br /&gt;My languages of choice at this point are F# and Haskell. I have written many applications in those languages, most of them trivial but some a bit more ambitious. The most substantial of these was a full implementation of the Rabin public key cipher for key exchange and a key generator to use with it. As time permits, I may also write on languages that have piqued my interest but in which I have not yet coded, such as Erlang or Scala.&lt;br /&gt;&lt;br /&gt;As I pointed out, I intend to advocate functional programming. Functional programming needs advocates: many programmers are barely aware it exists, and do not understand how functional programming works or why people use it. People who advocate the use of functional languages and explain how to tackle difficult problems not covered in beginners' textbooks could do a lot to raise awareness of the discipline. If people are aware of the motivation behind functional programming, they can provide better support for functional styles of programming when writing libraries which functional programmers will want to use. People who are aware of the functional programming style may also find that the functional programming style simplifies some difficult programming problems and makes them more approachable.&lt;br /&gt;&lt;br /&gt;I am still speaking in very vague terms here. In the coming months, I will be covering more specific examples of how I address my personal projects and class assignments in a functional way, and presenting my experiences with the tools and libraries available with for functional programmers (probably just Haskell, but I may touch on Visual Studio tools that pique my interest).&lt;br /&gt;&lt;br /&gt;&lt;div&gt;My intended audience are programmers who have already perused free online resources like&lt;i&gt; Real World Haskell&lt;/i&gt;, &lt;i&gt;Learn You a Haskell for Great Good&lt;/i&gt;, and &lt;i&gt;A Gentle Introduction to Haskell&lt;/i&gt;. I will however try to write such that anyone clever and determined enough should be able to understand what I am writing about.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Here are some links to the resources mentioned above:&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Real World Haskell: &lt;a href="http://book.realworldhaskell.org/read/"&gt;http://book.realworldhaskell.org/read/&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;Learn You a Haskell for Great Good: &lt;a href="http://learnyouahaskell.com/"&gt;http://learnyouahaskell.com&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;A Gentle Introduction to Haskell: &lt;a href="http://www.haskell.org/tutorial/"&gt;http://www.haskell.org/tutorial/&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;a href="http://www.haskell.org/tutorial/"&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;I would recommend you glance over these briefly if you are unfamiliar with the Haskell programming language.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;If you want to learn F#, I'd recommend buying &lt;i&gt;Expert F#&lt;/i&gt; by Don Syme. The F# language has been changing at a fast pace and a lot of previously "built-in" features have been removed from the language and placed in libraries. You will want to pay attention to the examples in that book, as some of them may no longer work with the current version of F#.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;My plan is to update at a minimum once every 2 months. My first planned post will be on parallel programming in Haskell, but I may deviate if I find something else more interesting to write about. I look forward to writing to you.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I am also a novice functional programmer, so I welcome any criticism and will gladly edit my posts accordingly to make them more instructive. So please read my blog postings critically, for your sake and mine, so we can learn from each other - or at least so that I can learn from you.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5914548803542669731-4880704954958201564?l=advfp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://advfp.blogspot.com/feeds/4880704954958201564/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://advfp.blogspot.com/2010/05/who-i-am-and-why-i-am-starting-this.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5914548803542669731/posts/default/4880704954958201564'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5914548803542669731/posts/default/4880704954958201564'/><link rel='alternate' type='text/html' href='http://advfp.blogspot.com/2010/05/who-i-am-and-why-i-am-starting-this.html' title='Who I am, and why I am starting this blog'/><author><name>Barend Venter</name><uri>http://www.blogger.com/profile/09627180080427883334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
