<?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/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Mike Burns, Coder</title>
	<atom:link href="http://mikeburnscoder.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://mikeburnscoder.wordpress.com</link>
	<description></description>
	<lastBuildDate>Tue, 22 Nov 2011 00:30:16 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='mikeburnscoder.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Mike Burns, Coder</title>
		<link>http://mikeburnscoder.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://mikeburnscoder.wordpress.com/osd.xml" title="Mike Burns, Coder" />
	<atom:link rel='hub' href='http://mikeburnscoder.wordpress.com/?pushpress=hub'/>
		<item>
		<title>timing-convenience, a Haskell package</title>
		<link>http://mikeburnscoder.wordpress.com/2011/11/21/timing-convenience-a-haskell-package/</link>
		<comments>http://mikeburnscoder.wordpress.com/2011/11/21/timing-convenience-a-haskell-package/#comments</comments>
		<pubDate>Tue, 22 Nov 2011 00:29:29 +0000</pubDate>
		<dc:creator>Mike Burns</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[convenience]]></category>
		<category><![CDATA[haskell]]></category>
		<category><![CDATA[scripting]]></category>
		<category><![CDATA[time]]></category>

		<guid isPermaLink="false">http://mikeburnscoder.wordpress.com/?p=114</guid>
		<description><![CDATA[I&#8217;ve been working on packages to make it easier to write in my favorite scripting language, Haskell. The first to make it on Hackage is timing-convenience. Install as usual: Then you can get the time three days ago: (See why I call it a scripting language? I&#8217;d like to see Perl be that obtuse!) I [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mikeburnscoder.wordpress.com&amp;blog=255131&amp;post=114&amp;subd=mikeburnscoder&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been working on packages to make it easier to write in my favorite scripting language, <a href="http://haskell.org/">Haskell</a>. The first to make it on Hackage is <a href="http://hackage.haskell.org/package/timing-convenience">timing-convenience</a>.</p>
<p>Install as usual:</p>
<p><pre class="brush: plain;">
cabal install timing-convenience
</pre></p>
<p>Then you can get the time three days ago:</p>
<p><pre class="brush: plain;">
import Data.Time
import Data.Time.Convenience

main = timeFor 3 Days Ago &gt;&gt;= putStrLn . show
</pre></p>
<p>(See why I call it a scripting language? I&#8217;d like to see Perl be that obtuse!)</p>
<p>I used this in <a href="https://github.com/mike-burns/this-week-in-open-source" title="this-week-in-open-source generation script">my script that generates</a> my <a href="http://robots.thoughtbot.com/tagged/this_week_in_open_source">This Week in Open Source series of blog posts on the thoughtbot blog</a>. I also made use of <a href="https://github.com/mike-burns/github" title="github API for Haskell">my github package</a>, which is still under development.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mikeburnscoder.wordpress.com/114/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mikeburnscoder.wordpress.com/114/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/mikeburnscoder.wordpress.com/114/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/mikeburnscoder.wordpress.com/114/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/mikeburnscoder.wordpress.com/114/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/mikeburnscoder.wordpress.com/114/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/mikeburnscoder.wordpress.com/114/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/mikeburnscoder.wordpress.com/114/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/mikeburnscoder.wordpress.com/114/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/mikeburnscoder.wordpress.com/114/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/mikeburnscoder.wordpress.com/114/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/mikeburnscoder.wordpress.com/114/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/mikeburnscoder.wordpress.com/114/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/mikeburnscoder.wordpress.com/114/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mikeburnscoder.wordpress.com&amp;blog=255131&amp;post=114&amp;subd=mikeburnscoder&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://mikeburnscoder.wordpress.com/2011/11/21/timing-convenience-a-haskell-package/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/01b9172e9f53e0955a1af7458752aa9b?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mike-burns</media:title>
		</media:content>
	</item>
		<item>
		<title>Dynamic Class Methods in Ruby</title>
		<link>http://mikeburnscoder.wordpress.com/2011/11/07/ruby-dynamic-class-methods/</link>
		<comments>http://mikeburnscoder.wordpress.com/2011/11/07/ruby-dynamic-class-methods/#comments</comments>
		<pubDate>Mon, 07 Nov 2011 11:34:34 +0000</pubDate>
		<dc:creator>Mike Burns</dc:creator>
				<category><![CDATA[ruby]]></category>
		<category><![CDATA[class-oriented]]></category>
		<category><![CDATA[object-oriented]]></category>
		<category><![CDATA[hacks]]></category>
		<category><![CDATA[activemodel]]></category>
		<category><![CDATA[instance methods]]></category>
		<category><![CDATA[class methods]]></category>
		<category><![CDATA[unobtrusive ruby]]></category>

		<guid isPermaLink="false">http://mikeburnscoder.wordpress.com/?p=106</guid>
		<description><![CDATA[Rails has a whole slew of class methods that really should be instance methods. The most notable of these methods is ActiveModel::Naming&#8216;s model_name, which is a class method that is expected on every ActiveModel object (for example, it is expected by form_for). This code uses that as an example, but the pattern applies anywhere. If [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mikeburnscoder.wordpress.com&amp;blog=255131&amp;post=106&amp;subd=mikeburnscoder&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Rails has a whole slew of class methods that really should be instance methods. The most notable of these methods is <code>ActiveModel::Naming</code>&#8216;s <code>model_name</code>, which is a class method that is expected on every ActiveModel object (for example, it is expected by <code>form_for</code>). This code uses that as an example, but the pattern applies anywhere.</p>
<p>If you want to make an ActiveModel factory, which is <a href="http://en.wikipedia.org/wiki/Factory_method_pattern" title="Factory pattern">a boring and classic design pattern</a>, then you need to deal with the fact that the <code>model_name</code> must be both a class method <em>and</em> different for each instance of your factory. That is:</p>
<p><pre class="brush: ruby;">
a = ActiveModelFactory.new(&quot;hello&quot;)
b = ActiveModelFactory.new(&quot;goodbye&quot;)
a.class.model_name.should == &quot;hello&quot;
b.class.model_name.should == &quot;goodbye&quot;
a.class.model_name.should == &quot;hello&quot;
</pre></p>
<p>Here&#8217;s how that looks:</p>
<p><pre class="brush: ruby;">
class ActiveModelFactory
  def initialize(model_name)
    @model_name = model_name
  end

  def class_with_model_name
    self.class_without_model_name.tap do |c|
      c.instance_variable_set('@_model_name', @model_name)
      (class &lt;&lt; c; self; end).send(:define_method,:model_name) do
        value = self.instance_variable_get('@_model_name')
        model_namer = Struct.new(:name).new(value)
        ActiveModel::Name.new(model_namer)
      end
    end
  end
  alias class_without_model_name class
  alias class class_with_model_name
end
</pre></p>
<p>Going through this: the initializer takes the model name and tucks it away in an instance variable, where it belongs. That part is straight-forward.</p>
<p>To make the <code>model_name</code> class method work we redefine the class to be different for each instance. It goes like this:</p>
<p>The <code>class_with_model_name</code> method produces the instance&#8217;s class, but first it modifies it. It sets an instance variable on the class itself, <code>@_model_name</code>, which is the same as the instance&#8217;s <code>@model_name</code> value. Then it defines a method named <code>model_name</code> on the class. Inside <code>model_name</code> it gets the value of this <code>@_model_name</code> instance variable, which has traveled from the factory instance through the class into an eigenclass and into a <code>define_method</code> block. Once it has this value it builds the struct and produces the <code>ActiveModel::Name</code> object as needed.</p>
<p>To tie this all together we use the <code>alias_method_chain</code> trick, which is used when someone screwed up. Alias <code>class</code> to <code>class_without_model_name</code>, then our <code>class_with_model_name</code> to <code>class</code>.</p>
<p>Elsewhere by me: <a href="http://robots.thoughtbot.com/post/10125070413/unobtrusive-ruby">Unobtrusive Ruby</a> doesn&#8217;t make people jump through these hoops. This research was done as part of my <a href="https://rubygems.org/gems/liaison">liaison</a> gem, which is an ActiveModel factory.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mikeburnscoder.wordpress.com/106/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mikeburnscoder.wordpress.com/106/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/mikeburnscoder.wordpress.com/106/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/mikeburnscoder.wordpress.com/106/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/mikeburnscoder.wordpress.com/106/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/mikeburnscoder.wordpress.com/106/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/mikeburnscoder.wordpress.com/106/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/mikeburnscoder.wordpress.com/106/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/mikeburnscoder.wordpress.com/106/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/mikeburnscoder.wordpress.com/106/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/mikeburnscoder.wordpress.com/106/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/mikeburnscoder.wordpress.com/106/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/mikeburnscoder.wordpress.com/106/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/mikeburnscoder.wordpress.com/106/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mikeburnscoder.wordpress.com&amp;blog=255131&amp;post=106&amp;subd=mikeburnscoder&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://mikeburnscoder.wordpress.com/2011/11/07/ruby-dynamic-class-methods/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/01b9172e9f53e0955a1af7458752aa9b?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mike-burns</media:title>
		</media:content>
	</item>
		<item>
		<title>Check your email into git using procmail</title>
		<link>http://mikeburnscoder.wordpress.com/2011/06/12/check-your-email-into-git-using-procmail/</link>
		<comments>http://mikeburnscoder.wordpress.com/2011/06/12/check-your-email-into-git-using-procmail/#comments</comments>
		<pubDate>Mon, 13 Jun 2011 00:21:33 +0000</pubDate>
		<dc:creator>Mike Burns</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://mikeburnscoder.wordpress.com/?p=98</guid>
		<description><![CDATA[In this blog post you will see how I commit my email into git one message at a time, as it is delivered, using procmail. This is a simple three-step process: Write a program to commit an email to git. This is the shell script I use; I named it ~/.bin/commit-an-email . It constructs a [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mikeburnscoder.wordpress.com&amp;blog=255131&amp;post=98&amp;subd=mikeburnscoder&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>In this blog post you will see how I commit my email into <a href="http://git-scm.com/">git</a> one message at a time, as it is delivered, using <a href="http://www.procmail.org/">procmail</a>.</p>
<p><img src="http://meatexplosion.com/emails-in-git.png" alt="Screenshot of the git log, showing the emails committed with their sender and subject" /></p>
<p>This is a simple three-step process:</p>
<h2>Write a program to commit an email to git.</h2>
<p>This is the shell script I use; I named it <code>~/.bin/commit-an-email</code> . It constructs a commit message with the sender and subject, adds the email to the repo, and commits using that message:</p>
<pre></code>#!/bin/sh

MAILDIR=$HOME/Maildir

commit_message=`grep '^From: ' $LASTFOLDER; grep '^Subject: ' $LASTFOLDER`

cd $MAILDIR &amp;&amp; \
git add `echo $LASTFOLDER | sed -e 's|^/home/mike/Maildir/||'` &amp;&amp; \
git commit -m "$commit_message"</code></pre>
<h2>Set a procmail <code>TRAP</code>.</h2>
<p>The <code><a href="http://www.enricozini.org/2007/tips/procmailrc-trap/">TRAP</a></code> setting points to a shell command which is executed after procmail has finished processing an email; it passes a copy of the email to <code>stdin</code>. Set this to the <code>commit-an-email</code> script in <code>~/.procmailrc</code> :</p>
<pre><code>TRAP=/usr/home/mike/.bin/commit-an-email</code></pre>
<h2>Clean up deletions and moves, and push.</h2>
<p>After the email is delivered you may read it, move it to another mailbox, or delete it. It&#8217;d be great if these actions were tracked as well. One option is to write a series of mutt macros that redefine <code>s</code>, <code>d</code>, <code>enter</code>, and so on, to do the appropriate git command. Alternatively, you could handle this nightly with this script, meant to be run from <code>cron</code>. I named it <code>~/.bin/commit-emails</code>:</p>
<pre><code>#!/bin/sh

GIT=/usr/local/bin/git
MAILDIR=$HOME/Maildir

cd $MAILDIR &amp;&amp; \
$GIT add . &amp;&amp; \
$GIT add -u &amp;&amp; \
$GIT commit -m "Nightly maintainance" &amp;&amp; \
$GIT push origin master &gt;/dev/null</code></pre>
<p>And this is my <code>crontab</code> :</p>
<pre><code>5 1 * * * /usr/home/mike/.bin/commit-email</code></pre>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mikeburnscoder.wordpress.com/98/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mikeburnscoder.wordpress.com/98/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/mikeburnscoder.wordpress.com/98/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/mikeburnscoder.wordpress.com/98/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/mikeburnscoder.wordpress.com/98/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/mikeburnscoder.wordpress.com/98/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/mikeburnscoder.wordpress.com/98/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/mikeburnscoder.wordpress.com/98/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/mikeburnscoder.wordpress.com/98/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/mikeburnscoder.wordpress.com/98/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/mikeburnscoder.wordpress.com/98/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/mikeburnscoder.wordpress.com/98/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/mikeburnscoder.wordpress.com/98/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/mikeburnscoder.wordpress.com/98/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mikeburnscoder.wordpress.com&amp;blog=255131&amp;post=98&amp;subd=mikeburnscoder&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://mikeburnscoder.wordpress.com/2011/06/12/check-your-email-into-git-using-procmail/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/01b9172e9f53e0955a1af7458752aa9b?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mike-burns</media:title>
		</media:content>

		<media:content url="http://meatexplosion.com/emails-in-git.png" medium="image">
			<media:title type="html">Screenshot of the git log, showing the emails committed with their sender and subject</media:title>
		</media:content>
	</item>
		<item>
		<title>One big mutt inbox, filtered after-the-fact using procmail</title>
		<link>http://mikeburnscoder.wordpress.com/2011/06/12/one-big-mutt-inbox-filtered-after-the-fact-using-procmail/</link>
		<comments>http://mikeburnscoder.wordpress.com/2011/06/12/one-big-mutt-inbox-filtered-after-the-fact-using-procmail/#comments</comments>
		<pubDate>Sun, 12 Jun 2011 23:03:59 +0000</pubDate>
		<dc:creator>Mike Burns</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[email]]></category>
		<category><![CDATA[inbox]]></category>
		<category><![CDATA[mutt]]></category>
		<category><![CDATA[procmail]]></category>

		<guid isPermaLink="false">http://mikeburnscoder.wordpress.com/?p=92</guid>
		<description><![CDATA[This article shows how to configure mutt and procmail to drop all emails into one big inbox which is then filtered, after you&#8217;ve read the email, into a distinct mailbox. For example, emails from your friends, girlfriend(s), sysadmin, and bank all show up in your inbox; after reading each they are sent to =friends/, =romances/, [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mikeburnscoder.wordpress.com&amp;blog=255131&amp;post=92&amp;subd=mikeburnscoder&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>This article shows how to configure <a href="http://www.mutt.org/">mutt</a> and <a href="http://www.procmail.org/">procmail</a> to drop all emails into one big inbox which is then filtered, after you&#8217;ve read the email, into a distinct mailbox. For example, emails from your friends, girlfriend(s), sysadmin, and bank all show up in your inbox; after reading each they are sent to =friends/, =romances/, =nightly/, and =finances/, respectively, automatically.</p>
<p>Rationale: each morning I read every email available to me, in order of a loose priority, no matter which mailbox it was in. As an email came in I&#8217;d immediately read it. It made little sense to open a new mailbox just to read yet another email; the mailboxes are more useful for saving the email to reference later.</p>
<p>In this setup you now need two procmailrcs: one that delivers stright to your inbox (you could probably get away without procmail for this role, even; I use procmail to handle the Maildir format and also to commit each email to git after delivering it), and one for the final filtering. I named these <code>~/.procmailrc</code> and <code>~/.procmail/finalrc</code> .</p>
<p>The ~/.procmailrc looks roughly like this:</p>
<pre><code>DEFAULT=$HOME/Maildir/
MAILDIR=$HOME/Maildir/
:0:
$MAILDIR</code></pre>
<p>(Mine also has a <code>TRAP</code>, as touched on above re git.)</p>
<p>Boring. It could probably be one line, even.</p>
<p>The other procmailrc, <code>~/.procmail/finalrc</code> , is your real procmail rules. If you have an existing <code>~/.procmailrc</code>, move it to this new place. Here&#8217;s an interesting snippet from mine:</p>
<pre><code>DEFAULT=$HOME/Maildir/
MAILDIR=$HOME/Maildir/
LOGFILE=/dev/null

# Friends
:0:
* ? formail -x"From" -x"From:" -x"Sender:" \
    -x"Reply-To:" -x"Return-Path:" -x"To:" \
        | fgrep -is -f ~/.procmail/friends.list
friends/

# Android
:0:
*^TO_droids@lists.bostonandroid.org
droids/

# Catch-all
:0:
$MAILDIR</code></pre>
<p>But great; so far emails are landing in your inbox and just staying there. Next you add this to your <code>~/.muttrc</code> :</p>
<pre><code>macro index y '&lt;enter-command&gt;unset wait_key&lt;enter&gt;&lt;tag-prefix&gt;&lt;pipe-entry&gt;/usr/local/bin/procmail /usr/home/mike/.procmail/finalrc&lt;enter&gt;&lt;tag-prefix&gt;&lt;delete-message&gt;&lt;enter-command&gt;set wait_key&lt;enter&gt;'
macro pager y '&lt;enter-command&gt;unset wait_key&lt;enter&gt;&lt;pipe-entry&gt;/usr/local/bin/procmail /usr/home/mike/.procmail/finalrc&lt;enter&gt;&lt;delete-message&gt;&lt;enter-command&gt;set wait_key&lt;enter&gt;'</code></pre>
<p>When you&#8217;re done reading an email press <code>y</code> . This will pipe that email through the <code>~/.procmail/finalrc</code> and delete it from your inbox, moving onto the next email.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mikeburnscoder.wordpress.com/92/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mikeburnscoder.wordpress.com/92/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/mikeburnscoder.wordpress.com/92/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/mikeburnscoder.wordpress.com/92/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/mikeburnscoder.wordpress.com/92/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/mikeburnscoder.wordpress.com/92/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/mikeburnscoder.wordpress.com/92/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/mikeburnscoder.wordpress.com/92/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/mikeburnscoder.wordpress.com/92/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/mikeburnscoder.wordpress.com/92/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/mikeburnscoder.wordpress.com/92/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/mikeburnscoder.wordpress.com/92/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/mikeburnscoder.wordpress.com/92/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/mikeburnscoder.wordpress.com/92/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mikeburnscoder.wordpress.com&amp;blog=255131&amp;post=92&amp;subd=mikeburnscoder&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://mikeburnscoder.wordpress.com/2011/06/12/one-big-mutt-inbox-filtered-after-the-fact-using-procmail/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/01b9172e9f53e0955a1af7458752aa9b?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mike-burns</media:title>
		</media:content>
	</item>
		<item>
		<title>DatePreference, an Android library</title>
		<link>http://mikeburnscoder.wordpress.com/2010/09/27/datepreference-an-android-library/</link>
		<comments>http://mikeburnscoder.wordpress.com/2010/09/27/datepreference-an-android-library/#comments</comments>
		<pubDate>Tue, 28 Sep 2010 03:27:43 +0000</pubDate>
		<dc:creator>Mike Burns</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://mikeburnscoder.wordpress.com/?p=83</guid>
		<description><![CDATA[Use this library if you want a DatePreference in your Android app.<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mikeburnscoder.wordpress.com&amp;blog=255131&amp;post=83&amp;subd=mikeburnscoder&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Use this library if you want a DatePreference in your Android app.</p>
<p>This is available as <a href="http://github.com/bostonandroid/DatePreference/tree/master">source code</a>, a <a href="http://bostonandroid.github.com/DatePreference/resources/DatePreference.jar">JAR</a>, and a <a href="http://bostonandroid.github.com/DatePreference/resources/DatePreference.dex">dex</a> file.</p>
<p><img src="http://bostonandroid.github.com/DatePreference/resources/date-of-birth-preference.png" alt="Screenshot showing the date preference for selecting the date of birth" /></p>
<p>Use it just like any other preference in your PreferenceScreen XML:</p>
<pre>&lt;org.bostonandroid.datepreference.DatePreference
      android:key="dob" android:title="@string/dob"
      android:defaultValue="1991.01.01" /&gt;</pre>
<p>There are also convenience methods for getting the selected value, setting the value, and so on. <a href="http://bostonandroid.github.com/DatePreference/org/bostonandroid/datepreference/DatePreference.html">Full API documentation</a> is available.</p>
<p>DatePreference was written during <a href="http://bostonandroid.org/">Boston Android</a> hackfests by Mike Burns with help from other Boston Android developers. <a href="http://github.com/bostonandroid/DatePreference/issues">Feedback welcome</a>!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mikeburnscoder.wordpress.com/83/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mikeburnscoder.wordpress.com/83/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/mikeburnscoder.wordpress.com/83/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/mikeburnscoder.wordpress.com/83/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/mikeburnscoder.wordpress.com/83/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/mikeburnscoder.wordpress.com/83/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/mikeburnscoder.wordpress.com/83/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/mikeburnscoder.wordpress.com/83/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/mikeburnscoder.wordpress.com/83/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/mikeburnscoder.wordpress.com/83/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/mikeburnscoder.wordpress.com/83/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/mikeburnscoder.wordpress.com/83/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/mikeburnscoder.wordpress.com/83/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/mikeburnscoder.wordpress.com/83/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mikeburnscoder.wordpress.com&amp;blog=255131&amp;post=83&amp;subd=mikeburnscoder&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://mikeburnscoder.wordpress.com/2010/09/27/datepreference-an-android-library/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/01b9172e9f53e0955a1af7458752aa9b?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mike-burns</media:title>
		</media:content>

		<media:content url="http://bostonandroid.github.com/DatePreference/resources/date-of-birth-preference.png" medium="image">
			<media:title type="html">Screenshot showing the date preference for selecting the date of birth</media:title>
		</media:content>
	</item>
		<item>
		<title>Mentors Wanted</title>
		<link>http://mikeburnscoder.wordpress.com/2010/09/18/mentors-wanted/</link>
		<comments>http://mikeburnscoder.wordpress.com/2010/09/18/mentors-wanted/#comments</comments>
		<pubDate>Sat, 18 Sep 2010 13:58:18 +0000</pubDate>
		<dc:creator>Mike Burns</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://mikeburnscoder.wordpress.com/?p=79</guid>
		<description><![CDATA[Lately I have ideas that are bigger than what I know; these ideas are outside the Web. And I need knowledge help.<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mikeburnscoder.wordpress.com&amp;blog=255131&amp;post=79&amp;subd=mikeburnscoder&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m something of an experienced Web developer. Ten years or so in Web programming in Perl, Scheme, Ruby, and dabbling in Haskell and Python. I&#8217;ve worked with MySQL, PostgreSQL, and MongoDB; CSS, XHTML, and XML; MVC, client-server, and state-based.</p>
<p>Lately I have ideas that are bigger than what I know; these ideas are outside the Web. And I need knowledge help.</p>
<p><strong>I have three projects that I would like a mentor for</strong>. These projects touch on niche technologies where I&#8217;d like to leave a mark and fully understand the implementations. If you are local (Bostonish) and available <a href="mailto:mike@mike-burns.com">we should talk</a>.</p>
<p>The projects need mentors for these concepts:</p>
<ul>
<li>Google Android testing. Experience with integration testing and unit testing all aspects of Android development, including various kinds of Activities, Services, Preferences, and so on. This you and you&#8217;re local? <a href="mailto:mike@bostonandroid.org">Let me know</a> or come find me at the next <a href="http://bostonandroid.org/">Boston Android</a> hackfest.</li>
<li>GNOME or GTK development. Experience with writing a GTK app, using Glade, in either C, Python, or Haskell. Normal GNOME apps are most interesting, but I am also interested in writing panel applets. This you and you&#8217;re local? <a href="mailto:mike@mike-burns.com">Let me know</a>.</li>
<li>BitTorrent client and server. My most ambitious project to date involves applying BitTorrent to concepts it was not made for, but I need help thinking through and working with the protocol itself, and programming the client and server as needed. This you and you&#8217;re local? <a href="mailto:mike@mike-burns.com">Let me know</a>.</li>
</ul>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mikeburnscoder.wordpress.com/79/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mikeburnscoder.wordpress.com/79/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/mikeburnscoder.wordpress.com/79/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/mikeburnscoder.wordpress.com/79/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/mikeburnscoder.wordpress.com/79/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/mikeburnscoder.wordpress.com/79/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/mikeburnscoder.wordpress.com/79/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/mikeburnscoder.wordpress.com/79/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/mikeburnscoder.wordpress.com/79/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/mikeburnscoder.wordpress.com/79/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/mikeburnscoder.wordpress.com/79/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/mikeburnscoder.wordpress.com/79/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/mikeburnscoder.wordpress.com/79/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/mikeburnscoder.wordpress.com/79/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mikeburnscoder.wordpress.com&amp;blog=255131&amp;post=79&amp;subd=mikeburnscoder&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://mikeburnscoder.wordpress.com/2010/09/18/mentors-wanted/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/01b9172e9f53e0955a1af7458752aa9b?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mike-burns</media:title>
		</media:content>
	</item>
		<item>
		<title>Boston Android</title>
		<link>http://mikeburnscoder.wordpress.com/2010/08/18/boston-android/</link>
		<comments>http://mikeburnscoder.wordpress.com/2010/08/18/boston-android/#comments</comments>
		<pubDate>Wed, 18 Aug 2010 15:28:14 +0000</pubDate>
		<dc:creator>Mike Burns</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://mikeburnscoder.wordpress.com/?p=76</guid>
		<description><![CDATA[I am co-running the local Boston Android programming group these days. Just so you know. Come hack code on Monday, August 23rd at the thoughtbot office.<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mikeburnscoder.wordpress.com&amp;blog=255131&amp;post=76&amp;subd=mikeburnscoder&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I am co-running the local <a href="http://bostonandroid.org/">Boston Android programming group</a> these days. Just so you know.</p>
<p>Come hack code on Monday, August 23rd at the thoughtbot office.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mikeburnscoder.wordpress.com/76/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mikeburnscoder.wordpress.com/76/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/mikeburnscoder.wordpress.com/76/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/mikeburnscoder.wordpress.com/76/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/mikeburnscoder.wordpress.com/76/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/mikeburnscoder.wordpress.com/76/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/mikeburnscoder.wordpress.com/76/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/mikeburnscoder.wordpress.com/76/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/mikeburnscoder.wordpress.com/76/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/mikeburnscoder.wordpress.com/76/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/mikeburnscoder.wordpress.com/76/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/mikeburnscoder.wordpress.com/76/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/mikeburnscoder.wordpress.com/76/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/mikeburnscoder.wordpress.com/76/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mikeburnscoder.wordpress.com&amp;blog=255131&amp;post=76&amp;subd=mikeburnscoder&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://mikeburnscoder.wordpress.com/2010/08/18/boston-android/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/01b9172e9f53e0955a1af7458752aa9b?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mike-burns</media:title>
		</media:content>
	</item>
		<item>
		<title>What I want out of a Web framework</title>
		<link>http://mikeburnscoder.wordpress.com/2010/05/22/what-i-want-out-of-a-web-framework/</link>
		<comments>http://mikeburnscoder.wordpress.com/2010/05/22/what-i-want-out-of-a-web-framework/#comments</comments>
		<pubDate>Sat, 22 May 2010 20:05:19 +0000</pubDate>
		<dc:creator>Mike Burns</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[haskell]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[whining]]></category>

		<guid isPermaLink="false">http://mikeburnscoder.wordpress.com/?p=70</guid>
		<description><![CDATA[Haskell has a serious Not Invented Here problem where it comes to Web frameworks. Everyone is unhappy with what we have, but no honest features differ between the six or so out there. Let&#8217;s start with what I don&#8217;t care about: Speed Computer Science If I cared about these things&#8212;or if any other Web developer [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mikeburnscoder.wordpress.com&amp;blog=255131&amp;post=70&amp;subd=mikeburnscoder&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Haskell has a serious Not Invented Here problem where it comes to Web frameworks. Everyone is unhappy with what we have, but no honest features differ between the six or so out there.</p>
<p>Let&#8217;s start with what I don&#8217;t care about:</p>
<ul>
<li>Speed</li>
<li>Computer Science</li>
</ul>
<p>If I cared about these things&mdash;or if any other Web developer cared about these things&mdash;I wouldn&#8217;t write in Ruby (or PHP, Perl, PLT Scheme, etc.).</p>
<p>These are nice but they&#8217;re not selling points.</p>
<p>Overall what I&mdash;and, Rails has taughts us, other Web developers&mdash;want out of a Web framework is a strong opinion. I want to be told where to put things. I want to be told that routes go here, HTML templates go there, tests go in this other place, and so on.</p>
<p>To not do that is to assume that Web apps are simple, that people maintain exactly one Web app, and that Web sites are completely unique. None of those assumptions are true.</p>
<p>Next up I want to bring knowledge over from the rest of my career. Some of my favorite design patterns apply here: observer and MVC. Just use MVC for your Web framework. It makes sense. I mean, it doesn&#8217;t, but it approximates it so well that it&#8217;s worth it.</p>
<p>The view should look like HTML. I&#8217;m not writing it, afterall; the designer is.  Or she and I are writing it together. Either way, it shouldn&#8217;t be validated. I don&#8217;t care if it&#8217;s valid; the designer doesn&#8217;t care; the Web browser doesn&#8217;t care (and sometimes needs it to be invalid); so just relax already. (Any Haskell in the view template needs to be valid. I understand this.)</p>
<p>And I don&#8217;t want to write SQL so use an abstraction layer like the active record pattern or <a href="http://github.com/nkallen/arel">Arel</a> or something dead easy. Simulate OO if you need to; it makes sense some times, and invoking behavior on data is that time.</p>
<p>I don&#8217;t want to &#8220;pretend I&#8217;m writing desktop apps&#8221; because this isn&#8217;t a familar metaphor. I want to write HTTP apps. I want to interact with GET, PUT, POST, and the others. The Web is a very familiar metaphor: data goes in, data comes out, and it&#8217;s over. It&#8217;s like a function call but with more moving parts. Not only does this make it easy to think about, it makes it easy to test.</p>
<p>I test my code. At work I test-drive my code, which also implies 100% code coverage but we don&#8217;t tend to care about code coverage. But that&#8217;s the kind of code I write: code that needs to be tested. I want to use an integration test suite to describe how the application should perform, and I want to use a unit-level test suite to ensure that refactoring goes well. My Web app will talk to other Web apps so I damn well better be able to fake that part out of my tests.</p>
<p>Pulling knowledge in from the rest of my career, I want to use Cucumber and something better than Selenium. In Rails we use Webrat and Holy Grail and EnvJS and ShamRack and a whole slew of other tools. There&#8217;s nothing stopping me from using Cucumber to describe my behavior except I can&#8217;t back it with a Haskell equivalent of Webrat.</p>
<p>Oh speaking of knowledge, I need documentation. The first-pass tutorial for a Web app isn&#8217;t &#8220;hello, world&#8221;, it&#8217;s a blog. If &#8220;hello, world&#8221; requires a full tutorial then your Web framework belongs in 1995. Make a screencast, those are fun. You should say, &#8220;Look at all these things I&#8217;m not doing!&#8221; in it, and mean it. But be aware that I&#8217;m not writing a blog. Well, I am, but it&#8217;s part of the app. Clients always demand a blog (and an admin interface, statistics, copy changes, A/B testing, &#8230;).</p>
<p>I see an idea crossing your mind right now and let me just say that splitting the individual components into discrete divisions that know nothing of each other simply isn&#8217;t fun to maintain. And even if it were fun to maintain, you don&#8217;t know how to make such a thing in the first version of your framework.</p>
<p>Speaking of things you don&#8217;t know how to do at first, I want hooks. Nearly every Web site out there is slightly different from another Web site, and I want to hook into the framework to handle those differences. The part of the framework that catches exceptions and shows a 500? I want to be able to replace that or augment it. The part that maps URL paths to module and function; the part that looks for the location of the HTML templates; the part that loads configuration files&#8212;all this, and more, are things I may want to augment.</p>
<p>If you provide a hooks, you should have a directory for storing plugins. That&#8217;s a nice, cheap way of having people contribute to your Web framework.</p>
<p>I mentioned errors, and this is one spot where Haskell, as a language, falls short. Here&#8217;s what you can get from a Ruby exception: backtrace, message, class name, and anything defined on Object, Class, Module, or Kernel. On the other hand, here&#8217;s what you can get from a Haskell exception: message. So you know that somewhere, somehow, maybe in your code, `head&#8217; got an empty list.</p>
<p>(I ran into this while writing a <a href="http://hoptoadapp.com/">Hoptoad</a> notification library for Haskell. It was a very &#8220;wait &#8230; what! &#8230; waaait. Oh, what!&#8221; reaction when I realized this.)</p>
<p>Rumor has it that ghc is working on backtraces.</p>
<p>As a tangent let me tell you about the first (and last) time I tried Merb. I had been a Rails developer for maybe three years by then and I had heard that Merb was a simpler Rails. &#8220;That sounds nice,&#8221; I thought to myself. &#8220;Rails is a big pile of hacks so presumably they&#8217;ve brought that pile down to a manageable level.&#8221; First thing I noticed was that ActiveSupport was missing. This meant I couldn&#8217;t #pluralize. As I wrote more I realized more and more was missing and that, really, Rails was extracted from a real, production-level, money-making Web app &#8230; and Merb simply wasn&#8217;t.</p>
<p>Anyway, when the Web app is ready I&#8217;m going to deploy it to staging and, when that&#8217;s ready, it&#8217;s off to production. Maybe there will be a pre-staging server, too, or a mirror of staging, or a mirror of production with forked traffic.  Either way deployment needs to happen and, when it breaks, it needs to be undone.</p>
<p>So it sounds like Rails has what I want. Why am I still here? Haskell gives me: type checking, a friendly and small community, and threading.  It&#8217;s a smart language for smart people, and I want to pretend to be a smart person.</p>
<p><strong>The next step</strong></p>
<p>Which Haskell Web framework is the one we should bring into this dream? There&#8217;s no need to make yet another; let&#8217;s just take an existing one and fully realize it. I can&#8217;t figure out which, though. Advice?</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mikeburnscoder.wordpress.com/70/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mikeburnscoder.wordpress.com/70/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/mikeburnscoder.wordpress.com/70/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/mikeburnscoder.wordpress.com/70/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/mikeburnscoder.wordpress.com/70/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/mikeburnscoder.wordpress.com/70/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/mikeburnscoder.wordpress.com/70/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/mikeburnscoder.wordpress.com/70/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/mikeburnscoder.wordpress.com/70/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/mikeburnscoder.wordpress.com/70/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/mikeburnscoder.wordpress.com/70/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/mikeburnscoder.wordpress.com/70/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/mikeburnscoder.wordpress.com/70/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/mikeburnscoder.wordpress.com/70/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mikeburnscoder.wordpress.com&amp;blog=255131&amp;post=70&amp;subd=mikeburnscoder&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://mikeburnscoder.wordpress.com/2010/05/22/what-i-want-out-of-a-web-framework/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/01b9172e9f53e0955a1af7458752aa9b?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mike-burns</media:title>
		</media:content>
	</item>
		<item>
		<title>An Infinite List of Fibonacci Numbers in Ruby</title>
		<link>http://mikeburnscoder.wordpress.com/2009/06/06/an-infinite-list-of-fibonacci-numbers-in-ruby/</link>
		<comments>http://mikeburnscoder.wordpress.com/2009/06/06/an-infinite-list-of-fibonacci-numbers-in-ruby/#comments</comments>
		<pubDate>Sat, 06 Jun 2009 21:11:47 +0000</pubDate>
		<dc:creator>Mike Burns</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[scanl]]></category>
		<category><![CDATA[fibonacci]]></category>
		<category><![CDATA[benchmarks]]></category>
		<category><![CDATA[space complexity]]></category>
		<category><![CDATA[time complexity]]></category>
		<category><![CDATA[memory profiling]]></category>
		<category><![CDATA[infinite lists]]></category>
		<category><![CDATA[lazy lists]]></category>

		<guid isPermaLink="false">http://mikeburnscoder.wordpress.com/?p=60</guid>
		<description><![CDATA[So I was reading through the Haskell Prelude when I stumbled across `scanl' as a kind of abstraction over `foldl'. I stared, and thought, and stared some more, and couldn&#8217;t come up with a use for it; a quick Web search revealed exactly one use: Fibonacci numbers. (In retrospect: duh.) So here are all the [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mikeburnscoder.wordpress.com&amp;blog=255131&amp;post=60&amp;subd=mikeburnscoder&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>So I was reading through the Haskell <a href="http://www.haskell.org/onlinereport/standard-prelude.html">Prelude</a> when I stumbled across <code>`<a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:scanl">scanl</a>'</code> as a kind of abstraction over <code>`<a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:foldl">foldl</a>'</code>. I stared, and thought, and stared some more, and couldn&#8217;t come up with a use for it; a quick Web search revealed exactly one use: Fibonacci numbers.</p>
<p>(In retrospect: duh.)</p>
<p>So here are all the Fibonacci numbers in Haskell:</p>
<pre>fibs = 0 : scanl (+) 1 fibs</pre>
<p>As you can see this makes use of infinite, recursive lists. So I wrote this in Ruby.</p>
<p>First I needed infinite lists:</p>
<p><pre class="brush: ruby;">
class LazyEmpty
  def empty?
    true
  end
end

class LazyCons
  attr_reader :first

  def initialize(first, &amp;rest)
    @first = first
    @rest = rest
    @rest_called = false
  end

  def rest
    if @rest_called
      @rest
    else
      @rest_called = true
      @rest = @rest.call
    end
  end

  def empty?
    false
  end
end
</pre></p>
<p>And now that I have such a thing, I need behavior on it. For example, <code>#take</code> will produce the first <var>n</var> elements of such a list:</p>
<p><pre class="brush: ruby;">
class LazyEmpty
  def take(n)
    LazyEmpty.new
  end
end
class LazyCons
  def take(n)
    if n &lt; 0
      self
    elsif n.zero?
      [self.first]
    else
      self.rest.take(n-1) + [self.first]
    end
  end
end
</pre></p>
<p>So now I can get at the elements:</p>
<p><pre class="brush: ruby;">
irb(main):001:0&gt; l = LazyCons.new(1) { LazyCons.new(2) { LazyCons.new(3) { LazyCons.new(4) { LazyEmpty.new }}}}
=&gt; #&lt;LazyCons:0x7f656ee21208 @rest_called=false, @rest=#&lt;Proc:0x00007f656ee212a8@(irb):2&gt;, @first=1&gt;
irb(main):002:0&gt; l.take(2)
=&gt; [3, 2, 1]
</pre></p>
<p>To get the most fun definition for the list of Fibonacci numbers I need <code>#scanl</code>:</p>
<p><pre class="brush: ruby;">
class LazyEmpty
  def scanl(q, &amp;f)
    LazyCons.new(q) { LazyEmpty.new }
  end
end

class LazyCons
  def scanl(q, &amp;f)
    LazyCons.new(q) { self.rest.scanl(f.call(q, self.first), &amp;f) }
  end
end
</pre></p>
<p>So now I have all the parts needed:</p>
<p><pre class="brush: ruby;">
def fibs
  LazyCons.new(0) { fibs.scanl(1) {|x,y| x + y} }
end
</pre></p>
<p>See?</p>
<p><pre class="brush: ruby;">
irb(main):008:0&gt; fibs.take(10)
=&gt; [55, 34, 21, 13, 8, 5, 3, 2, 1, 1, 0]
</pre></p>
<p>That is to say, the <var>n</var>th Fibonacci number is the first element from <code>take(<var>n</var>)</code>.</p>
<p><pre class="brush: ruby;">
def fib(n)
  fibs.take(n).first
end
</pre></p>
<p>At this point I wondered how it performed, especially against the na&iuml;ve implementation. So I used <a href="http://www.ruby-doc.org/core/classes/Benchmark.html">Benchmark.rb</a> and <a href="http://ruby-prof.rubyforge.org/">ruby-prof</a> to compare <code>#fib_naive</code>, <code>#fib_tail</code> (the tail-call rewrite of the na&iuml;ve implementation), <code>#fib_while</code> (the while loop rewrite of the tail-call rewrite), and <code>#fib_inf_list</code> (as defined above) &hellip; and the infinite list was not in last place!</p>
<pre>
       user       system      total        real
naive 12.020000   2.140000  14.160000 ( 14.174045)
tail   0.000000   0.000000   0.000000 (  0.010399)
while  0.020000   0.000000   0.020000 (  0.008730)
inf    3.360000   0.150000   3.510000 (  3.513216)

naive memory:
Thread ID: 70118283774380
Total: 970.630000

 %self     total     self     wait    child    calls  name
  5.11    970.63    49.61     0.00   921.02 17710000  Object#fib_naive-1 (fib_benchmarks.rb:6}
  1.01      9.79     9.79     0.00     0.00 17710000  Fixnum#- (ruby_runtime:0}
  0.94      9.16     9.16     0.00     0.00 17710500  Fixnum#&lt; (ruby_runtime:0}
  0.53      5.17     5.17     0.00     0.00  8855000  Fixnum#+ (ruby_runtime:0}
  0.00     73.73     0.00     0.00    73.73        1  Integer#times (ruby_runtime:0}
  0.00     73.73     0.00     0.00    73.73      500  Proc#call (ruby_runtime:0}
</pre>
<pre>
  0.00     73.73     0.00     0.00    73.73      500  Object#fib_naive (fib_benchmarks.rb:6}
  0.00     73.73     0.00     0.00    73.73        1  Object#profile (fib_benchmarks.rb:48}

tail memory:
Thread ID: 70118283774380
Total: 0.630000

 %self     total     self     wait    child    calls  name
  6.35      0.63     0.04     0.00     0.59    10500  Object#fib_tail_aux-1 (fib_benchmarks.rb:18}
  1.59      0.01     0.01     0.00     0.00    10500  Fixnum#+ (ruby_runtime:0}
  0.00      0.00     0.00     0.00     0.00    10500  Fixnum#- (ruby_runtime:0}
  0.00      0.05     0.00     0.00     0.05      500  Object#fib_tail_aux (fib_benchmarks.rb:18}
  0.00      0.05     0.00     0.00     0.05      500  Object#fib_tail (fib_benchmarks.rb:14}
  0.00      0.05     0.00     0.00     0.05        1  Integer#times (ruby_runtime:0}
  0.00      0.00     0.00     0.00     0.00    11000  Fixnum#zero? (ruby_runtime:0}
  0.00      0.05     0.00     0.00     0.05        1  Object#profile (fib_benchmarks.rb:48}
  0.00      0.05     0.00     0.00     0.05      500  Proc#call (ruby_runtime:0}

while memory:
Thread ID: 70118283774380
Total: 0.040000

 %self     total     self     wait    child    calls  name
 50.00      0.04     0.02     0.00     0.02      500  Object#fib_while (fib_benchmarks.rb:26}
 25.00      0.01     0.01     0.00     0.00    11000  Fixnum#&gt; (ruby_runtime:0}
 25.00      0.01     0.01     0.00     0.00    10500  Fixnum#+ (ruby_runtime:0}
  0.00      0.00     0.00     0.00     0.00    10500  Fixnum#- (ruby_runtime:0}
  0.00      0.04     0.00     0.00     0.04        1  Integer#times (ruby_runtime:0}
  0.00      0.04     0.00     0.00     0.04        1  Object#profile (fib_benchmarks.rb:48}
  0.00      0.04     0.00     0.00     0.04      500  Proc#call (ruby_runtime:0}

inf memory:
Thread ID: 70118283774380
Total: 63.810000

 %self     total     self     wait    child    calls  name
  3.96      2.53     2.53     0.00     0.00   126500  LazyCons#initialize (./fib_inf_list.rb:18}
  1.13     42.51     0.72     0.00    41.79   220500  Proc#call-1 (ruby_runtime:0}
  0.66      3.16     0.42     0.00     2.74   115500  LazyCons#scanl (./fib_inf_list.rb:37}
  0.53      2.94     0.34     0.00     2.60   126500  Class#new (ruby_runtime:0}
  0.38     37.95     0.24     0.00    37.71   105000  LazyCons#rest-1 (./fib_inf_list.rb:24}
  0.16      0.10     0.10     0.00     0.00   105000  Fixnum#+ (ruby_runtime:0}
  0.13     63.81     0.08     0.00    63.73    10500  LazyCons#take-1 (./fib_inf_list.rb:41}
  0.11      0.07     0.07     0.00     0.00   126500  #allocate (ruby_runtime:0}
  0.08      0.25     0.05     0.00     0.20    11000  Object#fibs (./fib_inf_list.rb:56}
  0.03      0.02     0.02     0.00     0.00    10500  Array#+ (ruby_runtime:0}
  0.03      4.60     0.02     0.00     4.58      500  Proc#call (ruby_runtime:0}
  0.02      4.48     0.01     0.00     4.47    10500  LazyCons#rest (./fib_inf_list.rb:24}
  0.00      4.60     0.00     0.00     4.60        1  Integer#times (ruby_runtime:0}
  0.00      4.58     0.00     0.00     4.58      500  LazyCons#take (./fib_inf_list.rb:41}
  0.00      4.60     0.00     0.00     4.60        1  Object#profile (fib_benchmarks.rb:48}
  0.00      4.58     0.00     0.00     4.58      500  Object#fib_inf_list (./fib_inf_list.rb:52}
  0.00      0.00     0.00     0.00     0.00    10500  Fixnum#- (ruby_runtime:0}
  0.00      0.00     0.00     0.00     0.00    11000  Fixnum#&lt; (ruby_runtime:0}
  0.00      0.00     0.00     0.00     0.00    11000  Fixnum#zero? (ruby_runtime:0}
  0.00      0.00     0.00     0.00     0.00      500  Array#first (ruby_runtime:0}
</pre>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mikeburnscoder.wordpress.com/60/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mikeburnscoder.wordpress.com/60/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/mikeburnscoder.wordpress.com/60/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/mikeburnscoder.wordpress.com/60/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/mikeburnscoder.wordpress.com/60/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/mikeburnscoder.wordpress.com/60/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/mikeburnscoder.wordpress.com/60/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/mikeburnscoder.wordpress.com/60/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/mikeburnscoder.wordpress.com/60/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/mikeburnscoder.wordpress.com/60/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/mikeburnscoder.wordpress.com/60/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/mikeburnscoder.wordpress.com/60/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/mikeburnscoder.wordpress.com/60/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/mikeburnscoder.wordpress.com/60/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mikeburnscoder.wordpress.com&amp;blog=255131&amp;post=60&amp;subd=mikeburnscoder&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://mikeburnscoder.wordpress.com/2009/06/06/an-infinite-list-of-fibonacci-numbers-in-ruby/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/01b9172e9f53e0955a1af7458752aa9b?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mike-burns</media:title>
		</media:content>
	</item>
		<item>
		<title>Powerset in Ruby Using the List Monad</title>
		<link>http://mikeburnscoder.wordpress.com/2009/05/30/powerset-in-ruby-using-the-list-monad/</link>
		<comments>http://mikeburnscoder.wordpress.com/2009/05/30/powerset-in-ruby-using-the-list-monad/#comments</comments>
		<pubDate>Sat, 30 May 2009 18:25:34 +0000</pubDate>
		<dc:creator>Mike Burns</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[haskell]]></category>
		<category><![CDATA[monads]]></category>
		<category><![CDATA[monkeypatch]]></category>
		<category><![CDATA[powerset]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://mikeburnscoder.wordpress.com/?p=54</guid>
		<description><![CDATA[While trying to think of good, quick interview questions I stumbled across power set (thanks to Mike DiStaula for suggesting it). After 10 minutes of hacking in Ruby I discovered that it&#8217;s not a reasonable replacement for our current starter question (it takes too long), but it&#8217;s also a fun problem to solve. Then I [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mikeburnscoder.wordpress.com&amp;blog=255131&amp;post=54&amp;subd=mikeburnscoder&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>While trying to think of good, quick interview questions I stumbled across <a href="http://en.wikipedia.org/wiki/Powerset">power set</a> (thanks to <a href="http://mikedistaula.com/">Mike DiStaula</a> for suggesting it). After 10 minutes of hacking in Ruby I discovered that it&#8217;s not a reasonable replacement for our current starter question (it takes too long), but it&#8217;s also a fun problem to solve.</p>
<p>Then I wandered across this definition of power set in Haskell:</p>
<pre>
powerset = filterM (const [True, False])
</pre>
<p>Well, that was easy. So I set out to write that in Ruby. That is, I wanted to write this:</p>
<p><pre class="brush: ruby;">
class Array
  def powerset
    self.filterM {|x| [true, false]}
  end
end
</pre></p>
<p>First thing I need is a list monad:</p>
<p><pre class="brush: ruby;">
class Array
  def self.unit(x)
    [x]
  end

  def bind(&amp;f)
    self.inject([]) do |acc, e|
      acc + f.call(e)
    end
  end
end
</pre></p>
<p>I quickly hit my weekly reminder that Ruby does not have <code>Array#rest</code>, so I added that:</p>
<p><pre class="brush: ruby;">
class Array
  def rest
    r = self[1..-1]
    r.nil? ? [] : r
  end
end
</pre></p>
<p>Whew; now things are easier. Next I needed <code>filterM</code>, so I added it to <code>Enumerable</code> as a faithful copy <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/src/Control-Monad.html#filterM">from Haskell</a> (expanding the <code>do</code> notation into the <code>&gt;&gt;=</code> notation):</p>
<p><pre class="brush: ruby;">
module Enumerable
  def filterM(&amp;p)
    return self.class.unit([]) if self.empty?
    p.call(self.first).bind do |flg|
      self.rest.filterM(&amp;p).bind do |ys|
        self.class.unit(flg ? ([self.first] + ys) : ys)
      end
    end
  end
end
</pre></p>
<p>Now my original <code>Array#powerset</code> method works:</p>
<p><pre class="brush: ruby;">
irb(main):013:0&gt; [1,2,3].powerset
=&gt; [[1, 2, 3], [1, 2], [1, 3], [1], [2, 3], [2], [3], []]
</pre></p>
<p>I expect you to write that quickly in your next interview.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mikeburnscoder.wordpress.com/54/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mikeburnscoder.wordpress.com/54/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/mikeburnscoder.wordpress.com/54/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/mikeburnscoder.wordpress.com/54/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/mikeburnscoder.wordpress.com/54/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/mikeburnscoder.wordpress.com/54/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/mikeburnscoder.wordpress.com/54/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/mikeburnscoder.wordpress.com/54/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/mikeburnscoder.wordpress.com/54/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/mikeburnscoder.wordpress.com/54/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/mikeburnscoder.wordpress.com/54/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/mikeburnscoder.wordpress.com/54/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/mikeburnscoder.wordpress.com/54/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/mikeburnscoder.wordpress.com/54/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mikeburnscoder.wordpress.com&amp;blog=255131&amp;post=54&amp;subd=mikeburnscoder&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://mikeburnscoder.wordpress.com/2009/05/30/powerset-in-ruby-using-the-list-monad/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/01b9172e9f53e0955a1af7458752aa9b?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mike-burns</media:title>
		</media:content>
	</item>
	</channel>
</rss>
