<?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>Robert Horvick &#187; Erlang</title>
	<atom:link href="http://www.roberthorvick.com/tag/erlang/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.roberthorvick.com</link>
	<description>Things my wife doesn&#039;t want on the family blog...</description>
	<lastBuildDate>Sat, 08 May 2010 23:27:04 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Syntax Highlighing for Erlang in NotePad++</title>
		<link>http://www.roberthorvick.com/2009/07/08/syntax-highlighing-for-erlang-in-notepad/</link>
		<comments>http://www.roberthorvick.com/2009/07/08/syntax-highlighing-for-erlang-in-notepad/#comments</comments>
		<pubDate>Wed, 08 Jul 2009 18:02:42 +0000</pubDate>
		<dc:creator>robert</dc:creator>
				<category><![CDATA[Erlang]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://www.roberthorvick.com/?p=64</guid>
		<description><![CDATA[Update: The definition has been updated to include support for atoms, variables and function names as well as additional file extensions.  Screen shot and downloadable content have been updated.
Thus far I&#8217;ve done all of my Erlang development on Fedora using vim or KWrite (which does a decent job in Ruby mode).
But today I found myself [...]]]></description>
			<content:encoded><![CDATA[<p><em>Update: The definition has been updated to include support for atoms, variables and function names as well as additional file extensions.  Screen shot and downloadable content have been updated.</em></p>
<p>Thus far I&#8217;ve done all of my Erlang development on Fedora using vim or KWrite (which does a decent job in Ruby mode).</p>
<p>But today I found myself on a windows box and wanted a basic syntax highlighting editor for Erlang that was free and worked on Windows.  Oh &#8211; and not Eclipse+Erlide.  I wanted something small and fast.</p>
<p>I grabbed the &#8220;<a href="http://en.wikipedia.org/wiki/Free_as_in_beer">free as in beer</a>&#8221; and &#8220;<a href="http://en.wikipedia.org/wiki/Free_as_in_beer#.22Free_as_in_beer.22_vs_.22Free_as_in_speech.22">free as in speech</a>&#8221; editor <a href="http://notepad-plus.sourceforge.net">NotePad++</a> and created a simple syntax file that is a bit hokey but will serve my needs fine.</p>
<p>Here&#8217;s a screen shot &#8230;<br />
<img class="aligncenter size-medium wp-image-65" title="Windows Erlang Syntax Highlighting Editor" src="http://www.roberthorvick.com/wp-content/uploads/2009/07/screenshot1.jpg" alt="Windows Erlang Syntax Highlighting Editor" width="550" height="449" /></p>
<p>NotePad++ has pretty weak syntax highlighting but was sufficent to do most of what I wanted.  Some regex based rules would make this a more robust.</p>
<p>Highlighted entities include</p>
<ul>
<li>Erlang reserved words (and named operators)</li>
<li>Variables</li>
<li>Atoms</li>
<li>function names (same coloring as atoms)</li>
<li>Operators</li>
<li>Comments</li>
<li>Kernal, stdlib, mnesia and odbc modules.</li>
<li>Support for *.erl, *.hrl and *.htp extentions</li>
</ul>
<p>I&#8217;ve probably missed several things.</p>
<p>Looks a lot better than nothing and it took all of <span style="text-decoration: line-through;">10</span> 15 minutes.</p>
<p>If you are using NotePad++ here is the file:</p>
<p><a href="http://www.roberthorvick.com/wp-content/uploads/2009/07/erlangSyntaxDefinition.zip">http://www.roberthorvick.com/wp-content/uploads/2009/07/erlangSyntaxDefinition.zip</a></p>
<p>And here are the instructions on how to install it:</p>
<p><a href="http://sourceforge.net/apps/mediawiki/notepad-plus/index.php?title=Syntax_Highlighting_Sharing">http://sourceforge.net/apps/mediawiki/notepad-plus/index.php?title=Syntax_Highlighting_Sharing</a></p>
<p>And here&#8217;s the instructions on modifying or creating your own:</p>
<p><a href="http://sourceforge.net/apps/mediawiki/notepad-plus/index.php?title=User_Defined_Languages">http://sourceforge.net/apps/mediawiki/notepad-plus/index.php?title=User_Defined_Languages</a></p>



Share and Enjoy:


	<a rel="nofollow" id="print" href="javascript:window.location='http%3A%2F%2Fwww.printfriendly.com%2Fprint%3Furl%3Dhttp%253A%252F%252Fwww.roberthorvick.com%252F2009%252F07%252F08%252Fsyntax-highlighing-for-erlang-in-notepad%252F%26amp%3Bpartner%3Dsociable';" title="Print this article!"><img src="http://www.roberthorvick.com/wp-content/plugins/sociable/images/printfriendly.png" title="Print this article!" alt="Print this article!" class="sociable-hovers" /></a>
	<a rel="nofollow" id="twitter" href="javascript:window.location='http%3A%2F%2Ftwitter.com%2Fhome%3Fstatus%3DSyntax%2520Highlighing%2520for%2520Erlang%2520in%2520NotePad%252B%252B%2520-%2520http%253A%252F%252Fwww.roberthorvick.com%252F2009%252F07%252F08%252Fsyntax-highlighing-for-erlang-in-notepad%252F';" title="Twitter"><img src="http://www.roberthorvick.com/wp-content/plugins/sociable/images/twitter.png" title="Twitter" alt="Twitter" class="sociable-hovers" /></a>
	<a rel="nofollow" id="digg" href="javascript:window.location='http%3A%2F%2Fdigg.com%2Fsubmit%3Fphase%3D2%26amp%3Burl%3Dhttp%253A%252F%252Fwww.roberthorvick.com%252F2009%252F07%252F08%252Fsyntax-highlighing-for-erlang-in-notepad%252F%26amp%3Btitle%3DSyntax%2520Highlighing%2520for%2520Erlang%2520in%2520NotePad%252B%252B%26amp%3Bbodytext%3DUpdate%253A%2520The%2520definition%2520has%2520been%2520updated%2520to%2520include%2520support%2520for%2520atoms%252C%2520variables%2520and%2520function%2520names%2520as%2520well%2520as%2520additional%2520file%2520extensions.%2520%25C2%25A0Screen%2520shot%2520and%2520downloadable%2520content%2520have%2520been%2520updated.%250D%250A%250D%250AThus%2520far%2520I%2527ve%2520done%2520all%2520of%2520my%2520Erlang%2520development%2520on%2520';" title="Digg"><img src="http://www.roberthorvick.com/wp-content/plugins/sociable/images/digg.png" title="Digg" alt="Digg" class="sociable-hovers" /></a>
	<a rel="nofollow" id="reddit" href="javascript:window.location='http%3A%2F%2Freddit.com%2Fsubmit%3Furl%3Dhttp%253A%252F%252Fwww.roberthorvick.com%252F2009%252F07%252F08%252Fsyntax-highlighing-for-erlang-in-notepad%252F%26amp%3Btitle%3DSyntax%2520Highlighing%2520for%2520Erlang%2520in%2520NotePad%252B%252B';" title="Reddit"><img src="http://www.roberthorvick.com/wp-content/plugins/sociable/images/reddit.png" title="Reddit" alt="Reddit" class="sociable-hovers" /></a>
	<a rel="nofollow" id="del.icio.us" href="javascript:window.location='http%3A%2F%2Fdelicious.com%2Fpost%3Furl%3Dhttp%253A%252F%252Fwww.roberthorvick.com%252F2009%252F07%252F08%252Fsyntax-highlighing-for-erlang-in-notepad%252F%26amp%3Btitle%3DSyntax%2520Highlighing%2520for%2520Erlang%2520in%2520NotePad%252B%252B%26amp%3Bnotes%3DUpdate%253A%2520The%2520definition%2520has%2520been%2520updated%2520to%2520include%2520support%2520for%2520atoms%252C%2520variables%2520and%2520function%2520names%2520as%2520well%2520as%2520additional%2520file%2520extensions.%2520%25C2%25A0Screen%2520shot%2520and%2520downloadable%2520content%2520have%2520been%2520updated.%250D%250A%250D%250AThus%2520far%2520I%2527ve%2520done%2520all%2520of%2520my%2520Erlang%2520development%2520on%2520';" title="del.icio.us"><img src="http://www.roberthorvick.com/wp-content/plugins/sociable/images/delicious.png" title="del.icio.us" alt="del.icio.us" class="sociable-hovers" /></a>
	<a rel="nofollow" id="facebook" href="javascript:window.location='http%3A%2F%2Fwww.facebook.com%2Fshare.php%3Fu%3Dhttp%253A%252F%252Fwww.roberthorvick.com%252F2009%252F07%252F08%252Fsyntax-highlighing-for-erlang-in-notepad%252F%26amp%3Bt%3DSyntax%2520Highlighing%2520for%2520Erlang%2520in%2520NotePad%252B%252B';" title="Facebook"><img src="http://www.roberthorvick.com/wp-content/plugins/sociable/images/facebook.png" title="Facebook" alt="Facebook" class="sociable-hovers" /></a>
	<a rel="nofollow" id="google" href="javascript:window.location='http%3A%2F%2Fwww.google.com%2Fbookmarks%2Fmark%3Fop%3Dedit%26amp%3Bbkmk%3Dhttp%253A%252F%252Fwww.roberthorvick.com%252F2009%252F07%252F08%252Fsyntax-highlighing-for-erlang-in-notepad%252F%26amp%3Btitle%3DSyntax%2520Highlighing%2520for%2520Erlang%2520in%2520NotePad%252B%252B%26amp%3Bannotation%3DUpdate%253A%2520The%2520definition%2520has%2520been%2520updated%2520to%2520include%2520support%2520for%2520atoms%252C%2520variables%2520and%2520function%2520names%2520as%2520well%2520as%2520additional%2520file%2520extensions.%2520%25C2%25A0Screen%2520shot%2520and%2520downloadable%2520content%2520have%2520been%2520updated.%250D%250A%250D%250AThus%2520far%2520I%2527ve%2520done%2520all%2520of%2520my%2520Erlang%2520development%2520on%2520';" title="Google Bookmarks"><img src="http://www.roberthorvick.com/wp-content/plugins/sociable/images/googlebookmark.png" title="Google Bookmarks" alt="Google Bookmarks" class="sociable-hovers" /></a>
	<a rel="nofollow" id="stumbleupon" href="javascript:window.location='http%3A%2F%2Fwww.stumbleupon.com%2Fsubmit%3Furl%3Dhttp%253A%252F%252Fwww.roberthorvick.com%252F2009%252F07%252F08%252Fsyntax-highlighing-for-erlang-in-notepad%252F%26amp%3Btitle%3DSyntax%2520Highlighing%2520for%2520Erlang%2520in%2520NotePad%252B%252B';" title="StumbleUpon"><img src="http://www.roberthorvick.com/wp-content/plugins/sociable/images/stumbleupon.png" title="StumbleUpon" alt="StumbleUpon" class="sociable-hovers" /></a>


<br/><br/>]]></content:encoded>
			<wfw:commentRss>http://www.roberthorvick.com/2009/07/08/syntax-highlighing-for-erlang-in-notepad/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Startup and Cleanup functions in Erlang EUnit tests</title>
		<link>http://www.roberthorvick.com/2009/07/06/startup-and-cleanup-functions-in-erlang-eunit-tests/</link>
		<comments>http://www.roberthorvick.com/2009/07/06/startup-and-cleanup-functions-in-erlang-eunit-tests/#comments</comments>
		<pubDate>Mon, 06 Jul 2009 04:22:16 +0000</pubDate>
		<dc:creator>robert</dc:creator>
				<category><![CDATA[Erlang]]></category>
		<category><![CDATA[eunit]]></category>

		<guid isPermaLink="false">http://www.roberthorvick.com/?p=62</guid>
		<description><![CDATA[I&#8217;ve got the basic grasp on Erlang but before I can do anything meaningful I need to learn how to test my code  EUnit is the de-facto test framework.  There are a ton of great sites that talk about testing with EUnit &#8211; I have linked to several at the end of this post.  I&#8217;m [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve got the basic grasp on Erlang but before I can do anything meaningful I need to learn how to test my code  EUnit is the de-facto test framework.  There are a ton of great sites that talk about testing with EUnit &#8211; I have linked to several at the end of this post.  I&#8217;m going to focus on the problem I ran into &#8211; needing to run some startup and cleanup code around the test suite.</p>
<p>I started by writing a very simple dictionary that lived in it&#8217;s own process.  The interface is:</p>

<div class="wp_syntax"><div class="code"><pre class="erlang" style="font-family:monospace;"><span style="color: #ff3c00;">start</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span> <span style="color: #006600;">ok</span>
<span style="color: #ff3c00;">stop</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span> <span style="color: #006600;">ok</span>
<span style="color: #ff3c00;">write</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Key</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Element</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span> <span style="color: #006600;">ok</span>
<span style="color: #ff3c00;">delete</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Key</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span> <span style="color: #006600;">ok</span>
<span style="color: #ff3c00;">read</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Key</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span> <span style="color: #109ab8;">&#123;</span>ok<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Value</span><span style="color: #109ab8;">&#125;</span> | not_found</pre></div></div>

<p>Calling start() spawns and registers the process the dictionary lives in.  Calling stop ends the process.  The rest do what you expect.</p>
<p>I started by writing some basic tests for each function but I didn&#8217;t really think it through.  The start test ran somewhere in the middle so all the tests prior to start either failed or timed out (because I was waiting on a receive that would never come since the process wasn&#8217;t started).  Very quickly I smacked my forehead and said &#8220;I need the test suite to have a pre and post function to start and stop the process&#8221;.</p>
<p>It took about 15 minutes of reading to realize that I needed to create a test generator with a setup tuple that defined the startup, cleanup and list of tests to run.</p>
<p>Conceptually it was easy to understand but getting the syntax right was a royal pain.  Basically you do this (I&#8217;m not sure if giving the function arity is the preferred method but it saved some keystrokes so I went with it):</p>

<div class="wp_syntax"><div class="code"><pre class="erlang" style="font-family:monospace;"><span style="color: #ff3c00;">my_db_test_</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
  <span style="color: #109ab8;">&#123;</span>spawn<span style="color: #6bb810;">,</span>
    <span style="color: #109ab8;">&#123;</span>setup<span style="color: #6bb810;">,</span>
      <span style="color: #186895;">fun</span> start<span style="color: #014ea4;">/</span><span style="color: #ff9600;">0</span><span style="color: #6bb810;">,</span>
      <span style="color: #186895;">fun</span> stop<span style="color: #014ea4;">/</span><span style="color: #ff9600;">1</span><span style="color: #6bb810;">,</span>
      <span style="color: #109ab8;">&#91;</span>
        <span style="color: #186895;">fun</span> write_new<span style="color: #014ea4;">/</span><span style="color: #ff9600;">0</span><span style="color: #6bb810;">,</span>
        <span style="color: #186895;">fun</span> write_existing<span style="color: #014ea4;">/</span><span style="color: #ff9600;">0</span><span style="color: #6bb810;">,</span>
        <span style="color: #186895;">fun</span> read_existing<span style="color: #014ea4;">/</span><span style="color: #ff9600;">0</span><span style="color: #6bb810;">,</span>
        <span style="color: #186895;">fun</span> read_missing<span style="color: #014ea4;">/</span><span style="color: #ff9600;">0</span><span style="color: #6bb810;">,</span>
        <span style="color: #186895;">fun</span> delete_existing<span style="color: #014ea4;">/</span><span style="color: #ff9600;">0</span><span style="color: #6bb810;">,</span>
        <span style="color: #186895;">fun</span> delete_missing<span style="color: #014ea4;">/</span><span style="color: #ff9600;">0</span>
      <span style="color: #109ab8;">&#93;</span>
    <span style="color: #109ab8;">&#125;</span>
  <span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">.</span></pre></div></div>

<p>The test methods are exactly what you&#8217;d expect so I won&#8217;t repeat them.  The syntax feels a little foreign and uncomfortable but it&#8217;s very easy to understand and I totally get why it&#8217;s written this way.  I&#8217;m just so used to <a href="http://en.wikipedia.org/wiki/MSTest">MSTest</a> attributes and <a href="http://rspec.info/">RSpec</a> that this new way is going to take a night or two to feel like an old friend.</p>
<h2>Some Eunit resources</h2>
<p><a href="http://pragdave.pragprog.com/pragdave/2007/04/testfirst_word_.html">Prag Dave &#8211; Test-First Word Wrap in Erlang</a></p>
<p><a href="http://svn.process-one.net/contribs/trunk/eunit/doc/overview-summary.html">EUnit &#8211; a Lightweight Unit Testing Framework for Erlang</a></p>
<p><a href="http://erlang.org/doc/apps/eunit/index.html">EUnit Reference Manual</a></p>
<p><a href="http://salientblue.com/codenotes/?name=erl_start">Getting Started: No Consoles!</a></p>



Share and Enjoy:


	<a rel="nofollow" id="print" href="javascript:window.location='http%3A%2F%2Fwww.printfriendly.com%2Fprint%3Furl%3Dhttp%253A%252F%252Fwww.roberthorvick.com%252F2009%252F07%252F06%252Fstartup-and-cleanup-functions-in-erlang-eunit-tests%252F%26amp%3Bpartner%3Dsociable';" title="Print this article!"><img src="http://www.roberthorvick.com/wp-content/plugins/sociable/images/printfriendly.png" title="Print this article!" alt="Print this article!" class="sociable-hovers" /></a>
	<a rel="nofollow" id="twitter" href="javascript:window.location='http%3A%2F%2Ftwitter.com%2Fhome%3Fstatus%3DStartup%2520and%2520Cleanup%2520functions%2520in%2520Erlang%2520EUnit%2520tests%2520-%2520http%253A%252F%252Fwww.roberthorvick.com%252F2009%252F07%252F06%252Fstartup-and-cleanup-functions-in-erlang-eunit-tests%252F';" title="Twitter"><img src="http://www.roberthorvick.com/wp-content/plugins/sociable/images/twitter.png" title="Twitter" alt="Twitter" class="sociable-hovers" /></a>
	<a rel="nofollow" id="digg" href="javascript:window.location='http%3A%2F%2Fdigg.com%2Fsubmit%3Fphase%3D2%26amp%3Burl%3Dhttp%253A%252F%252Fwww.roberthorvick.com%252F2009%252F07%252F06%252Fstartup-and-cleanup-functions-in-erlang-eunit-tests%252F%26amp%3Btitle%3DStartup%2520and%2520Cleanup%2520functions%2520in%2520Erlang%2520EUnit%2520tests%26amp%3Bbodytext%3DI%2527ve%2520got%2520the%2520basic%2520grasp%2520on%2520Erlang%2520but%2520before%2520I%2520can%2520do%2520anything%2520meaningful%2520I%2520need%2520to%2520learn%2520how%2520to%2520test%2520my%2520code%25C2%25A0%2520EUnit%2520is%2520the%2520de-facto%2520test%2520framework.%25C2%25A0%2520There%2520are%2520a%2520ton%2520of%2520great%2520sites%2520that%2520talk%2520about%2520testing%2520with%2520EUnit%2520-%2520I%2520have%2520linked%2520to%2520several%2520at%2520t';" title="Digg"><img src="http://www.roberthorvick.com/wp-content/plugins/sociable/images/digg.png" title="Digg" alt="Digg" class="sociable-hovers" /></a>
	<a rel="nofollow" id="reddit" href="javascript:window.location='http%3A%2F%2Freddit.com%2Fsubmit%3Furl%3Dhttp%253A%252F%252Fwww.roberthorvick.com%252F2009%252F07%252F06%252Fstartup-and-cleanup-functions-in-erlang-eunit-tests%252F%26amp%3Btitle%3DStartup%2520and%2520Cleanup%2520functions%2520in%2520Erlang%2520EUnit%2520tests';" title="Reddit"><img src="http://www.roberthorvick.com/wp-content/plugins/sociable/images/reddit.png" title="Reddit" alt="Reddit" class="sociable-hovers" /></a>
	<a rel="nofollow" id="del.icio.us" href="javascript:window.location='http%3A%2F%2Fdelicious.com%2Fpost%3Furl%3Dhttp%253A%252F%252Fwww.roberthorvick.com%252F2009%252F07%252F06%252Fstartup-and-cleanup-functions-in-erlang-eunit-tests%252F%26amp%3Btitle%3DStartup%2520and%2520Cleanup%2520functions%2520in%2520Erlang%2520EUnit%2520tests%26amp%3Bnotes%3DI%2527ve%2520got%2520the%2520basic%2520grasp%2520on%2520Erlang%2520but%2520before%2520I%2520can%2520do%2520anything%2520meaningful%2520I%2520need%2520to%2520learn%2520how%2520to%2520test%2520my%2520code%25C2%25A0%2520EUnit%2520is%2520the%2520de-facto%2520test%2520framework.%25C2%25A0%2520There%2520are%2520a%2520ton%2520of%2520great%2520sites%2520that%2520talk%2520about%2520testing%2520with%2520EUnit%2520-%2520I%2520have%2520linked%2520to%2520several%2520at%2520t';" title="del.icio.us"><img src="http://www.roberthorvick.com/wp-content/plugins/sociable/images/delicious.png" title="del.icio.us" alt="del.icio.us" class="sociable-hovers" /></a>
	<a rel="nofollow" id="facebook" href="javascript:window.location='http%3A%2F%2Fwww.facebook.com%2Fshare.php%3Fu%3Dhttp%253A%252F%252Fwww.roberthorvick.com%252F2009%252F07%252F06%252Fstartup-and-cleanup-functions-in-erlang-eunit-tests%252F%26amp%3Bt%3DStartup%2520and%2520Cleanup%2520functions%2520in%2520Erlang%2520EUnit%2520tests';" title="Facebook"><img src="http://www.roberthorvick.com/wp-content/plugins/sociable/images/facebook.png" title="Facebook" alt="Facebook" class="sociable-hovers" /></a>
	<a rel="nofollow" id="google" href="javascript:window.location='http%3A%2F%2Fwww.google.com%2Fbookmarks%2Fmark%3Fop%3Dedit%26amp%3Bbkmk%3Dhttp%253A%252F%252Fwww.roberthorvick.com%252F2009%252F07%252F06%252Fstartup-and-cleanup-functions-in-erlang-eunit-tests%252F%26amp%3Btitle%3DStartup%2520and%2520Cleanup%2520functions%2520in%2520Erlang%2520EUnit%2520tests%26amp%3Bannotation%3DI%2527ve%2520got%2520the%2520basic%2520grasp%2520on%2520Erlang%2520but%2520before%2520I%2520can%2520do%2520anything%2520meaningful%2520I%2520need%2520to%2520learn%2520how%2520to%2520test%2520my%2520code%25C2%25A0%2520EUnit%2520is%2520the%2520de-facto%2520test%2520framework.%25C2%25A0%2520There%2520are%2520a%2520ton%2520of%2520great%2520sites%2520that%2520talk%2520about%2520testing%2520with%2520EUnit%2520-%2520I%2520have%2520linked%2520to%2520several%2520at%2520t';" title="Google Bookmarks"><img src="http://www.roberthorvick.com/wp-content/plugins/sociable/images/googlebookmark.png" title="Google Bookmarks" alt="Google Bookmarks" class="sociable-hovers" /></a>
	<a rel="nofollow" id="stumbleupon" href="javascript:window.location='http%3A%2F%2Fwww.stumbleupon.com%2Fsubmit%3Furl%3Dhttp%253A%252F%252Fwww.roberthorvick.com%252F2009%252F07%252F06%252Fstartup-and-cleanup-functions-in-erlang-eunit-tests%252F%26amp%3Btitle%3DStartup%2520and%2520Cleanup%2520functions%2520in%2520Erlang%2520EUnit%2520tests';" title="StumbleUpon"><img src="http://www.roberthorvick.com/wp-content/plugins/sociable/images/stumbleupon.png" title="StumbleUpon" alt="StumbleUpon" class="sociable-hovers" /></a>


<br/><br/>]]></content:encoded>
			<wfw:commentRss>http://www.roberthorvick.com/2009/07/06/startup-and-cleanup-functions-in-erlang-eunit-tests/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The last word frequency post &#8211; from dict to ets</title>
		<link>http://www.roberthorvick.com/2009/07/03/the-last-word-frequency-post-from-dict-to-ets/</link>
		<comments>http://www.roberthorvick.com/2009/07/03/the-last-word-frequency-post-from-dict-to-ets/#comments</comments>
		<pubDate>Sat, 04 Jul 2009 03:15:56 +0000</pubDate>
		<dc:creator>robert</dc:creator>
				<category><![CDATA[Erlang]]></category>
		<category><![CDATA[ets]]></category>

		<guid isPermaLink="false">http://www.roberthorvick.com/?p=57</guid>
		<description><![CDATA[One last iteration through my learning exercise of building a word frequency list.  In this last post I&#8217;m moving away from a dict and to an ets table.  I was pleasantly surprised how easy the conversion was.  For example printing the output was just converting from dict:fold to ets:foldl.  The one [...]]]></description>
			<content:encoded><![CDATA[<p>One last iteration through my learning exercise of building a word frequency list.  In this last post I&#8217;m moving away from a dict and to an ets table.  I was pleasantly surprised how easy the conversion was.  For example printing the output was just converting from dict:fold to ets:foldl.  The one parity fail was that dict:update can take an initial value when the key is missing but ets:update_counter (nor any other ets function) has this benefit.  This required that I write a little wrapper function to call from the list:foldl (instead of having a multi-line inlined fun).</p>
<p>No point in getting too deep into this &#8211; here&#8217;s the code:</p>

<div class="wp_syntax"><div class="code"><pre class="erlang" style="font-family:monospace;"><span style="color: #014ea4;">-</span><span style="color: #5400b3;">module</span><span style="color: #109ab8;">&#40;</span>wordets<span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #014ea4;">-</span><span style="color: #5400b3;">export</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#91;</span>print_word_counts<span style="color: #014ea4;">/</span><span style="color: #ff9600;">1</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #ff3c00;">words</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">String</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
  <span style="color: #109ab8;">&#123;</span>match<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Captures</span><span style="color: #109ab8;">&#125;</span> <span style="color: #014ea4;">=</span> <span style="color: #ff4e18;">re</span>:<span style="color: #ff3c00;">run</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">String</span><span style="color: #6bb810;">,</span> <span style="color: #ff7800;">&quot;<span style="color: #000099; font-weight: bold;">\\</span>b<span style="color: #000099; font-weight: bold;">\\</span>w+<span style="color: #000099; font-weight: bold;">\\</span>b&quot;</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span>global<span style="color: #6bb810;">,</span><span style="color: #109ab8;">&#123;</span>capture<span style="color: #6bb810;">,</span>first<span style="color: #6bb810;">,</span><span style="color: #fa6fff;">list</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
  <span style="color: #ff4e18;">lists</span>:<span style="color: #ff3c00;">append</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Captures</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #666666; font-style: italic;">%% reads the next line from the file.  If there is data then...</span>
<span style="color: #666666; font-style: italic;">%% split the data into a list of words and add to the word table</span>
<span style="color: #ff3c00;">process_each_line</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">IoDevice</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Table</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
  <span style="color: #186895;">case</span> <span style="color: #ff4e18;">io</span>:<span style="color: #ff3c00;">get_line</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">IoDevice</span><span style="color: #6bb810;">,</span> <span style="color: #ff7800;">&quot;&quot;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #186895;">of</span>
    eof <span style="color: #6bb810;">-&gt;</span> 
      <span style="color: #ff4e18;">file</span>:<span style="color: #ff3c00;">close</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">IoDevice</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
      <span style="color: #45b3e6;">Table</span><span style="color: #6bb810;">;</span>
    <span style="color: #109ab8;">&#123;</span>error<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Reason</span><span style="color: #109ab8;">&#125;</span> <span style="color: #6bb810;">-&gt;</span>
      <span style="color: #ff4e18;">file</span>:<span style="color: #ff3c00;">close</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">IoDevice</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
      <span style="color: #ff3c00;">throw</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Reason</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">;</span>
    <span style="color: #45b3e6;">Data</span> <span style="color: #6bb810;">-&gt;</span>
      <span style="color: #45b3e6;">NewTable</span> <span style="color: #014ea4;">=</span> <span style="color: #ff4e18;">lists</span>:<span style="color: #ff3c00;">foldl</span><span style="color: #109ab8;">&#40;</span>
        <span style="color: #ff3c00;">fun</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">W</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">T</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span> <span style="color: #ff3c00;">update_word_count</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">W</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">T</span><span style="color: #109ab8;">&#41;</span> <span style="color: #186895;">end</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Table</span><span style="color: #6bb810;">,</span> <span style="color: #ff3c00;">words</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Data</span><span style="color: #109ab8;">&#41;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
      <span style="color: #ff3c00;">process_each_line</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">IoDevice</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">NewTable</span><span style="color: #109ab8;">&#41;</span>
  <span style="color: #186895;">end</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #ff3c00;">update_word_count</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Word</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Table</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
  <span style="color: #186895;">case</span> <span style="color: #ff4e18;">ets</span>:<span style="color: #ff3c00;">lookup</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Table</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Word</span><span style="color: #109ab8;">&#41;</span> <span style="color: #186895;">of</span>
    <span style="color: #109ab8;">&#91;</span><span style="color: #109ab8;">&#123;</span><span style="color: #45b3e6;">Word</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">_</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#93;</span> <span style="color: #6bb810;">-&gt;</span>
      <span style="color: #ff4e18;">ets</span>:<span style="color: #ff3c00;">update_counter</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Table</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Word</span><span style="color: #6bb810;">,</span> <span style="color: #ff9600;">1</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">;</span> 
    <span style="color: #109ab8;">&#91;</span><span style="color: #109ab8;">&#93;</span> <span style="color: #6bb810;">-&gt;</span>
      <span style="color: #ff4e18;">ets</span>:<span style="color: #ff3c00;">insert</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Table</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#123;</span><span style="color: #45b3e6;">Word</span><span style="color: #6bb810;">,</span> <span style="color: #ff9600;">1</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#41;</span>
  <span style="color: #186895;">end</span><span style="color: #6bb810;">,</span>
  <span style="color: #45b3e6;">Table</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #ff3c00;">print_words</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Words</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
  <span style="color: #ff4e18;">ets</span>:<span style="color: #ff3c00;">foldl</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff3c00;">fun</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#123;</span><span style="color: #45b3e6;">W</span><span style="color: #6bb810;">,</span><span style="color: #45b3e6;">C</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">AccIn</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span> 
    <span style="color: #ff4e18;">io</span>:<span style="color: #ff3c00;">format</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff7800;">&quot;~s: ~w~n&quot;</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span><span style="color: #45b3e6;">W</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">C</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">AccIn</span> <span style="color: #186895;">end</span><span style="color: #6bb810;">,</span> void<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Words</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #666666; font-style: italic;">%% opens the indicated file, processes the contents and prints</span>
<span style="color: #666666; font-style: italic;">%% out the word/count pairs to stdout</span>
<span style="color: #ff3c00;">print_word_counts</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Filename</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
  <span style="color: #109ab8;">&#123;</span>ok<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">IoDevice</span><span style="color: #109ab8;">&#125;</span> <span style="color: #014ea4;">=</span> <span style="color: #ff4e18;">file</span>:<span style="color: #ff3c00;">open</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Filename</span><span style="color: #6bb810;">,</span> read<span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
  <span style="color: #45b3e6;">Words</span> <span style="color: #014ea4;">=</span> <span style="color: #ff3c00;">process_each_line</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">IoDevice</span><span style="color: #6bb810;">,</span> <span style="color: #ff4e18;">ets</span>:<span style="color: #ff3c00;">new</span><span style="color: #109ab8;">&#40;</span>words<span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
  <span style="color: #ff3c00;">print_words</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Words</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span></pre></div></div>

<p>The ets implementation feels a bit forced (which it was &#8211; the point was to learn another module).  I don&#8217;t think I&#8217;d have gone this way in practice unless I wanted to persist the frequency data to a file or if the word data were more complex (for example if I were storing information about where in the file the word was, word neighbors, etc).</p>
<p>Enough of this sample.  On to something more substantial.</p>



Share and Enjoy:


	<a rel="nofollow" id="print" href="javascript:window.location='http%3A%2F%2Fwww.printfriendly.com%2Fprint%3Furl%3Dhttp%253A%252F%252Fwww.roberthorvick.com%252F2009%252F07%252F03%252Fthe-last-word-frequency-post-from-dict-to-ets%252F%26amp%3Bpartner%3Dsociable';" title="Print this article!"><img src="http://www.roberthorvick.com/wp-content/plugins/sociable/images/printfriendly.png" title="Print this article!" alt="Print this article!" class="sociable-hovers" /></a>
	<a rel="nofollow" id="twitter" href="javascript:window.location='http%3A%2F%2Ftwitter.com%2Fhome%3Fstatus%3DThe%2520last%2520word%2520frequency%2520post%2520-%2520from%2520dict%2520to%2520ets%2520-%2520http%253A%252F%252Fwww.roberthorvick.com%252F2009%252F07%252F03%252Fthe-last-word-frequency-post-from-dict-to-ets%252F';" title="Twitter"><img src="http://www.roberthorvick.com/wp-content/plugins/sociable/images/twitter.png" title="Twitter" alt="Twitter" class="sociable-hovers" /></a>
	<a rel="nofollow" id="digg" href="javascript:window.location='http%3A%2F%2Fdigg.com%2Fsubmit%3Fphase%3D2%26amp%3Burl%3Dhttp%253A%252F%252Fwww.roberthorvick.com%252F2009%252F07%252F03%252Fthe-last-word-frequency-post-from-dict-to-ets%252F%26amp%3Btitle%3DThe%2520last%2520word%2520frequency%2520post%2520-%2520from%2520dict%2520to%2520ets%26amp%3Bbodytext%3DOne%2520last%2520iteration%2520through%2520my%2520learning%2520exercise%2520of%2520building%2520a%2520word%2520frequency%2520list.%2520%2520In%2520this%2520last%2520post%2520I%2527m%2520moving%2520away%2520from%2520a%2520dict%2520and%2520to%2520an%2520ets%2520table.%2520%2520I%2520was%2520pleasantly%2520surprised%2520how%2520easy%2520the%2520conversion%2520was.%2520%2520For%2520example%2520printing%2520the%2520output%2520was%2520just%2520';" title="Digg"><img src="http://www.roberthorvick.com/wp-content/plugins/sociable/images/digg.png" title="Digg" alt="Digg" class="sociable-hovers" /></a>
	<a rel="nofollow" id="reddit" href="javascript:window.location='http%3A%2F%2Freddit.com%2Fsubmit%3Furl%3Dhttp%253A%252F%252Fwww.roberthorvick.com%252F2009%252F07%252F03%252Fthe-last-word-frequency-post-from-dict-to-ets%252F%26amp%3Btitle%3DThe%2520last%2520word%2520frequency%2520post%2520-%2520from%2520dict%2520to%2520ets';" title="Reddit"><img src="http://www.roberthorvick.com/wp-content/plugins/sociable/images/reddit.png" title="Reddit" alt="Reddit" class="sociable-hovers" /></a>
	<a rel="nofollow" id="del.icio.us" href="javascript:window.location='http%3A%2F%2Fdelicious.com%2Fpost%3Furl%3Dhttp%253A%252F%252Fwww.roberthorvick.com%252F2009%252F07%252F03%252Fthe-last-word-frequency-post-from-dict-to-ets%252F%26amp%3Btitle%3DThe%2520last%2520word%2520frequency%2520post%2520-%2520from%2520dict%2520to%2520ets%26amp%3Bnotes%3DOne%2520last%2520iteration%2520through%2520my%2520learning%2520exercise%2520of%2520building%2520a%2520word%2520frequency%2520list.%2520%2520In%2520this%2520last%2520post%2520I%2527m%2520moving%2520away%2520from%2520a%2520dict%2520and%2520to%2520an%2520ets%2520table.%2520%2520I%2520was%2520pleasantly%2520surprised%2520how%2520easy%2520the%2520conversion%2520was.%2520%2520For%2520example%2520printing%2520the%2520output%2520was%2520just%2520';" title="del.icio.us"><img src="http://www.roberthorvick.com/wp-content/plugins/sociable/images/delicious.png" title="del.icio.us" alt="del.icio.us" class="sociable-hovers" /></a>
	<a rel="nofollow" id="facebook" href="javascript:window.location='http%3A%2F%2Fwww.facebook.com%2Fshare.php%3Fu%3Dhttp%253A%252F%252Fwww.roberthorvick.com%252F2009%252F07%252F03%252Fthe-last-word-frequency-post-from-dict-to-ets%252F%26amp%3Bt%3DThe%2520last%2520word%2520frequency%2520post%2520-%2520from%2520dict%2520to%2520ets';" title="Facebook"><img src="http://www.roberthorvick.com/wp-content/plugins/sociable/images/facebook.png" title="Facebook" alt="Facebook" class="sociable-hovers" /></a>
	<a rel="nofollow" id="google" href="javascript:window.location='http%3A%2F%2Fwww.google.com%2Fbookmarks%2Fmark%3Fop%3Dedit%26amp%3Bbkmk%3Dhttp%253A%252F%252Fwww.roberthorvick.com%252F2009%252F07%252F03%252Fthe-last-word-frequency-post-from-dict-to-ets%252F%26amp%3Btitle%3DThe%2520last%2520word%2520frequency%2520post%2520-%2520from%2520dict%2520to%2520ets%26amp%3Bannotation%3DOne%2520last%2520iteration%2520through%2520my%2520learning%2520exercise%2520of%2520building%2520a%2520word%2520frequency%2520list.%2520%2520In%2520this%2520last%2520post%2520I%2527m%2520moving%2520away%2520from%2520a%2520dict%2520and%2520to%2520an%2520ets%2520table.%2520%2520I%2520was%2520pleasantly%2520surprised%2520how%2520easy%2520the%2520conversion%2520was.%2520%2520For%2520example%2520printing%2520the%2520output%2520was%2520just%2520';" title="Google Bookmarks"><img src="http://www.roberthorvick.com/wp-content/plugins/sociable/images/googlebookmark.png" title="Google Bookmarks" alt="Google Bookmarks" class="sociable-hovers" /></a>
	<a rel="nofollow" id="stumbleupon" href="javascript:window.location='http%3A%2F%2Fwww.stumbleupon.com%2Fsubmit%3Furl%3Dhttp%253A%252F%252Fwww.roberthorvick.com%252F2009%252F07%252F03%252Fthe-last-word-frequency-post-from-dict-to-ets%252F%26amp%3Btitle%3DThe%2520last%2520word%2520frequency%2520post%2520-%2520from%2520dict%2520to%2520ets';" title="StumbleUpon"><img src="http://www.roberthorvick.com/wp-content/plugins/sociable/images/stumbleupon.png" title="StumbleUpon" alt="StumbleUpon" class="sociable-hovers" /></a>


<br/><br/>]]></content:encoded>
			<wfw:commentRss>http://www.roberthorvick.com/2009/07/03/the-last-word-frequency-post-from-dict-to-ets/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Adding a custom protocol to Firefox for easy Erlang docs</title>
		<link>http://www.roberthorvick.com/2009/07/03/adding-a-custom-protocol-to-firefox-for-easy-erlang-docs/</link>
		<comments>http://www.roberthorvick.com/2009/07/03/adding-a-custom-protocol-to-firefox-for-easy-erlang-docs/#comments</comments>
		<pubDate>Sat, 04 Jul 2009 01:11:43 +0000</pubDate>
		<dc:creator>robert</dc:creator>
				<category><![CDATA[Erlang]]></category>

		<guid isPermaLink="false">http://www.roberthorvick.com/?p=50</guid>
		<description><![CDATA[To make getting to the Erlang docs a bit quicker I added a custom protocol handler to firefox so when I go to:
erlang://lists
I get redirected to
http://www.erlang.org/doc/man/lists.html
To do this I first created a little shell script that would take the address and spawn firefox with the appropriate url.  (insert caveat about this being the first [...]]]></description>
			<content:encoded><![CDATA[<p>To make getting to the Erlang docs a bit quicker I added a custom protocol handler to firefox so when I go to:</p>
<p><a href="erlang://lists">erlang://lists</a></p>
<p>I get redirected to</p>
<p><a href="http://www.erlang.org/doc/man/lists.html">http://www.erlang.org/doc/man/lists.html</a></p>
<p>To do this I first created a little shell script that would take the address and spawn firefox with the appropriate url.  (insert caveat about this being the first bash script I&#8217;ve written in 10 years here &#8230;).</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/bash</span>
<span style="color: #007800;">ERLANG_TOPIC</span>=<span style="color: #000000; font-weight: bold;">`</span><span style="color: #7a0874; font-weight: bold;">echo</span> $<span style="color: #000000;">1</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">sed</span> <span style="color: #ff0000;">'s/erlang:\/\///'</span><span style="color: #000000; font-weight: bold;">`</span>
<span style="color: #7a0874; font-weight: bold;">exec</span> firefox http:<span style="color: #000000; font-weight: bold;">//</span>www.erlang.org<span style="color: #000000; font-weight: bold;">/</span>doc<span style="color: #000000; font-weight: bold;">/</span>man<span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">$ERLANG_TOPIC</span>.html</pre></div></div>

<p>Next I marked it as executable:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">chmod</span> +x erlang.protocol</pre></div></div>

<p>Finally I followed <a href="http://kb.mozillazine.org/Register_protocol">these directions</a> and added the following config settings in firefox:</p>
<p><img class="aligncenter size-full wp-image-52" title="Adding custom protocol to firefox" src="http://www.roberthorvick.com/wp-content/uploads/2009/07/aboutconfig.png" alt="Adding custom protocol to firefox" width="774" height="137" /></p>
<p>Since the Erlang/OTP doc pages match their module names this works pretty well.</p>
<p>For queries where I&#8217;m not sure what I want I added a Erlang specific google search to my <a href="http://www.roberthorvick.com/erlang-resources/">Erlang Resources</a> page.</p>



Share and Enjoy:


	<a rel="nofollow" id="print" href="javascript:window.location='http%3A%2F%2Fwww.printfriendly.com%2Fprint%3Furl%3Dhttp%253A%252F%252Fwww.roberthorvick.com%252F2009%252F07%252F03%252Fadding-a-custom-protocol-to-firefox-for-easy-erlang-docs%252F%26amp%3Bpartner%3Dsociable';" title="Print this article!"><img src="http://www.roberthorvick.com/wp-content/plugins/sociable/images/printfriendly.png" title="Print this article!" alt="Print this article!" class="sociable-hovers" /></a>
	<a rel="nofollow" id="twitter" href="javascript:window.location='http%3A%2F%2Ftwitter.com%2Fhome%3Fstatus%3DAdding%2520a%2520custom%2520protocol%2520to%2520Firefox%2520for%2520easy%2520Erlang%2520docs%2520-%2520http%253A%252F%252Fwww.roberthorvick.com%252F2009%252F07%252F03%252Fadding-a-custom-protocol-to-firefox-for-easy-erlang-docs%252F';" title="Twitter"><img src="http://www.roberthorvick.com/wp-content/plugins/sociable/images/twitter.png" title="Twitter" alt="Twitter" class="sociable-hovers" /></a>
	<a rel="nofollow" id="digg" href="javascript:window.location='http%3A%2F%2Fdigg.com%2Fsubmit%3Fphase%3D2%26amp%3Burl%3Dhttp%253A%252F%252Fwww.roberthorvick.com%252F2009%252F07%252F03%252Fadding-a-custom-protocol-to-firefox-for-easy-erlang-docs%252F%26amp%3Btitle%3DAdding%2520a%2520custom%2520protocol%2520to%2520Firefox%2520for%2520easy%2520Erlang%2520docs%26amp%3Bbodytext%3DTo%2520make%2520getting%2520to%2520the%2520Erlang%2520docs%2520a%2520bit%2520quicker%2520I%2520added%2520a%2520custom%2520protocol%2520handler%2520to%2520firefox%2520so%2520when%2520I%2520go%2520to%253A%250D%250A%250D%250Aerlang%253A%252F%252Flists%250D%250A%250D%250AI%2520get%2520redirected%2520to%250D%250A%250D%250Ahttp%253A%252F%252Fwww.erlang.org%252Fdoc%252Fman%252Flists.html%250D%250A%250D%250ATo%2520do%2520this%2520I%2520first%2520created%2520a%2520little%2520shell%2520script%2520th';" title="Digg"><img src="http://www.roberthorvick.com/wp-content/plugins/sociable/images/digg.png" title="Digg" alt="Digg" class="sociable-hovers" /></a>
	<a rel="nofollow" id="reddit" href="javascript:window.location='http%3A%2F%2Freddit.com%2Fsubmit%3Furl%3Dhttp%253A%252F%252Fwww.roberthorvick.com%252F2009%252F07%252F03%252Fadding-a-custom-protocol-to-firefox-for-easy-erlang-docs%252F%26amp%3Btitle%3DAdding%2520a%2520custom%2520protocol%2520to%2520Firefox%2520for%2520easy%2520Erlang%2520docs';" title="Reddit"><img src="http://www.roberthorvick.com/wp-content/plugins/sociable/images/reddit.png" title="Reddit" alt="Reddit" class="sociable-hovers" /></a>
	<a rel="nofollow" id="del.icio.us" href="javascript:window.location='http%3A%2F%2Fdelicious.com%2Fpost%3Furl%3Dhttp%253A%252F%252Fwww.roberthorvick.com%252F2009%252F07%252F03%252Fadding-a-custom-protocol-to-firefox-for-easy-erlang-docs%252F%26amp%3Btitle%3DAdding%2520a%2520custom%2520protocol%2520to%2520Firefox%2520for%2520easy%2520Erlang%2520docs%26amp%3Bnotes%3DTo%2520make%2520getting%2520to%2520the%2520Erlang%2520docs%2520a%2520bit%2520quicker%2520I%2520added%2520a%2520custom%2520protocol%2520handler%2520to%2520firefox%2520so%2520when%2520I%2520go%2520to%253A%250D%250A%250D%250Aerlang%253A%252F%252Flists%250D%250A%250D%250AI%2520get%2520redirected%2520to%250D%250A%250D%250Ahttp%253A%252F%252Fwww.erlang.org%252Fdoc%252Fman%252Flists.html%250D%250A%250D%250ATo%2520do%2520this%2520I%2520first%2520created%2520a%2520little%2520shell%2520script%2520th';" title="del.icio.us"><img src="http://www.roberthorvick.com/wp-content/plugins/sociable/images/delicious.png" title="del.icio.us" alt="del.icio.us" class="sociable-hovers" /></a>
	<a rel="nofollow" id="facebook" href="javascript:window.location='http%3A%2F%2Fwww.facebook.com%2Fshare.php%3Fu%3Dhttp%253A%252F%252Fwww.roberthorvick.com%252F2009%252F07%252F03%252Fadding-a-custom-protocol-to-firefox-for-easy-erlang-docs%252F%26amp%3Bt%3DAdding%2520a%2520custom%2520protocol%2520to%2520Firefox%2520for%2520easy%2520Erlang%2520docs';" title="Facebook"><img src="http://www.roberthorvick.com/wp-content/plugins/sociable/images/facebook.png" title="Facebook" alt="Facebook" class="sociable-hovers" /></a>
	<a rel="nofollow" id="google" href="javascript:window.location='http%3A%2F%2Fwww.google.com%2Fbookmarks%2Fmark%3Fop%3Dedit%26amp%3Bbkmk%3Dhttp%253A%252F%252Fwww.roberthorvick.com%252F2009%252F07%252F03%252Fadding-a-custom-protocol-to-firefox-for-easy-erlang-docs%252F%26amp%3Btitle%3DAdding%2520a%2520custom%2520protocol%2520to%2520Firefox%2520for%2520easy%2520Erlang%2520docs%26amp%3Bannotation%3DTo%2520make%2520getting%2520to%2520the%2520Erlang%2520docs%2520a%2520bit%2520quicker%2520I%2520added%2520a%2520custom%2520protocol%2520handler%2520to%2520firefox%2520so%2520when%2520I%2520go%2520to%253A%250D%250A%250D%250Aerlang%253A%252F%252Flists%250D%250A%250D%250AI%2520get%2520redirected%2520to%250D%250A%250D%250Ahttp%253A%252F%252Fwww.erlang.org%252Fdoc%252Fman%252Flists.html%250D%250A%250D%250ATo%2520do%2520this%2520I%2520first%2520created%2520a%2520little%2520shell%2520script%2520th';" title="Google Bookmarks"><img src="http://www.roberthorvick.com/wp-content/plugins/sociable/images/googlebookmark.png" title="Google Bookmarks" alt="Google Bookmarks" class="sociable-hovers" /></a>
	<a rel="nofollow" id="stumbleupon" href="javascript:window.location='http%3A%2F%2Fwww.stumbleupon.com%2Fsubmit%3Furl%3Dhttp%253A%252F%252Fwww.roberthorvick.com%252F2009%252F07%252F03%252Fadding-a-custom-protocol-to-firefox-for-easy-erlang-docs%252F%26amp%3Btitle%3DAdding%2520a%2520custom%2520protocol%2520to%2520Firefox%2520for%2520easy%2520Erlang%2520docs';" title="StumbleUpon"><img src="http://www.roberthorvick.com/wp-content/plugins/sociable/images/stumbleupon.png" title="StumbleUpon" alt="StumbleUpon" class="sociable-hovers" /></a>


<br/><br/>]]></content:encoded>
			<wfw:commentRss>http://www.roberthorvick.com/2009/07/03/adding-a-custom-protocol-to-firefox-for-easy-erlang-docs/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Word frequency redux &#8211; Erlang list comprehension, regex and list folding</title>
		<link>http://www.roberthorvick.com/2009/07/02/word-frequency-redux-erlang-list-comprehension-regex-and-list-folding/</link>
		<comments>http://www.roberthorvick.com/2009/07/02/word-frequency-redux-erlang-list-comprehension-regex-and-list-folding/#comments</comments>
		<pubDate>Thu, 02 Jul 2009 21:28:10 +0000</pubDate>
		<dc:creator>robert</dc:creator>
				<category><![CDATA[Erlang]]></category>

		<guid isPermaLink="false">http://www.roberthorvick.com/?p=41</guid>
		<description><![CDATA[Sean Cribbs was nice enough to point out a pair of changes I could make to my word frequency counter from last time.
Based on his feedback I made three changes.  First &#8211; the regular expression code has changed from this:

matches&#40;H,&#123;match,M&#125;&#41; -&#62; matches&#40;H,M,&#91;&#93;&#41;.
matches&#40;_,&#91;&#93;,Acc&#41; -&#62; Acc;
matches&#40;H,&#91;&#123;I,L&#125;&#124;T&#93;,Acc&#41; -&#62;
    matches&#40;H,T,&#91;lists:sublist&#40;H,I,L&#41;&#124;Acc&#93;&#41;.
&#160;
words&#40;String&#41; -&#62; matches&#40;String,regexp:matches&#40;String, &#34;[A-Za-z0-1]+&#34;&#41;&#41;.

to this:

words&#40;String&#41; -&#62;
 [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://seancribbs.com/">Sean Cribbs</a> was nice enough to <a href="http://www.roberthorvick.com/2009/07/02/finding-word-frequencies-using-erlang/#comments">point out</a> a pair of changes I could make to my <a href="http://www.roberthorvick.com/2009/07/02/finding-word-frequencies-using-erlang/">word frequency counter</a> from last time.</p>
<p>Based on his feedback I made three changes.  First &#8211; the regular expression code has changed from this:</p>

<div class="wp_syntax"><div class="code"><pre class="erlang" style="font-family:monospace;"><span style="color: #ff3c00;">matches</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">H</span><span style="color: #6bb810;">,</span><span style="color: #109ab8;">&#123;</span>match<span style="color: #6bb810;">,</span><span style="color: #45b3e6;">M</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span> <span style="color: #ff3c00;">matches</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">H</span><span style="color: #6bb810;">,</span><span style="color: #45b3e6;">M</span><span style="color: #6bb810;">,</span><span style="color: #109ab8;">&#91;</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
<span style="color: #ff3c00;">matches</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">_</span><span style="color: #6bb810;">,</span><span style="color: #109ab8;">&#91;</span><span style="color: #109ab8;">&#93;</span><span style="color: #6bb810;">,</span><span style="color: #45b3e6;">Acc</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span> <span style="color: #45b3e6;">Acc</span><span style="color: #6bb810;">;</span>
<span style="color: #ff3c00;">matches</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">H</span><span style="color: #6bb810;">,</span><span style="color: #109ab8;">&#91;</span><span style="color: #109ab8;">&#123;</span><span style="color: #45b3e6;">I</span><span style="color: #6bb810;">,</span><span style="color: #45b3e6;">L</span><span style="color: #109ab8;">&#125;</span>|T<span style="color: #109ab8;">&#93;</span><span style="color: #6bb810;">,</span><span style="color: #45b3e6;">Acc</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #ff3c00;">matches</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">H</span><span style="color: #6bb810;">,</span><span style="color: #45b3e6;">T</span><span style="color: #6bb810;">,</span><span style="color: #109ab8;">&#91;</span><span style="color: #ff4e18;">lists</span>:<span style="color: #ff3c00;">sublist</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">H</span><span style="color: #6bb810;">,</span><span style="color: #45b3e6;">I</span><span style="color: #6bb810;">,</span><span style="color: #45b3e6;">L</span><span style="color: #109ab8;">&#41;</span>|Acc<span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #ff3c00;">words</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">String</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span> <span style="color: #ff3c00;">matches</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">String</span><span style="color: #6bb810;">,</span><span style="color: #ff4e18;">regexp</span>:<span style="color: #ff3c00;">matches</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">String</span><span style="color: #6bb810;">,</span> <span style="color: #ff7800;">&quot;[A-Za-z0-1]+&quot;</span><span style="color: #109ab8;">&#41;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span></pre></div></div>

<p>to this:</p>

<div class="wp_syntax"><div class="code"><pre class="erlang" style="font-family:monospace;"><span style="color: #ff3c00;">words</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">String</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
  <span style="color: #109ab8;">&#123;</span>match<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Captures</span><span style="color: #109ab8;">&#125;</span> <span style="color: #014ea4;">=</span> <span style="color: #ff4e18;">re</span>:<span style="color: #ff3c00;">run</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">String</span><span style="color: #6bb810;">,</span> <span style="color: #ff7800;">&quot;<span style="color: #000099; font-weight: bold;">\\</span>b<span style="color: #000099; font-weight: bold;">\\</span>w+<span style="color: #000099; font-weight: bold;">\\</span>b&quot;</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span>global<span style="color: #6bb810;">,</span><span style="color: #109ab8;">&#123;</span>capture<span style="color: #6bb810;">,</span>first<span style="color: #6bb810;">,</span><span style="color: #fa6fff;">list</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
  <span style="color: #109ab8;">&#91;</span><span style="color: #ff3c00;">hd</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">C</span><span style="color: #109ab8;">&#41;</span> <span style="color: #014ea4;">||</span> <span style="color: #45b3e6;">C</span><span style="color: #014ea4;">&lt;-</span><span style="color: #45b3e6;">Captures</span><span style="color: #109ab8;">&#93;</span><span style="color: #6bb810;">.</span></pre></div></div>

<p>That last line took me a bit to grok.  It&#8217;s a <a href="http://wiki.trapexit.org/List_Comprehension">list comprehension</a> (if you are reading Joe Armstrong&#8217;s <a href="http://www.sics.se/~joe/thesis/armstrong_thesis_2003.pdf">thesis</a> it is section 3.3.13.  In Erlang Programming it is chapter 9.3).  Basically it&#8217;s saying &#8220;for each list in the list of matches take the head of the list&#8221; &#8211; a-gigga-wah?</p>
<p>Ok.  Let&#8217;s go to erl.<br />
<code>7&gt; re:run("foo foo bar", "\\b\\w+\\b", [global,{capture,first,list}]).<br />
{match,[["foo"],["foo"],["bar"]]}</code><br />
Observe that re:run returns a nested list (i.e. a list of lists) &#8211; and each list has exactly one element (the string [which is itself a list but I'll cal them strings]).  What we want to do is take that list-of-lists-of-strings and turn it into a list-of-strings.</p>
<p>That&#8217;s what &#8220;[hd(C) || C&lt;-Captures].&#8221; does  &#8211; it pulls every capture (a word wrapped in a list) from the match list and runs it through erlang:hd which pulls the word from the list &#8211; then it gets added to the resulting list.  So we end up with a list strings.</p>
<p>It&#8217;s un-nesting the list.</p>
<p>Next Sean suggested <em>&#8220;Then I’d probably use some kind of key-value structure, like a proplist or dict, to count the words using a lists:foldX function.&#8221;</em></p>
<p>so I fired up &#8220;erl -man lists&#8221; to learn what foldX meant (actually &#8220;foldl&#8221; &#8220;foldr&#8221; depending on whether you want to fold from the left or right.</p>
<p>In a nut shell folding is iterates over a list calling a fun that takes the current value and an accumulator and which returns the new accumulator.  An example from the man page is:</p>
<p><code><br />
&gt; lists:foldl(fun(X, Sum) -&gt; X + Sum end, 0, [1,2,3,4,5]).<br />
15<br />
</code></p>
<p>I spent some time thinking and after some trial and error came up with this:</p>

<div class="wp_syntax"><div class="code"><pre class="erlang" style="font-family:monospace;"><span style="color: #ff4e18;">lists</span>:<span style="color: #ff3c00;">foldl</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff3c00;">fun</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">W</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Dict</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span> 
    <span style="color: #ff4e18;">dict</span>:<span style="color: #ff3c00;">update</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">W</span><span style="color: #6bb810;">,</span> <span style="color: #ff3c00;">fun</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">C</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span> <span style="color: #45b3e6;">C</span> <span style="color: #014ea4;">+</span> <span style="color: #ff9600;">1</span> <span style="color: #186895;">end</span><span style="color: #6bb810;">,</span> <span style="color: #ff9600;">1</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Dict</span><span style="color: #109ab8;">&#41;</span> <span style="color: #186895;">end</span><span style="color: #6bb810;">,</span> <span style="color: #ff4e18;">dict</span>:<span style="color: #ff3c00;">new</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span> 
    <span style="color: #109ab8;">&#91;</span><span style="color: #ff7800;">&quot;foo&quot;</span><span style="color: #6bb810;">,</span> <span style="color: #ff7800;">&quot;foo&quot;</span><span style="color: #6bb810;">,</span> <span style="color: #ff7800;">&quot;bar&quot;</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>  <span style="color: #666666; font-style: italic;">%% sample input</span></pre></div></div>

<p>In a nutshell &#8211; for every word in the list update the dictionary by calling the fun which increments the count value, setting the initial count to 1 if the value does not already exist in the dictionary (and starting with an empty dictionary).</p>
<p>After these three changes the new program is about half the size of the previous and really only has a few interesting lines surround by nearly error and flow control.</p>
<p><strong>Thanks Sean!</strong></p>
<p>The new code &#8230;</p>

<div class="wp_syntax"><div class="code"><pre class="erlang" style="font-family:monospace;"><span style="color: #014ea4;">-</span><span style="color: #5400b3;">module</span><span style="color: #109ab8;">&#40;</span>wordlist<span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #014ea4;">-</span><span style="color: #5400b3;">export</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#91;</span>print_word_counts<span style="color: #014ea4;">/</span><span style="color: #ff9600;">1</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #ff3c00;">words</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">String</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
  <span style="color: #109ab8;">&#123;</span>match<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Captures</span><span style="color: #109ab8;">&#125;</span> <span style="color: #014ea4;">=</span> <span style="color: #ff4e18;">re</span>:<span style="color: #ff3c00;">run</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">String</span><span style="color: #6bb810;">,</span> <span style="color: #ff7800;">&quot;<span style="color: #000099; font-weight: bold;">\\</span>b<span style="color: #000099; font-weight: bold;">\\</span>w+<span style="color: #000099; font-weight: bold;">\\</span>b&quot;</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span>global<span style="color: #6bb810;">,</span><span style="color: #109ab8;">&#123;</span>capture<span style="color: #6bb810;">,</span>first<span style="color: #6bb810;">,</span><span style="color: #fa6fff;">list</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
  <span style="color: #109ab8;">&#91;</span><span style="color: #ff3c00;">hd</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">C</span><span style="color: #109ab8;">&#41;</span> <span style="color: #014ea4;">||</span> <span style="color: #45b3e6;">C</span><span style="color: #014ea4;">&lt;-</span><span style="color: #45b3e6;">Captures</span><span style="color: #109ab8;">&#93;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #666666; font-style: italic;">%% reads the next line from the file.  If there is data then...</span>
<span style="color: #666666; font-style: italic;">%% split the data into a list of words and add those to the word dict</span>
<span style="color: #ff3c00;">process_each_line</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">IoDevice</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Dict</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #186895;">case</span> <span style="color: #ff4e18;">io</span>:<span style="color: #ff3c00;">get_line</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">IoDevice</span><span style="color: #6bb810;">,</span> <span style="color: #ff7800;">&quot;&quot;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #186895;">of</span>
        eof <span style="color: #6bb810;">-&gt;</span> 
            <span style="color: #ff4e18;">file</span>:<span style="color: #ff3c00;">close</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">IoDevice</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
            <span style="color: #45b3e6;">Dict</span><span style="color: #6bb810;">;</span>
        <span style="color: #109ab8;">&#123;</span>error<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Reason</span><span style="color: #109ab8;">&#125;</span> <span style="color: #6bb810;">-&gt;</span>
            <span style="color: #ff4e18;">file</span>:<span style="color: #ff3c00;">close</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">IoDevice</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
            <span style="color: #ff3c00;">throw</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Reason</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">;</span>
        <span style="color: #45b3e6;">Data</span> <span style="color: #6bb810;">-&gt;</span>
            <span style="color: #45b3e6;">NewDict</span> <span style="color: #014ea4;">=</span> <span style="color: #ff4e18;">lists</span>:<span style="color: #ff3c00;">foldl</span><span style="color: #109ab8;">&#40;</span>
                        <span style="color: #ff3c00;">fun</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">W</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">D</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span> <span style="color: #ff4e18;">dict</span>:<span style="color: #ff3c00;">update</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">W</span><span style="color: #6bb810;">,</span> <span style="color: #ff3c00;">fun</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">C</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span> <span style="color: #45b3e6;">C</span> <span style="color: #014ea4;">+</span> <span style="color: #ff9600;">1</span> <span style="color: #186895;">end</span><span style="color: #6bb810;">,</span> <span style="color: #ff9600;">1</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">D</span><span style="color: #109ab8;">&#41;</span> <span style="color: #186895;">end</span><span style="color: #6bb810;">,</span> 
                        <span style="color: #ff4e18;">dict</span>:<span style="color: #ff3c00;">new</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span> 
                        <span style="color: #ff3c00;">words</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Data</span><span style="color: #109ab8;">&#41;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
            <span style="color: #ff3c00;">process_each_line</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">IoDevice</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">NewDict</span><span style="color: #109ab8;">&#41;</span>
    <span style="color: #186895;">end</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #ff3c00;">print_dict</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Dict</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #ff4e18;">dict</span>:<span style="color: #ff3c00;">fold</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff3c00;">fun</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Word</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Count</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">AccIn</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span> 
        <span style="color: #ff4e18;">io</span>:<span style="color: #ff3c00;">format</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff7800;">&quot;~s: ~w~n&quot;</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span><span style="color: #45b3e6;">Word</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Count</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">AccIn</span> <span style="color: #186895;">end</span><span style="color: #6bb810;">,</span> void<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Dict</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #666666; font-style: italic;">%% opens the indicated file, processes the contents and prints</span>
<span style="color: #666666; font-style: italic;">%% out the word/count pairs to stdout</span>
<span style="color: #ff3c00;">print_word_counts</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Filename</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #186895;">case</span> <span style="color: #ff4e18;">file</span>:<span style="color: #ff3c00;">open</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Filename</span><span style="color: #6bb810;">,</span> read<span style="color: #109ab8;">&#41;</span> <span style="color: #186895;">of</span>
        <span style="color: #109ab8;">&#123;</span>ok<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">IoDevice</span><span style="color: #109ab8;">&#125;</span> <span style="color: #6bb810;">-&gt;</span>
            <span style="color: #45b3e6;">Dict</span> <span style="color: #014ea4;">=</span> <span style="color: #ff3c00;">process_each_line</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">IoDevice</span><span style="color: #6bb810;">,</span> <span style="color: #ff4e18;">dict</span>:<span style="color: #ff3c00;">new</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#41;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
            <span style="color: #ff3c00;">print_dict</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Dict</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">;</span>
    <span style="color: #186895;">end</span><span style="color: #6bb810;">.</span></pre></div></div>




Share and Enjoy:


	<a rel="nofollow" id="print" href="javascript:window.location='http%3A%2F%2Fwww.printfriendly.com%2Fprint%3Furl%3Dhttp%253A%252F%252Fwww.roberthorvick.com%252F2009%252F07%252F02%252Fword-frequency-redux-erlang-list-comprehension-regex-and-list-folding%252F%26amp%3Bpartner%3Dsociable';" title="Print this article!"><img src="http://www.roberthorvick.com/wp-content/plugins/sociable/images/printfriendly.png" title="Print this article!" alt="Print this article!" class="sociable-hovers" /></a>
	<a rel="nofollow" id="twitter" href="javascript:window.location='http%3A%2F%2Ftwitter.com%2Fhome%3Fstatus%3DWord%2520frequency%2520redux%2520-%2520Erlang%2520list%2520comprehension%252C%2520regex%2520and%2520list%2520folding%2520-%2520http%253A%252F%252Fwww.roberthorvick.com%252F2009%252F07%252F02%252Fword-frequency-redux-erlang-list-comprehension-regex-and-list-folding%252F';" title="Twitter"><img src="http://www.roberthorvick.com/wp-content/plugins/sociable/images/twitter.png" title="Twitter" alt="Twitter" class="sociable-hovers" /></a>
	<a rel="nofollow" id="digg" href="javascript:window.location='http%3A%2F%2Fdigg.com%2Fsubmit%3Fphase%3D2%26amp%3Burl%3Dhttp%253A%252F%252Fwww.roberthorvick.com%252F2009%252F07%252F02%252Fword-frequency-redux-erlang-list-comprehension-regex-and-list-folding%252F%26amp%3Btitle%3DWord%2520frequency%2520redux%2520-%2520Erlang%2520list%2520comprehension%252C%2520regex%2520and%2520list%2520folding%26amp%3Bbodytext%3DSean%2520Cribbs%2520was%2520nice%2520enough%2520to%2520point%2520out%2520a%2520pair%2520of%2520changes%2520I%2520could%2520make%2520to%2520my%2520word%2520frequency%2520counter%2520from%2520last%2520time.%250D%250A%250D%250ABased%2520on%2520his%2520feedback%2520I%2520made%2520three%2520changes.%2520%2520First%2520-%2520the%2520regular%2520expression%2520code%2520has%2520changed%2520from%2520this%253A%250D%250A%250D%250A%250D%250Amatches%2528H%252C%257Bmatch%252CM%257D%2529%2520';" title="Digg"><img src="http://www.roberthorvick.com/wp-content/plugins/sociable/images/digg.png" title="Digg" alt="Digg" class="sociable-hovers" /></a>
	<a rel="nofollow" id="reddit" href="javascript:window.location='http%3A%2F%2Freddit.com%2Fsubmit%3Furl%3Dhttp%253A%252F%252Fwww.roberthorvick.com%252F2009%252F07%252F02%252Fword-frequency-redux-erlang-list-comprehension-regex-and-list-folding%252F%26amp%3Btitle%3DWord%2520frequency%2520redux%2520-%2520Erlang%2520list%2520comprehension%252C%2520regex%2520and%2520list%2520folding';" title="Reddit"><img src="http://www.roberthorvick.com/wp-content/plugins/sociable/images/reddit.png" title="Reddit" alt="Reddit" class="sociable-hovers" /></a>
	<a rel="nofollow" id="del.icio.us" href="javascript:window.location='http%3A%2F%2Fdelicious.com%2Fpost%3Furl%3Dhttp%253A%252F%252Fwww.roberthorvick.com%252F2009%252F07%252F02%252Fword-frequency-redux-erlang-list-comprehension-regex-and-list-folding%252F%26amp%3Btitle%3DWord%2520frequency%2520redux%2520-%2520Erlang%2520list%2520comprehension%252C%2520regex%2520and%2520list%2520folding%26amp%3Bnotes%3DSean%2520Cribbs%2520was%2520nice%2520enough%2520to%2520point%2520out%2520a%2520pair%2520of%2520changes%2520I%2520could%2520make%2520to%2520my%2520word%2520frequency%2520counter%2520from%2520last%2520time.%250D%250A%250D%250ABased%2520on%2520his%2520feedback%2520I%2520made%2520three%2520changes.%2520%2520First%2520-%2520the%2520regular%2520expression%2520code%2520has%2520changed%2520from%2520this%253A%250D%250A%250D%250A%250D%250Amatches%2528H%252C%257Bmatch%252CM%257D%2529%2520';" title="del.icio.us"><img src="http://www.roberthorvick.com/wp-content/plugins/sociable/images/delicious.png" title="del.icio.us" alt="del.icio.us" class="sociable-hovers" /></a>
	<a rel="nofollow" id="facebook" href="javascript:window.location='http%3A%2F%2Fwww.facebook.com%2Fshare.php%3Fu%3Dhttp%253A%252F%252Fwww.roberthorvick.com%252F2009%252F07%252F02%252Fword-frequency-redux-erlang-list-comprehension-regex-and-list-folding%252F%26amp%3Bt%3DWord%2520frequency%2520redux%2520-%2520Erlang%2520list%2520comprehension%252C%2520regex%2520and%2520list%2520folding';" title="Facebook"><img src="http://www.roberthorvick.com/wp-content/plugins/sociable/images/facebook.png" title="Facebook" alt="Facebook" class="sociable-hovers" /></a>
	<a rel="nofollow" id="google" href="javascript:window.location='http%3A%2F%2Fwww.google.com%2Fbookmarks%2Fmark%3Fop%3Dedit%26amp%3Bbkmk%3Dhttp%253A%252F%252Fwww.roberthorvick.com%252F2009%252F07%252F02%252Fword-frequency-redux-erlang-list-comprehension-regex-and-list-folding%252F%26amp%3Btitle%3DWord%2520frequency%2520redux%2520-%2520Erlang%2520list%2520comprehension%252C%2520regex%2520and%2520list%2520folding%26amp%3Bannotation%3DSean%2520Cribbs%2520was%2520nice%2520enough%2520to%2520point%2520out%2520a%2520pair%2520of%2520changes%2520I%2520could%2520make%2520to%2520my%2520word%2520frequency%2520counter%2520from%2520last%2520time.%250D%250A%250D%250ABased%2520on%2520his%2520feedback%2520I%2520made%2520three%2520changes.%2520%2520First%2520-%2520the%2520regular%2520expression%2520code%2520has%2520changed%2520from%2520this%253A%250D%250A%250D%250A%250D%250Amatches%2528H%252C%257Bmatch%252CM%257D%2529%2520';" title="Google Bookmarks"><img src="http://www.roberthorvick.com/wp-content/plugins/sociable/images/googlebookmark.png" title="Google Bookmarks" alt="Google Bookmarks" class="sociable-hovers" /></a>
	<a rel="nofollow" id="stumbleupon" href="javascript:window.location='http%3A%2F%2Fwww.stumbleupon.com%2Fsubmit%3Furl%3Dhttp%253A%252F%252Fwww.roberthorvick.com%252F2009%252F07%252F02%252Fword-frequency-redux-erlang-list-comprehension-regex-and-list-folding%252F%26amp%3Btitle%3DWord%2520frequency%2520redux%2520-%2520Erlang%2520list%2520comprehension%252C%2520regex%2520and%2520list%2520folding';" title="StumbleUpon"><img src="http://www.roberthorvick.com/wp-content/plugins/sociable/images/stumbleupon.png" title="StumbleUpon" alt="StumbleUpon" class="sociable-hovers" /></a>


<br/><br/>]]></content:encoded>
			<wfw:commentRss>http://www.roberthorvick.com/2009/07/02/word-frequency-redux-erlang-list-comprehension-regex-and-list-folding/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Finding word frequencies using Erlang</title>
		<link>http://www.roberthorvick.com/2009/07/02/finding-word-frequencies-using-erlang/</link>
		<comments>http://www.roberthorvick.com/2009/07/02/finding-word-frequencies-using-erlang/#comments</comments>
		<pubDate>Thu, 02 Jul 2009 04:24:26 +0000</pubDate>
		<dc:creator>robert</dc:creator>
				<category><![CDATA[Erlang]]></category>

		<guid isPermaLink="false">http://www.roberthorvick.com/?p=32</guid>
		<description><![CDATA[Here&#8217;s a follow-up post that provides a better implementation.
I wanted to try and bite off something a little larger today hitting a few areas that seem generally useful:

Basic text file operations
Basic string operations
Using the gb_trees module
Avoiding any usage of lists:foreach; instead using tail recursion (that whole &#8220;thinking in Erlang&#8221; thing).

The problem is to produce the [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.roberthorvick.com/2009/07/02/word-frequency-redux-erlang-list-comprehension-regex-and-list-folding/">Here&#8217;s a follow-up post that provides a better implementation.</a></p>
<p>I wanted to try and bite off something a little larger today hitting a few areas that seem generally useful:</p>
<ol>
<li>Basic text <a href="http://www.erlang.org/doc/man/file.html">file</a> operations</li>
<li>Basic string operations</li>
<li>Using the <a href="http://www.erlang.org/doc/man/gb_trees.html">gb_trees</a> module</li>
<li>Avoiding any usage of lists:foreach; instead using tail recursion (that whole &#8220;thinking in Erlang&#8221; thing).</li>
</ol>
<p>The problem is to produce the word frequency of a specific text file and to print out the frequency information.  For example if a file overdunn.txt contained the text:</p>
<p><em>&#8220;Dunn was over Unger and I was over Dunn.&#8221;</em> (<a href="http://www.imdb.com/character/ch0006136/quotes">Capt. Oveur</a>, <a href="http://www.imdb.com/title/tt0083530/">Airplane II: The Sequel)</a></p>
<p>The output would be:</p>
<p><code>Dunn: 2<br />
I: 1<br />
Unger: 1<br />
and: 1<br />
over: 2<br />
was: 2</code></p>
<p>Word frequencies have some practical uses (fuzzy text matching, building tag clouds, etc).  So while it&#8217;s a bit contrived it is the basis for something useful.</p>
<p>The code doesn&#8217;t need a lot of explanation &#8211; so here you go &#8230;</p>

<div class="wp_syntax"><div class="code"><pre class="erlang" style="font-family:monospace;"><span style="color: #014ea4;">-</span><span style="color: #5400b3;">module</span><span style="color: #109ab8;">&#40;</span>wordlist<span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #014ea4;">-</span><span style="color: #5400b3;">export</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#91;</span>print_word_counts<span style="color: #014ea4;">/</span><span style="color: #ff9600;">1</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #666666; font-style: italic;">%% matches/* and words/1 From: http://www.trapexit.org/Matching_Words</span>
<span style="color: #ff3c00;">matches</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">H</span><span style="color: #6bb810;">,</span><span style="color: #109ab8;">&#123;</span>match<span style="color: #6bb810;">,</span><span style="color: #45b3e6;">M</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span> <span style="color: #ff3c00;">matches</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">H</span><span style="color: #6bb810;">,</span><span style="color: #45b3e6;">M</span><span style="color: #6bb810;">,</span><span style="color: #109ab8;">&#91;</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
<span style="color: #ff3c00;">matches</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">_</span><span style="color: #6bb810;">,</span><span style="color: #109ab8;">&#91;</span><span style="color: #109ab8;">&#93;</span><span style="color: #6bb810;">,</span><span style="color: #45b3e6;">Acc</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span> <span style="color: #45b3e6;">Acc</span><span style="color: #6bb810;">;</span>
<span style="color: #ff3c00;">matches</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">H</span><span style="color: #6bb810;">,</span><span style="color: #109ab8;">&#91;</span><span style="color: #109ab8;">&#123;</span><span style="color: #45b3e6;">I</span><span style="color: #6bb810;">,</span><span style="color: #45b3e6;">L</span><span style="color: #109ab8;">&#125;</span>|T<span style="color: #109ab8;">&#93;</span><span style="color: #6bb810;">,</span><span style="color: #45b3e6;">Acc</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #ff3c00;">matches</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">H</span><span style="color: #6bb810;">,</span><span style="color: #45b3e6;">T</span><span style="color: #6bb810;">,</span><span style="color: #109ab8;">&#91;</span><span style="color: #ff4e18;">lists</span>:<span style="color: #ff3c00;">sublist</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">H</span><span style="color: #6bb810;">,</span><span style="color: #45b3e6;">I</span><span style="color: #6bb810;">,</span><span style="color: #45b3e6;">L</span><span style="color: #109ab8;">&#41;</span>|Acc<span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #ff3c00;">words</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">String</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span> <span style="color: #ff3c00;">matches</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">String</span><span style="color: #6bb810;">,</span><span style="color: #ff4e18;">regexp</span>:<span style="color: #ff3c00;">matches</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">String</span><span style="color: #6bb810;">,</span> <span style="color: #ff7800;">&quot;[A-Za-z0-1]+&quot;</span><span style="color: #109ab8;">&#41;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
&nbsp;
&nbsp;
<span style="color: #666666; font-style: italic;">%% builds a tree of word/count pairs.  If the word does not exist in </span>
<span style="color: #666666; font-style: italic;">%% the tree it is added with an initial value of 1.  If the word does</span>
<span style="color: #666666; font-style: italic;">%% exist the count is retrieved and incremented</span>
<span style="color: #ff3c00;">build_word_tree</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#91;</span><span style="color: #109ab8;">&#93;</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Tree</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span> <span style="color: #45b3e6;">Tree</span><span style="color: #6bb810;">;</span>
<span style="color: #ff3c00;">build_word_tree</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#91;</span><span style="color: #45b3e6;">W</span>|R<span style="color: #109ab8;">&#93;</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Tree</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
	<span style="color: #186895;">case</span> <span style="color: #ff4e18;">gb_trees</span>:<span style="color: #ff3c00;">is_defined</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">W</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Tree</span><span style="color: #109ab8;">&#41;</span> <span style="color: #186895;">of</span>
		true <span style="color: #6bb810;">-&gt;</span>
			<span style="color: #45b3e6;">Count</span> <span style="color: #014ea4;">=</span> <span style="color: #ff4e18;">gb_trees</span>:<span style="color: #ff3c00;">get</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">W</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Tree</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
			<span style="color: #45b3e6;">NewTree</span> <span style="color: #014ea4;">=</span> <span style="color: #ff4e18;">gb_trees</span>:<span style="color: #ff3c00;">update</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">W</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Count</span> <span style="color: #014ea4;">+</span> <span style="color: #ff9600;">1</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Tree</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
			<span style="color: #ff3c00;">build_word_tree</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">R</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">NewTree</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">;</span>
		false <span style="color: #6bb810;">-&gt;</span>
			<span style="color: #45b3e6;">NewTree</span> <span style="color: #014ea4;">=</span> <span style="color: #ff4e18;">gb_trees</span>:<span style="color: #ff3c00;">insert</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">W</span><span style="color: #6bb810;">,</span> <span style="color: #ff9600;">1</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Tree</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
			<span style="color: #ff3c00;">build_word_tree</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">R</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">NewTree</span><span style="color: #109ab8;">&#41;</span>
	<span style="color: #186895;">end</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #666666; font-style: italic;">%% reads the next line from the file.  If there is data then...</span>
<span style="color: #666666; font-style: italic;">%% split the data into a list of words and add those to the word tree</span>
<span style="color: #ff3c00;">process_each_line</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">IoDevice</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Tree</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
	<span style="color: #186895;">case</span> <span style="color: #ff4e18;">io</span>:<span style="color: #ff3c00;">get_line</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">IoDevice</span><span style="color: #6bb810;">,</span> <span style="color: #ff7800;">&quot;&quot;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #186895;">of</span>
		eof <span style="color: #6bb810;">-&gt;</span> 
			<span style="color: #ff4e18;">file</span>:<span style="color: #ff3c00;">close</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">IoDevice</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
			<span style="color: #45b3e6;">Tree</span><span style="color: #6bb810;">;</span>
		<span style="color: #109ab8;">&#123;</span>error<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Reason</span><span style="color: #109ab8;">&#125;</span> <span style="color: #6bb810;">-&gt;</span>
			<span style="color: #ff4e18;">file</span>:<span style="color: #ff3c00;">close</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">IoDevice</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
			<span style="color: #ff3c00;">throw</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Reason</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">;</span>
		<span style="color: #45b3e6;">Data</span> <span style="color: #6bb810;">-&gt;</span>
			<span style="color: #45b3e6;">NewTree</span> <span style="color: #014ea4;">=</span> <span style="color: #ff3c00;">build_word_tree</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff3c00;">words</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Data</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Tree</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
			<span style="color: #ff3c00;">process_each_line</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">IoDevice</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">NewTree</span><span style="color: #109ab8;">&#41;</span>
	<span style="color: #186895;">end</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #666666; font-style: italic;">%% walks the gb_tree and prints each word/count pair</span>
<span style="color: #ff3c00;">print_tree</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Iter</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
	<span style="color: #186895;">case</span> <span style="color: #ff4e18;">gb_trees</span>:<span style="color: #ff3c00;">next</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Iter</span><span style="color: #109ab8;">&#41;</span> <span style="color: #186895;">of</span>
		none <span style="color: #6bb810;">-&gt;</span> <span style="color: #006600;">ok</span><span style="color: #6bb810;">;</span>
		<span style="color: #109ab8;">&#123;</span><span style="color: #45b3e6;">Key</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Val</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">NewIter</span><span style="color: #109ab8;">&#125;</span> <span style="color: #6bb810;">-&gt;</span>
			<span style="color: #ff4e18;">io</span>:<span style="color: #ff3c00;">format</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff7800;">&quot;~s: ~w~n&quot;</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span><span style="color: #45b3e6;">Key</span><span style="color: #6bb810;">,</span><span style="color: #45b3e6;">Val</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
			<span style="color: #ff3c00;">print_tree</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">NewIter</span><span style="color: #109ab8;">&#41;</span>
	<span style="color: #186895;">end</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #666666; font-style: italic;">%% opens the indicated file, processes the contents and prints</span>
<span style="color: #666666; font-style: italic;">%% out the word/count pairs to stdout</span>
<span style="color: #ff3c00;">print_word_counts</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Filename</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
	<span style="color: #186895;">case</span> <span style="color: #ff4e18;">file</span>:<span style="color: #ff3c00;">open</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Filename</span><span style="color: #6bb810;">,</span> read<span style="color: #109ab8;">&#41;</span> <span style="color: #186895;">of</span>
		<span style="color: #109ab8;">&#123;</span>ok<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">IoDevice</span><span style="color: #109ab8;">&#125;</span> <span style="color: #6bb810;">-&gt;</span>
			<span style="color: #45b3e6;">Tree</span> <span style="color: #014ea4;">=</span> <span style="color: #ff3c00;">process_each_line</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">IoDevice</span><span style="color: #6bb810;">,</span> <span style="color: #ff4e18;">gb_trees</span>:<span style="color: #ff3c00;">empty</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#41;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
			<span style="color: #ff3c00;">print_tree</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff4e18;">gb_trees</span>:<span style="color: #ff3c00;">iterator</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Tree</span><span style="color: #109ab8;">&#41;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">;</span>
		<span style="color: #109ab8;">&#123;</span>error<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Reason</span><span style="color: #109ab8;">&#125;</span> <span style="color: #6bb810;">-&gt;</span>
			<span style="color: #ff4e18;">io</span>:<span style="color: #ff3c00;">format</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff7800;">&quot;~s~n&quot;</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span><span style="color: #45b3e6;">Reason</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span>
	<span style="color: #186895;">end</span><span style="color: #6bb810;">.</span></pre></div></div>

<p>As usual &#8211; I&#8217;m just getting started with Erlang.  What is the good, bad and ugly with this code?</p>



Share and Enjoy:


	<a rel="nofollow" id="print" href="javascript:window.location='http%3A%2F%2Fwww.printfriendly.com%2Fprint%3Furl%3Dhttp%253A%252F%252Fwww.roberthorvick.com%252F2009%252F07%252F02%252Ffinding-word-frequencies-using-erlang%252F%26amp%3Bpartner%3Dsociable';" title="Print this article!"><img src="http://www.roberthorvick.com/wp-content/plugins/sociable/images/printfriendly.png" title="Print this article!" alt="Print this article!" class="sociable-hovers" /></a>
	<a rel="nofollow" id="twitter" href="javascript:window.location='http%3A%2F%2Ftwitter.com%2Fhome%3Fstatus%3DFinding%2520word%2520frequencies%2520using%2520Erlang%2520-%2520http%253A%252F%252Fwww.roberthorvick.com%252F2009%252F07%252F02%252Ffinding-word-frequencies-using-erlang%252F';" title="Twitter"><img src="http://www.roberthorvick.com/wp-content/plugins/sociable/images/twitter.png" title="Twitter" alt="Twitter" class="sociable-hovers" /></a>
	<a rel="nofollow" id="digg" href="javascript:window.location='http%3A%2F%2Fdigg.com%2Fsubmit%3Fphase%3D2%26amp%3Burl%3Dhttp%253A%252F%252Fwww.roberthorvick.com%252F2009%252F07%252F02%252Ffinding-word-frequencies-using-erlang%252F%26amp%3Btitle%3DFinding%2520word%2520frequencies%2520using%2520Erlang%26amp%3Bbodytext%3DHere%2527s%2520a%2520follow-up%2520post%2520that%2520provides%2520a%2520better%2520implementation.%250D%250A%250D%250AI%2520wanted%2520to%2520try%2520and%2520bite%2520off%2520something%2520a%2520little%2520larger%2520today%2520hitting%2520a%2520few%2520areas%2520that%2520seem%2520generally%2520useful%253A%250D%250A%250D%250A%2509Basic%2520text%2520file%2520operations%250D%250A%2509Basic%2520string%2520operations%250D%250A%2509Using%2520the%2520gb_tre';" title="Digg"><img src="http://www.roberthorvick.com/wp-content/plugins/sociable/images/digg.png" title="Digg" alt="Digg" class="sociable-hovers" /></a>
	<a rel="nofollow" id="reddit" href="javascript:window.location='http%3A%2F%2Freddit.com%2Fsubmit%3Furl%3Dhttp%253A%252F%252Fwww.roberthorvick.com%252F2009%252F07%252F02%252Ffinding-word-frequencies-using-erlang%252F%26amp%3Btitle%3DFinding%2520word%2520frequencies%2520using%2520Erlang';" title="Reddit"><img src="http://www.roberthorvick.com/wp-content/plugins/sociable/images/reddit.png" title="Reddit" alt="Reddit" class="sociable-hovers" /></a>
	<a rel="nofollow" id="del.icio.us" href="javascript:window.location='http%3A%2F%2Fdelicious.com%2Fpost%3Furl%3Dhttp%253A%252F%252Fwww.roberthorvick.com%252F2009%252F07%252F02%252Ffinding-word-frequencies-using-erlang%252F%26amp%3Btitle%3DFinding%2520word%2520frequencies%2520using%2520Erlang%26amp%3Bnotes%3DHere%2527s%2520a%2520follow-up%2520post%2520that%2520provides%2520a%2520better%2520implementation.%250D%250A%250D%250AI%2520wanted%2520to%2520try%2520and%2520bite%2520off%2520something%2520a%2520little%2520larger%2520today%2520hitting%2520a%2520few%2520areas%2520that%2520seem%2520generally%2520useful%253A%250D%250A%250D%250A%2509Basic%2520text%2520file%2520operations%250D%250A%2509Basic%2520string%2520operations%250D%250A%2509Using%2520the%2520gb_tre';" title="del.icio.us"><img src="http://www.roberthorvick.com/wp-content/plugins/sociable/images/delicious.png" title="del.icio.us" alt="del.icio.us" class="sociable-hovers" /></a>
	<a rel="nofollow" id="facebook" href="javascript:window.location='http%3A%2F%2Fwww.facebook.com%2Fshare.php%3Fu%3Dhttp%253A%252F%252Fwww.roberthorvick.com%252F2009%252F07%252F02%252Ffinding-word-frequencies-using-erlang%252F%26amp%3Bt%3DFinding%2520word%2520frequencies%2520using%2520Erlang';" title="Facebook"><img src="http://www.roberthorvick.com/wp-content/plugins/sociable/images/facebook.png" title="Facebook" alt="Facebook" class="sociable-hovers" /></a>
	<a rel="nofollow" id="google" href="javascript:window.location='http%3A%2F%2Fwww.google.com%2Fbookmarks%2Fmark%3Fop%3Dedit%26amp%3Bbkmk%3Dhttp%253A%252F%252Fwww.roberthorvick.com%252F2009%252F07%252F02%252Ffinding-word-frequencies-using-erlang%252F%26amp%3Btitle%3DFinding%2520word%2520frequencies%2520using%2520Erlang%26amp%3Bannotation%3DHere%2527s%2520a%2520follow-up%2520post%2520that%2520provides%2520a%2520better%2520implementation.%250D%250A%250D%250AI%2520wanted%2520to%2520try%2520and%2520bite%2520off%2520something%2520a%2520little%2520larger%2520today%2520hitting%2520a%2520few%2520areas%2520that%2520seem%2520generally%2520useful%253A%250D%250A%250D%250A%2509Basic%2520text%2520file%2520operations%250D%250A%2509Basic%2520string%2520operations%250D%250A%2509Using%2520the%2520gb_tre';" title="Google Bookmarks"><img src="http://www.roberthorvick.com/wp-content/plugins/sociable/images/googlebookmark.png" title="Google Bookmarks" alt="Google Bookmarks" class="sociable-hovers" /></a>
	<a rel="nofollow" id="stumbleupon" href="javascript:window.location='http%3A%2F%2Fwww.stumbleupon.com%2Fsubmit%3Furl%3Dhttp%253A%252F%252Fwww.roberthorvick.com%252F2009%252F07%252F02%252Ffinding-word-frequencies-using-erlang%252F%26amp%3Btitle%3DFinding%2520word%2520frequencies%2520using%2520Erlang';" title="StumbleUpon"><img src="http://www.roberthorvick.com/wp-content/plugins/sociable/images/stumbleupon.png" title="StumbleUpon" alt="StumbleUpon" class="sociable-hovers" /></a>


<br/><br/>]]></content:encoded>
			<wfw:commentRss>http://www.roberthorvick.com/2009/07/02/finding-word-frequencies-using-erlang/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Aha Moments &#8211; gb_trees:update and thinking in Erlang</title>
		<link>http://www.roberthorvick.com/2009/07/01/aha-moments-gb_treesupdate-and-thinking-in-erlang/</link>
		<comments>http://www.roberthorvick.com/2009/07/01/aha-moments-gb_treesupdate-and-thinking-in-erlang/#comments</comments>
		<pubDate>Wed, 01 Jul 2009 06:07:14 +0000</pubDate>
		<dc:creator>robert</dc:creator>
				<category><![CDATA[Erlang]]></category>

		<guid isPermaLink="false">http://www.roberthorvick.com/?p=25</guid>
		<description><![CDATA[The first episode of The X-Files I ever saw was the Home.  I was hooked immediately &#8211; and at the same time somewhat disappointed.  This was before on-demand TV, hulu or DVD compilations on NetFlix.  I had missed more than 3 seasons of a what was clearly going to be one of my favorite shows [...]]]></description>
			<content:encoded><![CDATA[<p>The first episode of The <a href="http://en.wikipedia.org/wiki/The_X-Files">X-Files</a> I ever saw was the <a href="http://en.wikipedia.org/wiki/Home_%28The_X-Files%29">Home</a>.  I was hooked immediately &#8211; and at the same time somewhat disappointed.  This was before on-demand TV, hulu or DVD compilations on NetFlix.  I had missed more than 3 seasons of a what was clearly going to be one of my favorite shows and there the only way to catch up was the hope that the next rerun would be one I hadn&#8217;t seen.  Then it got all weird and aliens were showing up too often, Mulder basically disappeared and The Lone Gunman got their own spinoff &#8230;</p>
<p>Learning Erlang is a little like seeing the first episode.  I&#8217;m hooked immediately &#8211; and at the same time somewhat disappointed.  I&#8217;m years behind again.  At least this time I don&#8217;t need to fret over not being able to find the reruns I want and there is very little risk that <a href="http://www.deanhaglund.com/">Dean Haglund</a> will make an appearance (I bet Langly knew Erlang).</p>
<p>A few minutes ago I had my first significant Aha! moment.  In my effort to map what I do know (procedural/OO paradigms) to Erlang I wondered &#8220;how would a balance tree be implemented in Erlang&#8221;.  I binged (yeah, I said it) for &#8220;<a href="http://www.bing.com/search?q=Erlang+balanced+trees">Erlang balanced trees</a>&#8221; and quickly found the <a href="http://www.erlang.org/doc/man/gb_trees.html">gb_trees</a> module.</p>
<p>What I wanted to understand was:</p>
<ol>
<li>How is the tree represented in Erlang?</li>
<li>How is the tree (and it&#8217;s nodes) modified (insert, update, delete, etc)?</li>
<li>Can processes share the same tree (and how is concurrency handled)?</li>
</ol>
<h2>How is the tree represented in Erlang?</h2>
<p>This took me the longest to understand &#8211; but once it fell into place everything else made so much more sense.  If you are curious go ahead and open up gb_trees.erl (on my machine it&#8217;s in /usr/lib/erlang/lib/stdlib-1.15.5/src) &#8211; now go to the definition of the node and tree types.  Go ahead&#8230; I&#8217;ll wait.</p>
<p>Found them yet?  No?  Maybe it&#8217;s in some header file.  Feel free to check &#8230; in the meantime I&#8217;ll continue.</p>
<p>Ready for this?  There isn&#8217;t one.  You don&#8217;t need to define a tree or node type &#8211; it&#8217;s just a tuple that gets passed around and interpreted at runtime.  Not quite clear?  OK &#8211; if we were going to define it, it would look something like this:</p>
<p><code>{Size, {Key, Value, Smaller, Bigger}}</code></p>
<ul>
<li><strong>Size</strong> is the number of nodes in the tree (which is used for balancing).</li>
<li><strong>Key</strong> is the key of the current node.</li>
<li><strong>Value</strong> is the value associated with Key.</li>
<li><strong>Smaller</strong> is the nodes that are smaller (i.e. &#8220;to the left&#8221;).</li>
<li><strong>Bigger</strong> is nodes that are bigger (&#8221;to the right&#8221;).</li>
</ul>
<p>These functions really helped make it much clearer:</p>

<div class="wp_syntax"><div class="code"><pre class="erlang" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">%%-spec(empty/0 :: () -&gt; gb_tree()).</span>
&nbsp;
<span style="color: #ff3c00;">empty</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #109ab8;">&#123;</span><span style="color: #ff9600;">0</span><span style="color: #6bb810;">,</span> nil<span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #666666; font-style: italic;">%%-spec(is_empty/1 :: (gb_tree()) -&gt; bool()).</span>
&nbsp;
<span style="color: #ff3c00;">is_empty</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#123;</span><span style="color: #ff9600;">0</span><span style="color: #6bb810;">,</span> nil<span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #006600;">true</span><span style="color: #6bb810;">;</span>
<span style="color: #ff3c00;">is_empty</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">_</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #006600;">false</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #666666; font-style: italic;">%%-spec(size/1 :: (gb_tree()) -&gt; non_neg_integer()).</span>
&nbsp;
<span style="color: #ff3c00;">size</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#123;</span><span style="color: #45b3e6;">Size</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">_</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #186895;">when</span> <span style="color: #ff3c00;">is_integer</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Size</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Size</span> <span style="color: #014ea4;">&gt;=</span> <span style="color: #ff9600;">0</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #45b3e6;">Size</span><span style="color: #6bb810;">.</span></pre></div></div>

<p>&#8220;size&#8221; says so much it&#8217;s wonderful.  Besides the obvious of getting the size of the tree it also validates that the size is greater-than-or-equal-to zero otherwise there will be an exception.  This is a great example of Erlang failing fast.  Try it out:</p>
<pre>2&gt; gb_trees:size({-1, {[]}}).
** exception error: no function clause matching gb_trees:size({-1,{[]}})</pre>
<p>See &#8211; the clause doesn&#8217;t match and an exception is thrown.  Think of the comparable C++ code.  It would look something like:</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">int</span> size<span style="color: #008000;">&#40;</span>Tree <span style="color: #000040;">*</span>tree<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>tree <span style="color: #000080;">==</span> null<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
        <span style="color: #0000ff;">throw</span> ...<span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span>tree<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>size <span style="color: #000080;">&lt;</span> <span style="color: #0000dd;">0</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
        <span style="color: #0000ff;">throw</span> ...<span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #0000ff;">return</span> tree<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>size<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

<p><img class="size-medium wp-image-26" title="I'm lovin it!" src="http://www.roberthorvick.com/wp-content/uploads/2009/07/lovinit-300x290.jpg" alt="I'm Loving It" width="300" height="290" /></p>
<h2>How is the tree modified?</h2>
<p>I think gb_trees:update is the most approachable example of this.  Besides being crazy small it is a very clear example of how the tree is walked to search for the key and how error handling is meant to be done.</p>

<div class="wp_syntax"><div class="code"><pre class="erlang" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">%%-spec(update/3 :: (_, _, gb_tree()) -&gt; gb_tree()).</span>
&nbsp;
<span style="color: #ff3c00;">update</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Key</span><span style="color: #6bb810;">,</span>  <span style="color: #45b3e6;">Val</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#123;</span><span style="color: #45b3e6;">S</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">T</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #45b3e6;">T1</span> <span style="color: #014ea4;">=</span> <span style="color: #ff3c00;">update_1</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Key</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Val</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">T</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
    <span style="color: #109ab8;">&#123;</span><span style="color: #45b3e6;">S</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">T1</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #666666; font-style: italic;">%% See `lookup' for notes on the term comparison order.</span>
&nbsp;
<span style="color: #ff3c00;">update_1</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Key</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Value</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#123;</span><span style="color: #45b3e6;">Key1</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">V</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Smaller</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Bigger</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #186895;">when</span> <span style="color: #45b3e6;">Key</span> <span style="color: #014ea4;">&lt;</span> <span style="color: #45b3e6;">Key1</span> <span style="color: #6bb810;">-&gt;</span> 
    <span style="color: #109ab8;">&#123;</span><span style="color: #45b3e6;">Key1</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">V</span><span style="color: #6bb810;">,</span> <span style="color: #ff3c00;">update_1</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Key</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Value</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Smaller</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Bigger</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">;</span>
<span style="color: #ff3c00;">update_1</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Key</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Value</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#123;</span><span style="color: #45b3e6;">Key1</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">V</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Smaller</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Bigger</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #186895;">when</span> <span style="color: #45b3e6;">Key</span> <span style="color: #014ea4;">&gt;</span> <span style="color: #45b3e6;">Key1</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #109ab8;">&#123;</span><span style="color: #45b3e6;">Key1</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">V</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Smaller</span><span style="color: #6bb810;">,</span> <span style="color: #ff3c00;">update_1</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Key</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Value</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Bigger</span><span style="color: #109ab8;">&#41;</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">;</span>
<span style="color: #ff3c00;">update_1</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Key</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Value</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#123;</span><span style="color: #45b3e6;">_</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">_</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Smaller</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Bigger</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #109ab8;">&#123;</span><span style="color: #45b3e6;">Key</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Value</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Smaller</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Bigger</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">.</span></pre></div></div>

<p>Notice first that since update is never changing the size it does not bother to pass it to update_1 &#8211; only the &#8220;node&#8221; portion of the tuple is passed.</p>
<p>Once passed there are four possible options &#8211; three of which need to be codified (in the same order as the code):</p>
<ol>
<li>The provided key is smaller than the current tree node.  In this case build up a new result and call update_1 with update_1(Key, Value, Smaller) &#8211; &#8220;walk left&#8221;</li>
<li>The provided key is larger than the current tree node.  Walk right.</li>
<li>The provided key is exactly the current node key (not too big &#8230; not to small &#8230; just right!).  In this case build up a new node with the new value.</li>
<li>(implicit) The provided key is not in the tree.  Throw an exception.</li>
</ol>
<p>In the case where the node is not found update_1 ends up being called like:</p>
<p>update_1(Key, Value, nil)</p>
<p>Since the match on #1-3 require a non-nil tuple this turns into a missing function clause error.</p>
<h2>Can processes share the same tree?</h2>
<p>No.  No they can&#8217;t.  I was having a little trouble groking this until I ran through some samples in erl.  This is what made it clear for me:</p>
<p><code><br />
1&gt; Tree = gb_trees:empty().<br />
{0,nil}<br />
2&gt; Tree2 = gb_trees:insert("Foo", "Bar", Tree).<br />
{1,{"Foo","Bar",nil,nil}}<br />
3&gt; Tree3 = gb_trees:update("Foo", "NewBar", Tree2).<br />
{1,{"Foo","NewBar",nil,nil}}<br />
4&gt; Tree4 = gb_trees:update("Missing", "value", Tree3).<br />
** exception error: no function clause matching gb_trees:update_1("Missing","value",nil)<br />
in function  gb_trees:update_1/3<br />
in call from gb_trees:update/3</code></p>
<p>Each time anything was done a new tree was created &#8211; the old tree was still valid and could be used but it was not the new tree.  It&#8217;s the old tree.  This boggled me for a few minutes until <a href="https://twitter.com/justinsheehy">Justin Sheehy</a> confirmed what the code was saying.</p>
<p><img class="size-full wp-image-27" title="thanks-justin" src="http://www.roberthorvick.com/wp-content/uploads/2009/07/thanks-justin.png" alt="@bubbafat They are immutable data structures. In functional programming, &quot;update&quot; is nondestructive" width="339" height="208" /></p>
<p>So no &#8211; multiple processes could not possibly share the tree because the tree is immutable.</p>
<p>Want proof?  Go back to erl and run gb_trees:get on the key &#8220;Foo&#8221; on Tree, Tree2 and Tree3.  Tree will error (it&#8217;s an empty tree).  Tree2 will find &#8220;Bar&#8221; and Tree3 will find &#8220;NewBar&#8221;.</p>
<p><code><br />
14&gt; gb_trees:get("Foo", Tree).<br />
** exception error: no function clause matching gb_trees:get_1("Foo",nil)<br />
15&gt; gb_trees:get("Foo", Tree2).<br />
"Bar"<br />
16&gt; gb_trees:get("Foo", Tree3).<br />
"NewBar"</code></p>
<p style="font-size:xx-large;"><strong>Aha!</strong></p>



Share and Enjoy:


	<a rel="nofollow" id="print" href="javascript:window.location='http%3A%2F%2Fwww.printfriendly.com%2Fprint%3Furl%3Dhttp%253A%252F%252Fwww.roberthorvick.com%252F2009%252F07%252F01%252Faha-moments-gb_treesupdate-and-thinking-in-erlang%252F%26amp%3Bpartner%3Dsociable';" title="Print this article!"><img src="http://www.roberthorvick.com/wp-content/plugins/sociable/images/printfriendly.png" title="Print this article!" alt="Print this article!" class="sociable-hovers" /></a>
	<a rel="nofollow" id="twitter" href="javascript:window.location='http%3A%2F%2Ftwitter.com%2Fhome%3Fstatus%3DAha%2520Moments%2520-%2520gb_trees%253Aupdate%2520and%2520thinking%2520in%2520Erlang%2520-%2520http%253A%252F%252Fwww.roberthorvick.com%252F2009%252F07%252F01%252Faha-moments-gb_treesupdate-and-thinking-in-erlang%252F';" title="Twitter"><img src="http://www.roberthorvick.com/wp-content/plugins/sociable/images/twitter.png" title="Twitter" alt="Twitter" class="sociable-hovers" /></a>
	<a rel="nofollow" id="digg" href="javascript:window.location='http%3A%2F%2Fdigg.com%2Fsubmit%3Fphase%3D2%26amp%3Burl%3Dhttp%253A%252F%252Fwww.roberthorvick.com%252F2009%252F07%252F01%252Faha-moments-gb_treesupdate-and-thinking-in-erlang%252F%26amp%3Btitle%3DAha%2520Moments%2520-%2520gb_trees%253Aupdate%2520and%2520thinking%2520in%2520Erlang%26amp%3Bbodytext%3DThe%2520first%2520episode%2520of%2520The%2520X-Files%2520I%2520ever%2520saw%2520was%2520the%2520Home.%25C2%25A0%2520I%2520was%2520hooked%2520immediately%2520-%2520and%2520at%2520the%2520same%2520time%2520somewhat%2520disappointed.%25C2%25A0%2520This%2520was%2520before%2520on-demand%2520TV%252C%2520hulu%2520or%2520DVD%2520compilations%2520on%2520NetFlix.%25C2%25A0%2520I%2520had%2520missed%2520more%2520than%25203%2520seasons%2520of%2520a%2520what%2520was%2520c';" title="Digg"><img src="http://www.roberthorvick.com/wp-content/plugins/sociable/images/digg.png" title="Digg" alt="Digg" class="sociable-hovers" /></a>
	<a rel="nofollow" id="reddit" href="javascript:window.location='http%3A%2F%2Freddit.com%2Fsubmit%3Furl%3Dhttp%253A%252F%252Fwww.roberthorvick.com%252F2009%252F07%252F01%252Faha-moments-gb_treesupdate-and-thinking-in-erlang%252F%26amp%3Btitle%3DAha%2520Moments%2520-%2520gb_trees%253Aupdate%2520and%2520thinking%2520in%2520Erlang';" title="Reddit"><img src="http://www.roberthorvick.com/wp-content/plugins/sociable/images/reddit.png" title="Reddit" alt="Reddit" class="sociable-hovers" /></a>
	<a rel="nofollow" id="del.icio.us" href="javascript:window.location='http%3A%2F%2Fdelicious.com%2Fpost%3Furl%3Dhttp%253A%252F%252Fwww.roberthorvick.com%252F2009%252F07%252F01%252Faha-moments-gb_treesupdate-and-thinking-in-erlang%252F%26amp%3Btitle%3DAha%2520Moments%2520-%2520gb_trees%253Aupdate%2520and%2520thinking%2520in%2520Erlang%26amp%3Bnotes%3DThe%2520first%2520episode%2520of%2520The%2520X-Files%2520I%2520ever%2520saw%2520was%2520the%2520Home.%25C2%25A0%2520I%2520was%2520hooked%2520immediately%2520-%2520and%2520at%2520the%2520same%2520time%2520somewhat%2520disappointed.%25C2%25A0%2520This%2520was%2520before%2520on-demand%2520TV%252C%2520hulu%2520or%2520DVD%2520compilations%2520on%2520NetFlix.%25C2%25A0%2520I%2520had%2520missed%2520more%2520than%25203%2520seasons%2520of%2520a%2520what%2520was%2520c';" title="del.icio.us"><img src="http://www.roberthorvick.com/wp-content/plugins/sociable/images/delicious.png" title="del.icio.us" alt="del.icio.us" class="sociable-hovers" /></a>
	<a rel="nofollow" id="facebook" href="javascript:window.location='http%3A%2F%2Fwww.facebook.com%2Fshare.php%3Fu%3Dhttp%253A%252F%252Fwww.roberthorvick.com%252F2009%252F07%252F01%252Faha-moments-gb_treesupdate-and-thinking-in-erlang%252F%26amp%3Bt%3DAha%2520Moments%2520-%2520gb_trees%253Aupdate%2520and%2520thinking%2520in%2520Erlang';" title="Facebook"><img src="http://www.roberthorvick.com/wp-content/plugins/sociable/images/facebook.png" title="Facebook" alt="Facebook" class="sociable-hovers" /></a>
	<a rel="nofollow" id="google" href="javascript:window.location='http%3A%2F%2Fwww.google.com%2Fbookmarks%2Fmark%3Fop%3Dedit%26amp%3Bbkmk%3Dhttp%253A%252F%252Fwww.roberthorvick.com%252F2009%252F07%252F01%252Faha-moments-gb_treesupdate-and-thinking-in-erlang%252F%26amp%3Btitle%3DAha%2520Moments%2520-%2520gb_trees%253Aupdate%2520and%2520thinking%2520in%2520Erlang%26amp%3Bannotation%3DThe%2520first%2520episode%2520of%2520The%2520X-Files%2520I%2520ever%2520saw%2520was%2520the%2520Home.%25C2%25A0%2520I%2520was%2520hooked%2520immediately%2520-%2520and%2520at%2520the%2520same%2520time%2520somewhat%2520disappointed.%25C2%25A0%2520This%2520was%2520before%2520on-demand%2520TV%252C%2520hulu%2520or%2520DVD%2520compilations%2520on%2520NetFlix.%25C2%25A0%2520I%2520had%2520missed%2520more%2520than%25203%2520seasons%2520of%2520a%2520what%2520was%2520c';" title="Google Bookmarks"><img src="http://www.roberthorvick.com/wp-content/plugins/sociable/images/googlebookmark.png" title="Google Bookmarks" alt="Google Bookmarks" class="sociable-hovers" /></a>
	<a rel="nofollow" id="stumbleupon" href="javascript:window.location='http%3A%2F%2Fwww.stumbleupon.com%2Fsubmit%3Furl%3Dhttp%253A%252F%252Fwww.roberthorvick.com%252F2009%252F07%252F01%252Faha-moments-gb_treesupdate-and-thinking-in-erlang%252F%26amp%3Btitle%3DAha%2520Moments%2520-%2520gb_trees%253Aupdate%2520and%2520thinking%2520in%2520Erlang';" title="StumbleUpon"><img src="http://www.roberthorvick.com/wp-content/plugins/sociable/images/stumbleupon.png" title="StumbleUpon" alt="StumbleUpon" class="sociable-hovers" /></a>


<br/><br/>]]></content:encoded>
			<wfw:commentRss>http://www.roberthorvick.com/2009/07/01/aha-moments-gb_treesupdate-and-thinking-in-erlang/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Converting the Erlang directory walker to multi-process design</title>
		<link>http://www.roberthorvick.com/2009/06/29/converting-the-erlang-directory-walker-to-multi-process-design/</link>
		<comments>http://www.roberthorvick.com/2009/06/29/converting-the-erlang-directory-walker-to-multi-process-design/#comments</comments>
		<pubDate>Tue, 30 Jun 2009 00:30:12 +0000</pubDate>
		<dc:creator>robert</dc:creator>
				<category><![CDATA[Erlang]]></category>

		<guid isPermaLink="false">http://www.roberthorvick.com/?p=16</guid>
		<description><![CDATA[In my previous post I wrote a simple file system walker using Erlang for the purposes of getting my head around the syntax.  To start thinking more in an Erlang mindset (though in a very contrived manner) in this post I convert the file system walker to use two processes.  The first process (&#8221;walk&#8221;) performs [...]]]></description>
			<content:encoded><![CDATA[<p>In my <a href="http://www.roberthorvick.com/2009/06/29/walking-the-directory-tree-in-erlang/">previous post</a> I wrote a simple file system walker using Erlang for the purposes of getting my head around the syntax.  To start thinking more in an Erlang mindset (though in a <i>very</i> contrived manner) in this post I convert the file system walker to use two processes.  The first process (&#8221;walk&#8221;) performs the file system walking and the second (&#8221;visit&#8221;) processes each found item (i.e. prints the full item path name).</p>
<p>Something along the lines of this&#8230;</p>
<p><img class="aligncenter size-full wp-image-18" title="walk-visit" src="http://www.roberthorvick.com/wp-content/uploads/2009/06/walk-visit1.png" alt="walk-visit" width="411" height="195" /></p>
<p>Since walk and visit are the process entry points they need to be in the export list (by the way &#8211; forgetting to do this does not cause a compiler error in erl &#8211; why is that?) and we need a new entry function to create the new processes (start/1).</p>

<div class="wp_syntax"><div class="code"><pre class="erlang" style="font-family:monospace;"><span style="color: #ff3c00;">start</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Path</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
	<span style="color: #45b3e6;">Visit_PID</span> <span style="color: #014ea4;">=</span> <span style="color: #ff3c00;">spawn</span><span style="color: #109ab8;">&#40;</span>walkproc<span style="color: #6bb810;">,</span> visit<span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
	<span style="color: #ff3c00;">spawn</span><span style="color: #109ab8;">&#40;</span>walkproc<span style="color: #6bb810;">,</span> walk<span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span><span style="color: #45b3e6;">Path</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Visit_PID</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span></pre></div></div>

<p>On line 2 we create the process whose pid is assigned to Visit_PID.  This process calls the visit() function with 0 parameters.  At this point visit is running and waiting to receive a message.</p>
<p>On line 3 we spawn off another process.  This process calls the walk/2 function as walk(Path, Visit_PID).  Since the walk function is doing the file system walking it makes sense that it will be the one sending the first message.  Because of this it needs to know the PID of the process to send the message to.</p>
<p>visit is a very straight forward function.  It receives a message, processes it, sends a response and recurses (rinse and repeat).</p>

<div class="wp_syntax"><div class="code"><pre class="erlang" style="font-family:monospace;"><span style="color: #ff3c00;">visit</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
	<span style="color: #186895;">receive</span>
		<span style="color: #109ab8;">&#123;</span><span style="color: #45b3e6;">Path</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Walk_PID</span><span style="color: #109ab8;">&#125;</span> <span style="color: #6bb810;">-&gt;</span>
			<span style="color: #ff4e18;">io</span>:<span style="color: #ff3c00;">format</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff7800;">&quot;~s~n&quot;</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span><span style="color: #45b3e6;">Path</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
			<span style="color: #45b3e6;">Walk_PID</span> <span style="color: #014ea4;">!</span> next<span style="color: #6bb810;">,</span>
			<span style="color: #ff3c00;">visit</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#41;</span>
	<span style="color: #186895;">end</span><span style="color: #6bb810;">.</span></pre></div></div>

<p>walk is very similar (and has not changed substantially from our previous version.  it starts by firing a message off to visit with the Path passed as a parameter.  Next it waits for the &#8220;next&#8221; message.  Once it receives that it gets the next file system entry and recurses.</p>

<div class="wp_syntax"><div class="code"><pre class="erlang" style="font-family:monospace;"><span style="color: #ff3c00;">walk</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Path</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Visit_PID</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
	<span style="color: #45b3e6;">Visit_PID</span> <span style="color: #014ea4;">!</span> <span style="color: #109ab8;">&#123;</span><span style="color: #45b3e6;">Path</span><span style="color: #6bb810;">,</span> <span style="color: #ff3c00;">self</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#41;</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">,</span>
	<span style="color: #186895;">receive</span>
		next <span style="color: #6bb810;">-&gt;</span>
			<span style="color: #45b3e6;">FileType</span> <span style="color: #014ea4;">=</span> <span style="color: #ff3c00;">file_type</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Path</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
			<span style="color: #186895;">case</span> <span style="color: #45b3e6;">FileType</span> <span style="color: #186895;">of</span>
				file <span style="color: #6bb810;">-&gt;</span>
					<span style="color: #006600;">ok</span><span style="color: #6bb810;">;</span>
				symlink <span style="color: #6bb810;">-&gt;</span>
					<span style="color: #006600;">ok</span><span style="color: #6bb810;">;</span>
				directory <span style="color: #6bb810;">-&gt;</span>
					<span style="color: #45b3e6;">Children</span> <span style="color: #014ea4;">=</span> <span style="color: #ff4e18;">filelib</span>:<span style="color: #ff3c00;">wildcard</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Path</span> <span style="color: #014ea4;">++</span> <span style="color: #ff7800;">&quot;/*&quot;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
					<span style="color: #ff4e18;">lists</span>:<span style="color: #ff3c00;">foreach</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff3c00;">fun</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">P</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span> <span style="color: #ff3c00;">walk</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">P</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Visit_PID</span><span style="color: #109ab8;">&#41;</span> <span style="color: #186895;">end</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Children</span><span style="color: #109ab8;">&#41;</span>
			<span style="color: #186895;">end</span>
	<span style="color: #186895;">end</span><span style="color: #6bb810;">.</span></pre></div></div>

<p>The other methods (file_type and is_symlink) have not changed.</p>
<p>I enjoyed how easy it was to convert to a multi-process approach and am looking forward to moving to a solution that uses RabbitMQ. </p>



Share and Enjoy:


	<a rel="nofollow" id="print" href="javascript:window.location='http%3A%2F%2Fwww.printfriendly.com%2Fprint%3Furl%3Dhttp%253A%252F%252Fwww.roberthorvick.com%252F2009%252F06%252F29%252Fconverting-the-erlang-directory-walker-to-multi-process-design%252F%26amp%3Bpartner%3Dsociable';" title="Print this article!"><img src="http://www.roberthorvick.com/wp-content/plugins/sociable/images/printfriendly.png" title="Print this article!" alt="Print this article!" class="sociable-hovers" /></a>
	<a rel="nofollow" id="twitter" href="javascript:window.location='http%3A%2F%2Ftwitter.com%2Fhome%3Fstatus%3DConverting%2520the%2520Erlang%2520directory%2520walker%2520to%2520multi-process%2520design%2520-%2520http%253A%252F%252Fwww.roberthorvick.com%252F2009%252F06%252F29%252Fconverting-the-erlang-directory-walker-to-multi-process-design%252F';" title="Twitter"><img src="http://www.roberthorvick.com/wp-content/plugins/sociable/images/twitter.png" title="Twitter" alt="Twitter" class="sociable-hovers" /></a>
	<a rel="nofollow" id="digg" href="javascript:window.location='http%3A%2F%2Fdigg.com%2Fsubmit%3Fphase%3D2%26amp%3Burl%3Dhttp%253A%252F%252Fwww.roberthorvick.com%252F2009%252F06%252F29%252Fconverting-the-erlang-directory-walker-to-multi-process-design%252F%26amp%3Btitle%3DConverting%2520the%2520Erlang%2520directory%2520walker%2520to%2520multi-process%2520design%26amp%3Bbodytext%3DIn%2520my%2520previous%2520post%2520I%2520wrote%2520a%2520simple%2520file%2520system%2520walker%2520using%2520Erlang%2520for%2520the%2520purposes%2520of%2520getting%2520my%2520head%2520around%2520the%2520syntax.%25C2%25A0%2520To%2520start%2520thinking%2520more%2520in%2520an%2520Erlang%2520mindset%2520%2528though%2520in%2520a%2520very%2520contrived%2520manner%2529%2520in%2520this%2520post%2520I%2520convert%2520the%2520file%2520system%2520walke';" title="Digg"><img src="http://www.roberthorvick.com/wp-content/plugins/sociable/images/digg.png" title="Digg" alt="Digg" class="sociable-hovers" /></a>
	<a rel="nofollow" id="reddit" href="javascript:window.location='http%3A%2F%2Freddit.com%2Fsubmit%3Furl%3Dhttp%253A%252F%252Fwww.roberthorvick.com%252F2009%252F06%252F29%252Fconverting-the-erlang-directory-walker-to-multi-process-design%252F%26amp%3Btitle%3DConverting%2520the%2520Erlang%2520directory%2520walker%2520to%2520multi-process%2520design';" title="Reddit"><img src="http://www.roberthorvick.com/wp-content/plugins/sociable/images/reddit.png" title="Reddit" alt="Reddit" class="sociable-hovers" /></a>
	<a rel="nofollow" id="del.icio.us" href="javascript:window.location='http%3A%2F%2Fdelicious.com%2Fpost%3Furl%3Dhttp%253A%252F%252Fwww.roberthorvick.com%252F2009%252F06%252F29%252Fconverting-the-erlang-directory-walker-to-multi-process-design%252F%26amp%3Btitle%3DConverting%2520the%2520Erlang%2520directory%2520walker%2520to%2520multi-process%2520design%26amp%3Bnotes%3DIn%2520my%2520previous%2520post%2520I%2520wrote%2520a%2520simple%2520file%2520system%2520walker%2520using%2520Erlang%2520for%2520the%2520purposes%2520of%2520getting%2520my%2520head%2520around%2520the%2520syntax.%25C2%25A0%2520To%2520start%2520thinking%2520more%2520in%2520an%2520Erlang%2520mindset%2520%2528though%2520in%2520a%2520very%2520contrived%2520manner%2529%2520in%2520this%2520post%2520I%2520convert%2520the%2520file%2520system%2520walke';" title="del.icio.us"><img src="http://www.roberthorvick.com/wp-content/plugins/sociable/images/delicious.png" title="del.icio.us" alt="del.icio.us" class="sociable-hovers" /></a>
	<a rel="nofollow" id="facebook" href="javascript:window.location='http%3A%2F%2Fwww.facebook.com%2Fshare.php%3Fu%3Dhttp%253A%252F%252Fwww.roberthorvick.com%252F2009%252F06%252F29%252Fconverting-the-erlang-directory-walker-to-multi-process-design%252F%26amp%3Bt%3DConverting%2520the%2520Erlang%2520directory%2520walker%2520to%2520multi-process%2520design';" title="Facebook"><img src="http://www.roberthorvick.com/wp-content/plugins/sociable/images/facebook.png" title="Facebook" alt="Facebook" class="sociable-hovers" /></a>
	<a rel="nofollow" id="google" href="javascript:window.location='http%3A%2F%2Fwww.google.com%2Fbookmarks%2Fmark%3Fop%3Dedit%26amp%3Bbkmk%3Dhttp%253A%252F%252Fwww.roberthorvick.com%252F2009%252F06%252F29%252Fconverting-the-erlang-directory-walker-to-multi-process-design%252F%26amp%3Btitle%3DConverting%2520the%2520Erlang%2520directory%2520walker%2520to%2520multi-process%2520design%26amp%3Bannotation%3DIn%2520my%2520previous%2520post%2520I%2520wrote%2520a%2520simple%2520file%2520system%2520walker%2520using%2520Erlang%2520for%2520the%2520purposes%2520of%2520getting%2520my%2520head%2520around%2520the%2520syntax.%25C2%25A0%2520To%2520start%2520thinking%2520more%2520in%2520an%2520Erlang%2520mindset%2520%2528though%2520in%2520a%2520very%2520contrived%2520manner%2529%2520in%2520this%2520post%2520I%2520convert%2520the%2520file%2520system%2520walke';" title="Google Bookmarks"><img src="http://www.roberthorvick.com/wp-content/plugins/sociable/images/googlebookmark.png" title="Google Bookmarks" alt="Google Bookmarks" class="sociable-hovers" /></a>
	<a rel="nofollow" id="stumbleupon" href="javascript:window.location='http%3A%2F%2Fwww.stumbleupon.com%2Fsubmit%3Furl%3Dhttp%253A%252F%252Fwww.roberthorvick.com%252F2009%252F06%252F29%252Fconverting-the-erlang-directory-walker-to-multi-process-design%252F%26amp%3Btitle%3DConverting%2520the%2520Erlang%2520directory%2520walker%2520to%2520multi-process%2520design';" title="StumbleUpon"><img src="http://www.roberthorvick.com/wp-content/plugins/sociable/images/stumbleupon.png" title="StumbleUpon" alt="StumbleUpon" class="sociable-hovers" /></a>


<br/><br/>]]></content:encoded>
			<wfw:commentRss>http://www.roberthorvick.com/2009/06/29/converting-the-erlang-directory-walker-to-multi-process-design/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Walking the directory tree in Erlang</title>
		<link>http://www.roberthorvick.com/2009/06/29/walking-the-directory-tree-in-erlang/</link>
		<comments>http://www.roberthorvick.com/2009/06/29/walking-the-directory-tree-in-erlang/#comments</comments>
		<pubDate>Mon, 29 Jun 2009 13:43:14 +0000</pubDate>
		<dc:creator>robert</dc:creator>
				<category><![CDATA[Erlang]]></category>

		<guid isPermaLink="false">http://www.roberthorvick.com/?p=3</guid>
		<description><![CDATA[I&#8217;m learning Erlang.  I&#8217;ll get into &#8220;why&#8221; in some other post &#8211; the purpose here is to share my first sample program and solicit feedback.  The purpose of the program is to start print the contents of a file system from the indicated point downwards (ignoring symlinks).
The application has a single module, walker, which exports [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m learning Erlang.  I&#8217;ll get into &#8220;why&#8221; in some other post &#8211; the purpose here is to share my first sample program and solicit feedback.  The purpose of the program is to start print the contents of a file system from the indicated point downwards (ignoring symlinks).</p>
<p>The application has a single module, walker, which exports walk/1.  The argument to walk/1 is the starting path.  For example:<br />
<code><br />
&gt; walker:walk("/home").<br />
</code></p>
<p>This method prints the path name, determines the type of the current path (file, directory or symlink), and then IFF the path is a directory it calls filelib:wildcard to get the children of the path and repeats the process on them.</p>

<div class="wp_syntax"><div class="code"><pre class="erlang" style="font-family:monospace;"><span style="color: #014ea4;">-</span><span style="color: #5400b3;">module</span><span style="color: #109ab8;">&#40;</span>walker<span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #014ea4;">-</span><span style="color: #5400b3;">include_lib</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff7800;">&quot;kernel/include/file.hrl&quot;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #014ea4;">-</span><span style="color: #5400b3;">export</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#91;</span>walk<span style="color: #014ea4;">/</span><span style="color: #ff9600;">1</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #ff3c00;">is_symlink</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Path</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
	<span style="color: #186895;">case</span> <span style="color: #ff4e18;">file</span>:<span style="color: #ff3c00;">read_link_info</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Path</span><span style="color: #109ab8;">&#41;</span> <span style="color: #186895;">of</span>
		<span style="color: #109ab8;">&#123;</span>ok<span style="color: #6bb810;">,</span> #<span style="color: #d400ed;">file_info</span><span style="color: #109ab8;">&#123;</span>type <span style="color: #014ea4;">=</span> symlink<span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#125;</span> <span style="color: #6bb810;">-&gt;</span>
			<span style="color: #006600;">true</span><span style="color: #6bb810;">;</span>
		<span style="color: #45b3e6;">_</span> <span style="color: #6bb810;">-&gt;</span>
			<span style="color: #006600;">false</span>
	<span style="color: #186895;">end</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #ff3c00;">file_type</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Path</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
	<span style="color: #45b3e6;">IsRegular</span> <span style="color: #014ea4;">=</span> <span style="color: #ff4e18;">filelib</span>:<span style="color: #ff3c00;">is_regular</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Path</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
	<span style="color: #186895;">case</span> <span style="color: #45b3e6;">IsRegular</span> <span style="color: #186895;">of</span>
		true <span style="color: #6bb810;">-&gt;</span>
			<span style="color: #006600;">file</span><span style="color: #6bb810;">;</span>
		false <span style="color: #6bb810;">-&gt;</span>
			<span style="color: #186895;">case</span> <span style="color: #ff3c00;">is_symlink</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Path</span><span style="color: #109ab8;">&#41;</span> <span style="color: #186895;">of</span>
				true <span style="color: #6bb810;">-&gt;</span>
					<span style="color: #006600;">symlink</span><span style="color: #6bb810;">;</span>
				false <span style="color: #6bb810;">-&gt;</span>
					<span style="color: #006600;">directory</span>
			<span style="color: #186895;">end</span>
	<span style="color: #186895;">end</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #ff3c00;">walk</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Path</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
	<span style="color: #ff4e18;">io</span>:<span style="color: #ff3c00;">format</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff7800;">&quot;~s~n&quot;</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span><span style="color: #45b3e6;">Path</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
&nbsp;
	<span style="color: #45b3e6;">FileType</span> <span style="color: #014ea4;">=</span> <span style="color: #ff3c00;">file_type</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Path</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
	<span style="color: #186895;">case</span> <span style="color: #45b3e6;">FileType</span> <span style="color: #186895;">of</span>
		file <span style="color: #6bb810;">-&gt;</span>
			<span style="color: #006600;">ok</span><span style="color: #6bb810;">;</span>
		symlink <span style="color: #6bb810;">-&gt;</span>
			<span style="color: #006600;">ok</span><span style="color: #6bb810;">;</span>
		directory <span style="color: #6bb810;">-&gt;</span>
			<span style="color: #45b3e6;">Children</span> <span style="color: #014ea4;">=</span> <span style="color: #ff4e18;">filelib</span>:<span style="color: #ff3c00;">wildcard</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Path</span> <span style="color: #014ea4;">++</span> <span style="color: #ff7800;">&quot;/*&quot;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
			<span style="color: #ff4e18;">lists</span>:<span style="color: #ff3c00;">foreach</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff3c00;">fun</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">P</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span> <span style="color: #ff3c00;">walk</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">P</span><span style="color: #109ab8;">&#41;</span> <span style="color: #186895;">end</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Children</span><span style="color: #109ab8;">&#41;</span>
	<span style="color: #186895;">end</span><span style="color: #6bb810;">.</span></pre></div></div>

<p>My questions about this module are:</p>
<ol>
<li>Does calling walk(P) in a foreach prevent tail recursion optimizations?</li>
<li>Where I have &#8220;case FileType of&#8221; (in walk/1) is there a more succinct way to express that?</li>
<li>Why doesn&#8217;t read_file_info ever return file_info#type==symlink?</li>
<li>How should this have really been done?</li>
</ol>
<p>I&#8217;ll be working on answering #1-3 on my way to learning #4 &#8211; but if you have any feedback I would love to hear it.</p>
<p>The next step is to make this message based and have the walk/1 method send messages to a consumer who will do the printing.</p>
<p>The next-next step is to  RabbitMQ and setup one producer and three consumers &#8211; one for files, one for directories and one for symlinks.  The walk/1 method will no longer print the file info but rather send the appropriate message and let the consumers print the messages.</p>



Share and Enjoy:


	<a rel="nofollow" id="print" href="javascript:window.location='http%3A%2F%2Fwww.printfriendly.com%2Fprint%3Furl%3Dhttp%253A%252F%252Fwww.roberthorvick.com%252F2009%252F06%252F29%252Fwalking-the-directory-tree-in-erlang%252F%26amp%3Bpartner%3Dsociable';" title="Print this article!"><img src="http://www.roberthorvick.com/wp-content/plugins/sociable/images/printfriendly.png" title="Print this article!" alt="Print this article!" class="sociable-hovers" /></a>
	<a rel="nofollow" id="twitter" href="javascript:window.location='http%3A%2F%2Ftwitter.com%2Fhome%3Fstatus%3DWalking%2520the%2520directory%2520tree%2520in%2520Erlang%2520-%2520http%253A%252F%252Fwww.roberthorvick.com%252F2009%252F06%252F29%252Fwalking-the-directory-tree-in-erlang%252F';" title="Twitter"><img src="http://www.roberthorvick.com/wp-content/plugins/sociable/images/twitter.png" title="Twitter" alt="Twitter" class="sociable-hovers" /></a>
	<a rel="nofollow" id="digg" href="javascript:window.location='http%3A%2F%2Fdigg.com%2Fsubmit%3Fphase%3D2%26amp%3Burl%3Dhttp%253A%252F%252Fwww.roberthorvick.com%252F2009%252F06%252F29%252Fwalking-the-directory-tree-in-erlang%252F%26amp%3Btitle%3DWalking%2520the%2520directory%2520tree%2520in%2520Erlang%26amp%3Bbodytext%3DI%2527m%2520learning%2520Erlang.%25C2%25A0%2520I%2527ll%2520get%2520into%2520%2522why%2522%2520in%2520some%2520other%2520post%2520-%2520the%2520purpose%2520here%2520is%2520to%2520share%2520my%2520first%2520sample%2520program%2520and%2520solicit%2520feedback.%25C2%25A0%2520The%2520purpose%2520of%2520the%2520program%2520is%2520to%2520start%2520print%2520the%2520contents%2520of%2520a%2520file%2520system%2520from%2520the%2520indicated%2520point%2520downwards';" title="Digg"><img src="http://www.roberthorvick.com/wp-content/plugins/sociable/images/digg.png" title="Digg" alt="Digg" class="sociable-hovers" /></a>
	<a rel="nofollow" id="reddit" href="javascript:window.location='http%3A%2F%2Freddit.com%2Fsubmit%3Furl%3Dhttp%253A%252F%252Fwww.roberthorvick.com%252F2009%252F06%252F29%252Fwalking-the-directory-tree-in-erlang%252F%26amp%3Btitle%3DWalking%2520the%2520directory%2520tree%2520in%2520Erlang';" title="Reddit"><img src="http://www.roberthorvick.com/wp-content/plugins/sociable/images/reddit.png" title="Reddit" alt="Reddit" class="sociable-hovers" /></a>
	<a rel="nofollow" id="del.icio.us" href="javascript:window.location='http%3A%2F%2Fdelicious.com%2Fpost%3Furl%3Dhttp%253A%252F%252Fwww.roberthorvick.com%252F2009%252F06%252F29%252Fwalking-the-directory-tree-in-erlang%252F%26amp%3Btitle%3DWalking%2520the%2520directory%2520tree%2520in%2520Erlang%26amp%3Bnotes%3DI%2527m%2520learning%2520Erlang.%25C2%25A0%2520I%2527ll%2520get%2520into%2520%2522why%2522%2520in%2520some%2520other%2520post%2520-%2520the%2520purpose%2520here%2520is%2520to%2520share%2520my%2520first%2520sample%2520program%2520and%2520solicit%2520feedback.%25C2%25A0%2520The%2520purpose%2520of%2520the%2520program%2520is%2520to%2520start%2520print%2520the%2520contents%2520of%2520a%2520file%2520system%2520from%2520the%2520indicated%2520point%2520downwards';" title="del.icio.us"><img src="http://www.roberthorvick.com/wp-content/plugins/sociable/images/delicious.png" title="del.icio.us" alt="del.icio.us" class="sociable-hovers" /></a>
	<a rel="nofollow" id="facebook" href="javascript:window.location='http%3A%2F%2Fwww.facebook.com%2Fshare.php%3Fu%3Dhttp%253A%252F%252Fwww.roberthorvick.com%252F2009%252F06%252F29%252Fwalking-the-directory-tree-in-erlang%252F%26amp%3Bt%3DWalking%2520the%2520directory%2520tree%2520in%2520Erlang';" title="Facebook"><img src="http://www.roberthorvick.com/wp-content/plugins/sociable/images/facebook.png" title="Facebook" alt="Facebook" class="sociable-hovers" /></a>
	<a rel="nofollow" id="google" href="javascript:window.location='http%3A%2F%2Fwww.google.com%2Fbookmarks%2Fmark%3Fop%3Dedit%26amp%3Bbkmk%3Dhttp%253A%252F%252Fwww.roberthorvick.com%252F2009%252F06%252F29%252Fwalking-the-directory-tree-in-erlang%252F%26amp%3Btitle%3DWalking%2520the%2520directory%2520tree%2520in%2520Erlang%26amp%3Bannotation%3DI%2527m%2520learning%2520Erlang.%25C2%25A0%2520I%2527ll%2520get%2520into%2520%2522why%2522%2520in%2520some%2520other%2520post%2520-%2520the%2520purpose%2520here%2520is%2520to%2520share%2520my%2520first%2520sample%2520program%2520and%2520solicit%2520feedback.%25C2%25A0%2520The%2520purpose%2520of%2520the%2520program%2520is%2520to%2520start%2520print%2520the%2520contents%2520of%2520a%2520file%2520system%2520from%2520the%2520indicated%2520point%2520downwards';" title="Google Bookmarks"><img src="http://www.roberthorvick.com/wp-content/plugins/sociable/images/googlebookmark.png" title="Google Bookmarks" alt="Google Bookmarks" class="sociable-hovers" /></a>
	<a rel="nofollow" id="stumbleupon" href="javascript:window.location='http%3A%2F%2Fwww.stumbleupon.com%2Fsubmit%3Furl%3Dhttp%253A%252F%252Fwww.roberthorvick.com%252F2009%252F06%252F29%252Fwalking-the-directory-tree-in-erlang%252F%26amp%3Btitle%3DWalking%2520the%2520directory%2520tree%2520in%2520Erlang';" title="StumbleUpon"><img src="http://www.roberthorvick.com/wp-content/plugins/sociable/images/stumbleupon.png" title="StumbleUpon" alt="StumbleUpon" class="sociable-hovers" /></a>


<br/><br/>]]></content:encoded>
			<wfw:commentRss>http://www.roberthorvick.com/2009/06/29/walking-the-directory-tree-in-erlang/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
