<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Heap Heap Array! &#187; Functional Programming</title>
	<atom:link href="http://siwoti.com/blog/category/functional-programming/feed/" rel="self" type="application/rss+xml" />
	<link>http://siwoti.com/blog</link>
	<description>Putting the &#039;dys&#039; in &#039;functional programming&#039;.</description>
	<lastBuildDate>Fri, 03 Sep 2010 03:05:51 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Project Euler Problem 14</title>
		<link>http://siwoti.com/blog/2009/12/project-euler-problem-14/</link>
		<comments>http://siwoti.com/blog/2009/12/project-euler-problem-14/#comments</comments>
		<pubDate>Mon, 07 Dec 2009 05:24:47 +0000</pubDate>
		<dc:creator>Benjamin Geiger</dc:creator>
				<category><![CDATA[F#]]></category>
		<category><![CDATA[Functional Programming]]></category>
		<category><![CDATA[Project Euler]]></category>

		<guid isPermaLink="false">http://siwoti.com/blog/?p=74</guid>
		<description><![CDATA[For the last 36 hours, off and on, I&#8217;ve been working on solutions to Project Euler problems, just to learn some F#. I started at the beginning and have been working my way up, as the difficulty increases. So far, I&#8217;ve solved problems 1-10, 14, 47, and 243. Problem 9 doesn&#8217;t really count as I [...]]]></description>
			<content:encoded><![CDATA[<p>For the last 36 hours, off and on, I&#8217;ve been working on solutions to <a href="http://projecteuler.net/" onclick="pageTracker._trackPageview('/outgoing/projecteuler.net/?referer=');">Project Euler</a> problems, just to learn some F#. I started at the beginning and have been working my way up, as the difficulty increases.</p>
<p>So far, I&#8217;ve solved problems 1-10, 14, 47, and 243. Problem 9 doesn&#8217;t really count as I basically borrowed the code verbatim from <a href="http://diditwith.net/2009/03/09/YAPESProblemNine.aspx" onclick="pageTracker._trackPageview('/outgoing/diditwith.net/2009/03/09/YAPESProblemNine.aspx?referer=');">another site</a>, and problem 5 almost doesn&#8217;t as I solved it with pencil and paper.</p>
<p>I may cover a few of the others later, but for now I&#8217;ll focus on 14.</p>
<p><span id="more-74"></span></p>
<p><a href="http://projecteuler.net/index.php?section=problems&#038;id=14" onclick="pageTracker._trackPageview('/outgoing/projecteuler.net/index.php?section=problems_038_id=14&amp;referer=');">Problem 14</a> was a bit trickier than it looked. I knew from the start that I&#8217;d have to resort to some sort of memoization to get runtime down to a reasonable level. As noted on the Project Euler site:</p>
<blockquote><p>
Each problem has been designed according to a &#8220;one-minute rule&#8221;, which means that although it may take several hours to design a successful algorithm with more difficult problems, an efficient implementation will allow a solution to be obtained on a modestly powered computer in less than one minute.
</p></blockquote>
<p>A brute-force solution without memoization took way too long on the virtual machine I use to run Visual Studio 2010. (I don&#8217;t know how long, because I killed it after about ten minutes.) So, I borrowed some code from <cite>Programming F#</cite> (page 199):</p>
<pre class="brush: fsharp; title: ; notranslate">
open System.Collections.Generic

let memoize (f : 'a -&gt; 'b) =
    let dict = new Dictionary&lt;'a, 'b&gt;()

    let memoizedFunc (input : 'a) =
        match dict.TryGetValue(input) with
        | true, x -&gt; x
        | false, _ -&gt;
            let answer = f input
            dict.Add(input, answer)
            answer

    memoizedFunc
</pre>
<p>The project statement uses a starting point of 13, and gives a sequence length of 10; I realized that if the sequence ever reached 13, for instance, it would always be at 1 ten iterations later. My first attempt at a solution copied around the actual sequence of numbers for each starting point. Ideally, if I always tacked the new number on as the head, the tail would eventually be a list that had already been generated, and wouldn&#8217;t need to be recreated or even copied, as the new list could just point to the old one.</p>
<p>While this wasn&#8217;t a horrible idea, it seemed a lot slower than I&#8217;d like. So, I switched to a simple tally of sequence length. Still slow.</p>
<p>After I let the program run all the way through, I realized my problem: the debugging output. What started as a ten-minute process shortened itself to about ten seconds when I removed the printfn from the inner function. I probably could have kept the sequence after all.</p>
<pre class="brush: fsharp; title: ; notranslate">
let rec collatz =
    // The only reason to create an inner function here
    // is to memoize it. You have to call the outer
    // function recursively or the memoize function
    // won't catch it.
    let collatz_ (x : int64) =
        if x = 1L then 0
        elif x % 2L = 0L then
            1 + collatz (x / 2L)
        else
            1 + collatz (3L * x + 1L)

    memoize collatz_

// Candidates
[ 1L..999999L ]
    // Calculate path length for each, decorate
    |&gt; List.map (fun x -&gt; (collatz x, x))
    // Sort by path length...
    |&gt; List.sortBy fst
    // ... long paths first
    |&gt; List.rev
    // Give me just the longest path
    |&gt; List.head
    // Give me just the starting point
    |&gt; snd;;
</pre>
<p>PS: <a href="http://en.wikipedia.org/wiki/Collatz_conjecture" onclick="pageTracker._trackPageview('/outgoing/en.wikipedia.org/wiki/Collatz_conjecture?referer=');">if you&#8217;re asking why it&#8217;s called &#8220;collatz&#8221;?</a></p>
<p>So, what did I learn?</p>
<p>I learned that console output is <em>slow</em>. I also learned that decorating an input list with tuples (a la the &#8220;Schwartzian Transform&#8221;) is a useful technique in F#. Function pipelining is incredibly handy. And I&#8217;m addicted to Project Euler.</p>
]]></content:encoded>
			<wfw:commentRss>http://siwoti.com/blog/2009/12/project-euler-problem-14/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Fledgling Forays in F#</title>
		<link>http://siwoti.com/blog/2009/11/fledgling-forays-in-f/</link>
		<comments>http://siwoti.com/blog/2009/11/fledgling-forays-in-f/#comments</comments>
		<pubDate>Sat, 14 Nov 2009 04:01:48 +0000</pubDate>
		<dc:creator>Benjamin Geiger</dc:creator>
				<category><![CDATA[F#]]></category>
		<category><![CDATA[Functional Programming]]></category>

		<guid isPermaLink="false">http://siwoti.com/blog/?p=38</guid>
		<description><![CDATA[So, to start learning F#, I searched for existing F# code. One of the first snippets I found was the sieve of Eratosthenes in many languages, including F#. Except the listed F# &#8216;sieve&#8217; wasn&#8217;t; it did an exhaustive search from 2 to Math.Sqrt(int_of_float n) for every element n. I thought, &#8220;Even as a beginner, I [...]]]></description>
			<content:encoded><![CDATA[<p>So, to start learning F#, I searched for existing F# code. One of the first snippets I found was <a href="http://www.scriptol.com/programming/sieve.php" onclick="pageTracker._trackPageview('/outgoing/www.scriptol.com/programming/sieve.php?referer=');">the sieve of Eratosthenes in many languages</a>, including F#. Except the listed F# &#8216;sieve&#8217; wasn&#8217;t; it did an exhaustive search from 2 to <code>Math.Sqrt(int_of_float n)</code> for every element <code>n</code>.</p>
<p>I thought, &#8220;Even as a beginner, I can do better than that.&#8221; Here&#8217;s my first attempt:</p>
<p><span id="more-38"></span></p>
<pre class="brush: fsharp; title: ; notranslate">
let rec primes_match n =
    match n with
        | nn when nn &lt;= 1 -&gt; []
        | nn when nn &gt; 1 -&gt;
            let so_far = primes_match (n - 1)
            if (so_far |&gt; List.filter (fun d -&gt; nn % d = 0) |&gt; List.isEmpty)
            then nn :: so_far
            else so_far

let primes n = n |&gt; primes_match |&gt; List.rev
</pre>
<p>Then I realized &#8216;match&#8217; was a bit heavy for what I&#8217;m doing, and shifted to if/then/else:</p>
<pre class="brush: fsharp; title: ; notranslate">
let rec primes_match n =
    if n &lt;= 1 then []
    else
        let so_far = primes_match (n - 1)
        if (so_far |&gt; List.filter (fun d -&gt; n % d = 0) |&gt; List.isEmpty)
        then n :: so_far
        else so_far

let primes n = n |&gt; primes_match |&gt; List.rev
</pre>
<p>And finally, I learned about <code>List.exists</code>.</p>
<pre class="brush: fsharp; title: ; notranslate">
let rec primes_match n =
    if n &lt;= 1 then []
    else
        let so_far = primes_match (n - 1)
        if (so_far |&gt; List.exists (fun d -&gt; n % d = 0))
        then n :: so_far
        else so_far

let primes n = n |&gt; primes_match |&gt; List.rev
</pre>
<p>I was proud, but not satisfied. There are still two major problems with this code. First, it&#8217;s still not the sieve of Eratosthenes. It&#8217;s just a more-time-efficient version (I think, maybe) of the original algorithm. Second, it&#8217;s not tail-recursive, and stack depth grows with the input parameter, so it can only generate primes up to 32,750 or so.</p>
<p>So, I started from scratch. I managed to create a new sieve function that is, in fact, the sieve of Eratosthenes, and tail-recursive. As it turns out, Chris Smith has <a href="http://blogs.msdn.com/chrsmith/archive/2008/04/29/sieve-of-eratosthenes-in-f.aspx" onclick="pageTracker._trackPageview('/outgoing/blogs.msdn.com/chrsmith/archive/2008/04/29/sieve-of-eratosthenes-in-f.aspx?referer=');">a sieve implementation</a> as well, but I didn&#8217;t look at it before writing my own. Mine came out shorter, but probably less efficient.</p>
<pre class="brush: fsharp; title: ; notranslate">
let rec sieve_drain (sifted : int list) (unsifted : int list) =
    if List.isEmpty unsifted then sifted
    elif (sifted |&gt; List.exists (fun d -&gt; (List.head unsifted) % d = 0))
    then sieve_drain sifted (List.tail unsifted)
    else sieve_drain ((List.head unsifted) :: sifted) (List.tail unsifted)

let sieve n =
    sieve_drain [] (2::[3..2..n]) |&gt; List.rev
</pre>
<p>Any suggestions? Am I being too strict when it comes to functional style? Is there any way I can polish this?</p>
<p><b>Update:</b></p>
<p>I managed to find a cleaner way to do this:</p>
<pre class="brush: fsharp; title: ; notranslate">
let rec sieve_drain (sifted : int list) (unsifted : int list) =
    match unsifted with
    | [] -&gt; sifted
    | x :: xs -&gt;
        if not (sifted |&gt; List.exists (fun d -&gt; x % d = 0))
        then sieve_drain (x::sifted) xs
        else sieve_drain sifted xs

let sieve n =
    if n &lt; 2 then [] else sieve_drain [] (2::[3..2..n]) |&gt; List.rev
</pre>
<p>But it&#8217;s not very efficient. Chris Smith&#8217;s implementation (due to the use of shared state) takes about 2.5 seconds to run from 1 to 500,000. Mine takes about 55.</p>
]]></content:encoded>
			<wfw:commentRss>http://siwoti.com/blog/2009/11/fledgling-forays-in-f/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Trying To Think Functionally</title>
		<link>http://siwoti.com/blog/2009/11/trying-to-think-functionally/</link>
		<comments>http://siwoti.com/blog/2009/11/trying-to-think-functionally/#comments</comments>
		<pubDate>Fri, 13 Nov 2009 00:14:21 +0000</pubDate>
		<dc:creator>Benjamin Geiger</dc:creator>
				<category><![CDATA[F#]]></category>
		<category><![CDATA[Functional Programming]]></category>

		<guid isPermaLink="false">http://siwoti.com/blog/?p=11</guid>
		<description><![CDATA[Lisp is worth learning for the profound enlightenment experience you will have when you finally get it; that experience will make you a better programmer for the rest of your days, even if you never actually use Lisp itself a lot. [Eric S. Raymond] I, for one, know that I&#8217;m only partially enlightened. When I [...]]]></description>
			<content:encoded><![CDATA[<blockquote><p>
Lisp is worth learning for the profound enlightenment experience you will have when you finally get it; that experience will make you a better programmer for the rest of your days, even if you never actually use Lisp itself a lot.  [Eric S. Raymond]
</p></blockquote>
<p>I, for one, know that I&#8217;m only partially enlightened.</p>
<p>When I was taking &#8220;Programming Languages&#8221; (COP 4020), one of the languages covered, intended to represent the entirety of functional programming, was Common Lisp. We studied it for about two weeks. On the exam, a 5-point question asked us to write a function to determine whether a list was palindromic. I set off writing tons of code (on paper, even), checking for the equality of the first and last elements, then stripping them off and recursing on the rest.</p>
<p>As I handed in my exam, I commented on the difficulty of that question compared to the low point value. The professor looked at my test, then at me, and then she wrote on a scrap of paper so that the other students couldn&#8217;t see (yet):</p>
<p><code>(defun is-a-palindrome (lst) (equal lst (reverse lst)))</code></p>
<p><em>That&#8217;s</em> thinking functionally. I could hammer out the code, but I was writing C with a bunch of parentheses. I wasn&#8217;t really writing in Lisp.</p>
<p>When I started working here, I was writing a lot of Python. Python isn&#8217;t generally considered a functional language, but it has enough of the features (first class functions, lists, map/filter/reduce, etc) to give me a taste of power. Then I was forced into using VB.NET 2005, which felt like stepping back in time a decade. It had none of the Pythony goodness I was used to: no list comprehensions, no map/filter/reduce (with clunky forms added in VB 2008), and no lambda statements (halfassedly added in 2008 and properly added, supposedly, in 2010).</p>
<p>What skill I picked up from Python quickly began to fade.</p>
<p>My outlook was bleak, as well. I thought the .NET platform was headed for the same old languages and the same old paradigms, for the same old <a href="http://www.paulgraham.com/avg.html" onclick="pageTracker._trackPageview('/outgoing/www.paulgraham.com/avg.html?referer=');">Blub coders</a>. I was afraid that I&#8217;d end up a Blub coder&#8230; or worse, that I already was one.</p>
<p>Then I saw some of the nice features of C# in .NET 3.5 (and immediately started griping that VB didn&#8217;t have them), and what&#8217;s more, I found F#.</p>
<p>Let me say this up front: I like Lisp. Most of it makes very little sense to me, but I can feel the power behind it. Though I&#8217;ve wanted to learn a functional language for a while now, I know that my chances of ever getting a job writing it are slim, so I&#8217;ve focused on the standard OO and procedural languages. F# has the advantage of being backed by Microsoft; Visual Studio 2010 will have F# out of the box, and it&#8217;ll be right there on the desks of almost every .NET programmer, overcoming much of the inertia that leads people to use languages like VB.</p>
<p>So that&#8217;s why I&#8217;ve decided to throw myself into F#; it&#8217;s a paradigm I want to embrace, and a language that I may actually get paid to use someday. That&#8217;s worth reshaping my mind for.</p>
<p>And at the very least, I&#8217;ll end up writing better code in other languages.</p>
]]></content:encoded>
			<wfw:commentRss>http://siwoti.com/blog/2009/11/trying-to-think-functionally/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

