<?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>NPCT &#187; Erlang</title>
	<atom:link href="http://www.nonperiodic.net/blog/category/computing/erlang/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.nonperiodic.net/blog</link>
	<description>Nonperiodic Central Trajectory</description>
	<lastBuildDate>Tue, 07 Apr 2009 03:01:42 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Ungoogleable Erlang Documentation</title>
		<link>http://www.nonperiodic.net/blog/2008/02/20/ungoogleable-erlang-documentation/</link>
		<comments>http://www.nonperiodic.net/blog/2008/02/20/ungoogleable-erlang-documentation/#comments</comments>
		<pubDate>Wed, 20 Feb 2008 00:16:51 +0000</pubDate>
		<dc:creator>Ryan</dc:creator>
				<category><![CDATA[Computing]]></category>
		<category><![CDATA[Erlang]]></category>

		<guid isPermaLink="false">http://www.nonperiodic.net/blog/2008/02/20/ungoogleable-erlang-documentation/</guid>
		<description><![CDATA[While I&#8217;m complaining about Erlang: why doesn&#8217;t Google ever return any hits on the documentation? If I google &#8220;perl sprintf&#8221; the first hit is the documentation page http://perldoc.perl.org/functions/sprintf.html. The same thing happens if I Google &#8220;python array&#8221; or &#8220;lisp map&#8221; or &#8220;php echo.&#8221; If I type &#8220;erlang supervisor&#8221; I don&#8217;t get anything manual-like until the [...]]]></description>
			<content:encoded><![CDATA[<p>While I&#8217;m complaining about Erlang: why doesn&#8217;t Google ever return any hits on the documentation?  If I google &#8220;perl sprintf&#8221; the first hit is the documentation page <a href="http://perldoc.perl.org/functions/sprintf.html">http://perldoc.perl.org/functions/sprintf.html</a>.  The same thing happens if I Google &#8220;python array&#8221; or &#8220;lisp map&#8221; or &#8220;php echo.&#8221;  If I type &#8220;erlang supervisor&#8221; I don&#8217;t get anything manual-like until the 18th hit with <a href="http://erlang.org/doc/design_principles/sup_princ.html">this page</a>, which isn&#8217;t even the man page.  Moreover, that page <b>doesn&#8217;t even link to the actual manual page</b> despite referring to it:</p>
<blockquote><p>
This section should be read in conjunction with supervisor(3), where all details about the supervisor behaviour is given.
</p></blockquote>
<p>In fact, even if you start <a href="http://erlang.org/doc/">at the documentation page</a>, it&#8217;s not clear how you would find <code>supervisor (3)</code> aside from actually typing &#8220;man supervisor&#8221; at the command prompt.  The <a href="http://erlang.org/doc/reference_manual/part_frame.html">Erlang Reference Manual</a> (with its <b>HORRIBLE HORRIBLE FRAMES</b>) doesn&#8217;t actually talk about the supervisor behaviour, presumably because this is technically an OTP thing.  Eventually, I go to <a href="http://erlang.org/doc/man_index.html">the index</a> and there it is.  Why is this so hard?  I feel like I can&#8217;t be the only one who finds this frustrating.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.nonperiodic.net/blog/2008/02/20/ungoogleable-erlang-documentation/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Erlang PostgreSQL Roundup</title>
		<link>http://www.nonperiodic.net/blog/2008/02/20/erlang-postgresql-roundup/</link>
		<comments>http://www.nonperiodic.net/blog/2008/02/20/erlang-postgresql-roundup/#comments</comments>
		<pubDate>Tue, 19 Feb 2008 23:56:12 +0000</pubDate>
		<dc:creator>Ryan</dc:creator>
				<category><![CDATA[Britain]]></category>
		<category><![CDATA[Computing]]></category>
		<category><![CDATA[Erlang]]></category>

		<guid isPermaLink="false">http://www.nonperiodic.net/blog/2008/02/20/erlang-postgresql-roundup/</guid>
		<description><![CDATA[Like just about everything to do with Erlang, database driver support appears to be in total disarray. I&#8217;d like to be able to store data in a PostgreSQL database and access it reasonably well. Options appear to be Erlang psql driver that is a fork or something of the code by Erlang Consulting. You can&#8217;t [...]]]></description>
			<content:encoded><![CDATA[<p>Like just about everything to do with Erlang, database driver support appears to be in total disarray.  I&#8217;d like to be able to store data in a PostgreSQL database and access it reasonably well.  Options appear to be</p>
<ul>
<li><a href="http://code.google.com/p/erlang-psql-driver/">Erlang psql driver</a> that is a fork or something of the code by Erlang Consulting.  You can&#8217;t even directly download it.  You have to check it out from SVN.  It doesn&#8217;t even have a README file.</li>
<li>On <a href="http://jungerl.sourceforge.net/">Jungerl</a> there claims to be psql project, but you can&#8217;t download it or anything without apparently downloading all this other stuff.  In fact, like the one above, you can only check it out via CVS.  The CVS repository for it is viewable <a href="http://jungerl.cvs.sourceforge.net/jungerl/jungerl/lib/pgsql/">here</a>.  It only claims to be able to perform &#8220;simple commands&#8221; and the code doesn&#8217;t look like it&#8217;s been updated in a while.</li>
<li><a href="http://erlang-consulting.com/aboutus/opensource.html">Erlang Consulting</a> has released some code, but no examples or anything about how to use it.</li>
<li>There is apparently an <a href="http://linux.die.net/man/3/odbc">ODBC</a> implementation, but from the mailing list it sounds like it is very slow and doesn&#8217;t work well in Linux, while also not implementing many of PostgreSQL&#8217;s features.</li>
<li>ejabberd <a href="https://forge.process-one.net/browse/ejabberd-modules/pgsql">also has an implementation</a></li>
</ul>
<p>There&#8217;s a blog post <a href="http://devtopics.blogspot.com/2006/07/postgresql-part-1.html">here</a> from 2006 where Ernie Makris claims to have written a kick-ass interface and is going to tell us all about it and post it.  Unfortunately he never posts on his blog again.  There is an extensive thread <a href="http://www.trapexit.org/forum/viewtopic.php?t=10861&#038;start=0&#038;sid=4e3fcba8b22227f55c075f7abf4f6c80">here</a> where people express the same frustrations as I am.  This thread is only a couple of months old, so maybe things have gotten somewhere. </p>
<p>It appears, anecdotally, that the one on Jungerl by Christian Sunesson is pretty stable, and it seems to be relatively standalone.  I will give this one a shot first and see where it gets me.  Connection seems straightforward enough:<br />
<verbatim><br />
{ok, Db} = pgsql:connect(&#8220;host&#8221;, &#8220;database&#8221;, &#8220;user&#8221;, &#8220;password&#8221;).<br />
</verbatim><br />
My first little query:<br />
<verbatim><br />
pgsql:squery(Db, &#8220;SELECT NOW()&#8221;).<br />
</verbatim><br />
After turning off SSL in the postgresql.conf file, I got back the quite-reasonable answer:<br />
<verbatim><br />
{ok,[{"SELECT",<br />
      [{desc,0,"now",timestamptz,text,8,-1,0}],<br />
      [[< <"2008-02-19 18:55:06.87229-05">>]]}]}<br />
</verbatim><br />
So, I&#8217;m cautiously optimistic that I might be able to make this work.</p>
<p><b>UPDATE:</b><br />
It looks like the ejabberd stuff may actually be the way to go.  It is a branch of the Jungerl work by Christian Sunesson and it appears to be <a href="https://forge.process-one.net/browse/ejabberd-modules/pgsql/trunk/src">under active development</a>.  Specifically, they have implemented things with <code>gen_server</code>, which would seem to be a big improvement.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.nonperiodic.net/blog/2008/02/20/erlang-postgresql-roundup/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>XML Stream Parsing in Erlang, II</title>
		<link>http://www.nonperiodic.net/blog/2008/02/19/xml-stream-parsing-in-erlang-ii/</link>
		<comments>http://www.nonperiodic.net/blog/2008/02/19/xml-stream-parsing-in-erlang-ii/#comments</comments>
		<pubDate>Tue, 19 Feb 2008 21:37:13 +0000</pubDate>
		<dc:creator>Ryan</dc:creator>
				<category><![CDATA[Computing]]></category>
		<category><![CDATA[Erlang]]></category>
		<category><![CDATA[Gaming]]></category>
		<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://www.nonperiodic.net/blog/2008/02/19/xml-stream-parsing-in-erlang-ii/</guid>
		<description><![CDATA[In my previous post, I complained a lot about trying to get XML stream parsing working. Ultimately, I just decided to rip the guts out of ejabberd, rather than reinvent the wheel. The relevant files are xml_stream.erl, xml.erl, and expat_erl.c. You can see how to use it in ejabberd_receiver.erl. Frankly, these guys seem to have [...]]]></description>
			<content:encoded><![CDATA[<p>In <a href="http://www.nonperiodic.net/blog/2008/02/18/xml-stream-parsing-in-erlang/">my previous post</a>, I complained a lot about trying to get XML stream parsing working.  Ultimately, I just decided to rip the guts out of ejabberd, rather than reinvent the wheel.  The relevant files are <a href="https://forge.process-one.net/browse/ejabberd/trunk/src/xml_stream.erl">xml_stream.erl</a>, <a href="https://forge.process-one.net/browse/ejabberd/trunk/src/xml.erl">xml.erl</a>, and <a href="https://forge.process-one.net/browse/ejabberd/trunk/src/expat_erl.c">expat_erl.c</a>.  You can see how to use it in <a href="https://forge.process-one.net/browse/ejabberd/trunk/src/ejabberd_receiver.erl">ejabberd_receiver.erl</a>.  Frankly, these guys seem to have it pretty well figured out.  The way I went about it is this: using the tcp-client <code>gen_fsm</code> from <a href="http://www.trapexit.org/Building_a_Non-blocking_TCP_server_using_OTP_principles">here</a>, I added init code to load up the library in start_link, with something like this:<br />
<verbatim><br />
    case erl_ddll:load_driver(&#8220;ebin&#8221;, expat_erl) of<br />
        ok -> ok;<br />
        {error, already_loaded} -> ok;<br />
	{error, Reason} -><br />
	    error_logger:error_msg(&#8220;Could not load expat driver: ~p~n&#8221;,<br />
				   erl_ddll:format_error(Reason))<br />
    end<br />
</verbatim><br />
I added a bit to the fsm state record to manage the xml state.  When a client connects and the process gets started for it in the <code>'WAIT_FOR_SOCKET'({socket_ready, Socket}, State) when is_port(Socket)</code> call, I initialize the xml parser <code>xml_stream:new(self())</code> and store that in the record.  Upon receiving data in <code>'WAIT_FOR_DATA'({data, Data},</code>, I call <code>NewXmlState = xml_stream:parse(XmlState, Data)</code> and update the record with the new state.  Then, messages just appear in the fsm queue and I handle them.  What I do, specifically, is set up another fsm and send it messages that have been parsed, so that it essentially abstracts away the tcp and the xml.  My plan is to add udp functionality that uses the same interface, so that datagrams look just like stanza&#8217;d messages and the process doesn&#8217;t need to know where the data came from.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.nonperiodic.net/blog/2008/02/19/xml-stream-parsing-in-erlang-ii/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>XML Stream Parsing in Erlang</title>
		<link>http://www.nonperiodic.net/blog/2008/02/18/xml-stream-parsing-in-erlang/</link>
		<comments>http://www.nonperiodic.net/blog/2008/02/18/xml-stream-parsing-in-erlang/#comments</comments>
		<pubDate>Mon, 18 Feb 2008 22:53:20 +0000</pubDate>
		<dc:creator>Ryan</dc:creator>
				<category><![CDATA[Computing]]></category>
		<category><![CDATA[Erlang]]></category>
		<category><![CDATA[Gaming]]></category>

		<guid isPermaLink="false">http://www.nonperiodic.net/blog/2008/02/18/xml-stream-parsing-in-erlang/</guid>
		<description><![CDATA[There&#8217;s a lively debate out there about how one should communicate with clients in a game, in particular UDP vs TCP. I won&#8217;t go into details about it, but you can read a lively debate here. The choice for my ridiculous game is TCP+UDP. I want to use TCP for various communications where I want [...]]]></description>
			<content:encoded><![CDATA[<p>There&#8217;s a lively debate out there about how one should communicate with clients in a game, in particular UDP vs TCP.  I won&#8217;t go into details about it, but you can read a lively debate <a href="http://www.gamedev.net/community/forums/topic.asp?topic_id=319003">here</a>.  The choice for my ridiculous game is TCP+UDP.  I want to use TCP for various communications where I want reliability, and UDP for fast updates that can afford to be lost.  I don&#8217;t want to deal with having to build a reliable application protocol on top of UDP.  I like the idea that a player is connected to a game or not, and I can encapsulate that idea with TCP.</p>
<p>So, I decided that a good first step would be to implement a simple TCP server in Erlang, extending what I introduced <a href="http://www.nonperiodic.net/blog/2008/01/23/starting-an-erlang-project-part-i/">in</a> <a href="http://www.nonperiodic.net/blog/2008/01/24/starting-an-erlang-project-part-ii/">previous</a> <a href="http://www.nonperiodic.net/blog/2008/01/24/starting-an-erlang-project-part-iii/">posts</a>. There are various examples out there, but I decided to follow &#8220;<a href="http://www.trapexit.org/Building_a_Non-blocking_TCP_server_using_OTP_principles">Building a Non-blocking TCP server using OTP principles</a>&#8221; on TrapExit.  Not too hard to do, and theoretically implements an echo server.  However, one gotcha is that when you setup the socket, you&#8217;ll use lots of <code>{packet, 2}</code> options and I didn&#8217;t realize at first that this is an application-layer thing that helps Erlang decide when to throw you an event.  So you <b>will not</b> be able to just log into telnet and bounce things off of your server, because telnet won&#8217;t know to include the packet length.  It&#8217;s easy enough to do this in Perl, by prepending a packed message length to your message, but be forewarned.  The easiest thing to do is to replace it with <code>{packet, line}</code> and then it will maybe do what you&#8217;re expecting.</p>
<p>Frankly, I found this whole thing a bit annoying, because it wasn&#8217;t clear from the documentation that <code>gen_fsm</code> was going to magically receive messages from the socket when data arrived.  But I eventually sorted this out and it seems to work okay.</p>
<p>Now what I want to do is to implement a simple XML-based protocol for my game.  The idea is that this will fit well with the finite state machine approach, and allows me to extend it to include new functionality pretty easily.  It&#8217;s not very good for bandwidth usage, but I don&#8217;t expect to send much data this way.  <a href="http://www.ejabberd.im/">ejabberd</a> is a good example of XML streaming in Erlang, and there are at least two libraries out there for parsing: <a href="http://www.erlang.org/doc/apps/xmerl/index.html">xmerl</a> (<a href="http://www.erlang.org/doc/apps/xmerl/index.html">User&#8217;s Guide</a>) and <a href="http://sourceforge.net/projects/erlsom/">erlsom</a>.  Since I want streamed parsing, I&#8217;ll need an event-based parser with something like SAX.  Neither of them have much documentation about event-driven usage (lack of documentation is starting to be my biggest problem with Erlang), but <a href="http://erlang.org/pipermail/erlang-questions/2007-February/025107.html">this thread</a> would imply that I&#8217;m better off with Erlsom.  Trying it out, however, it wouldn&#8217;t work without a complete document.  I want to implement something like the &#8220;stanzas&#8221; of XMPP.</p>
<p>Of course, for some reason, doing even the simplest things in Erlang is like pulling teeth.  I thought I&#8217;d play with xmerl to see if might do what I want.  I look at the sparse documentation, and at <a href="http://pragdave.pragprog.com/pragdave/2007/04/a_first_erlang_.html">this blog entry</a> and write the simplest possible program for parsing an xml file.<br />
<verbatim><br />
-module(lame).<br />
-include_lib(&#8220;xmerl/include/xmerl.hrl&#8221;).<br />
-export([ parsemo/0 ]).</p>
<p>parsemo() -><br />
    {Xml, Rest} = xmerl_scan:file(&#8220;foo.xml&#8221;),<br />
    io:format(&#8220;~p  ~p&#8221;, [Xml, Rest]).<br />
</verbatim><br />
foo.xml is just about the simplest thing you could imagine:<br />
<verbatim><br />
&lt;?xml version=&#8221;1.0&#8243; encoding=&#8221;utf-8&#8243; ?&gt;<br />
&lt;foo&gt;<br />
 bar<br />
&lt;/foo&gt;<br />
</verbatim></p>
<p>I try to run this thing, and get this:<br />
<verbatim><br />
Erlang (BEAM) emulator version 5.5.5 </p>
<p>Eshell V5.5.5  (abort with ^G)<br />
1> c(lame).<br />
{ok,lame}<br />
2> lame:parsemo().</p>
<p>=ERROR REPORT==== 18-Feb-2008::16:44:14 ===<br />
Error in process &lt;0.31.0> with exit value: {undef,[{xmerl_scan,file,["foo.xml"]},{lame,parsemo,0},<br />
{erl_eval,do_apply,5},{shell,exprs,6},{shell,eval_loop,3}]}</p>
<p>** exited: {undef,[{xmerl_scan,file,["foo.xml"]},<br />
                   {lame,parsemo,0},<br />
                   {erl_eval,do_apply,5},<br />
                   {shell,exprs,6},<br />
                   {shell,eval_loop,3}]} **<br />
</verbatim><br />
What the hell?  For one thing, there is almost no information about what is wrong.  This is a <b>huge</b> failing on the part of Erlang.  The error messages are ridiculous.  I <b>assume</b> that the problem is that it doesn&#8217;t know about xmerl and can&#8217;t resolve the function call.  It managed to load it just fine with the <code>include_lib</code>, but it doesn&#8217;t seem that it&#8217;s finding <code>xmerl_scan:file</code>.  I don&#8217;t even know where to begin, to figure out how to get Erlang to find the module.  I mean, am I insane?  This is the sort of thing that makes a tool a no-go for me.  I could write a streaming XML parser in Perl in about ten minutes.  I know this because I&#8217;ve done it before.  XML parsing is the sort of thing that should never have to be implemented in a modern development toolset &#8211; there should be clearly documented libraries with standard interfaces.</p>
<p>Taking a deep breath and looking at Section 6.7 of Joe Armstrong&#8217;s book, I see that this cryptic error message indicates one of four possible failure modes in trying to find <code>xmerl_scan:file</code>: 1) no module xmerl_scan, 2) xmerl_scan hasn&#8217;t been compiled, 3) xmerl_scan.beam can&#8217;t be found, 4) there are multiple versions of xmerl_scan floating around in the path.  I was under the impression that xmerl was included in the standard libraries.  I installed Erlang 5.5.5 via apt-get erlang-base-hipe (Ubuntu Gutsy), and it would seem that xmerl_scan is around, inasmuch as <code>man xmerl_scan</code> gives me the &#8220;docs.&#8221;  However, I&#8217;m not able to actually use it.</p>
<p>After much wringing of hands, I installed every erlang-related package I could find via apt-cache and eventually it seemed to work.  I have no idea what the problem was.  Now my silly parser outputs:<br />
<verbatim><br />
{xmlElement,foo,<br />
            foo,<br />
            [],<br />
            {xmlNamespace,[],[]},<br />
            [],<br />
            1,<br />
            [],<br />
            [{xmlText,[{foo,1}],1,[],&#8221;\n bar\n&#8221;,text}],<br />
            [],<br />
            &#8220;.&#8221;,<br />
            undeclared}  []<br />
</verbatim><br />
which is at least a step in the right direction.  When I try to run it on a partial string, however, we fail.  I think this is the behavior that xmerl intends to have.  I&#8217;m starting to think that implementing whatever ejabberd does is going to be the only way to resolve this, unfortunately.  So, I guess that&#8217;ll be next time.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.nonperiodic.net/blog/2008/02/18/xml-stream-parsing-in-erlang/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Starting an Erlang Project, Part III</title>
		<link>http://www.nonperiodic.net/blog/2008/01/24/starting-an-erlang-project-part-iii/</link>
		<comments>http://www.nonperiodic.net/blog/2008/01/24/starting-an-erlang-project-part-iii/#comments</comments>
		<pubDate>Thu, 24 Jan 2008 20:44:07 +0000</pubDate>
		<dc:creator>Ryan</dc:creator>
				<category><![CDATA[Computing]]></category>
		<category><![CDATA[Erlang]]></category>

		<guid isPermaLink="false">http://www.nonperiodic.net/blog/2008/01/24/starting-an-erlang-project-part-iii/</guid>
		<description><![CDATA[I&#8217;ve posted twice now about starting an Erlang project (one and two). I now have a directory structure and a Makefile that I&#8217;m happy with, plus some odds-and-ends from my first attempt at stubbing out an OTP application. I&#8217;m now going to begin again, with a healthy dose of Chapter 18 from Joe Armstrong&#8217;s book [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve posted twice now about starting an Erlang project (<a href="http://www.nonperiodic.net/blog/2008/01/23/starting-an-erlang-project-part-i/">one</a> and <a href="http://www.nonperiodic.net/blog/2008/01/24/starting-an-erlang-project-part-ii/">two</a>).  I now have a directory structure and a Makefile that I&#8217;m happy with, plus some odds-and-ends from my first attempt at stubbing out an OTP application.  I&#8217;m now going to begin again, with a healthy dose of Chapter 18 from <a href="http://www.amazon.com/gp/product/193435600X?ie=UTF8&#038;tag=nonperiodicce-20&#038;linkCode=xm2&#038;camp=1789&#038;creativeASIN=193435600X">Joe Armstrong&#8217;s book</a> and a bit of <a href="http://www.kazmier.com/computer/port-howto/">Pete Kazmier&#8217;s Howto</a> as well.</p>
<p>To remind you again, we&#8217;re calling this project &#8220;North Zulch&#8221; and prefixing all of our modules with &#8220;nz.&#8221;  This sort of prefixing and underscoring seems to be the way that Erlang manages its namespace.  It&#8217;s a bit ugly, but that&#8217;s the way it is.  The first thing we want is an application callback module, more or less like we made before.  We&#8217;ll name this file after the overall project: <code>north_zulch.erl</code>.  Our first shot at this is:</p>
<pre>
-module(north_zulch).
-behaviour(application).
-export([ start/2, stop/1 ]).

start(_Type, _StartArgs) ->
    io:format("north_zulch is starting~n"),
    {ok, self()}.

stop(_State) ->
    io:format("north_zulch has stopped~n"),
    ok.
</pre>
<p>This obviously doesn&#8217;t do anything interesting at all, but it&#8217;s a good place to start.  The <code>start/2</code> function prints out a little message and then returns a tuple of the term <code>ok</code> and our process id.  Generally, this process id will be for a supervisor, but right now we just give it this.  <code>stop/1</code> does a similar thing, but without a process id.  Note that we prefix the various arguments with underscores to indicate that we&#8217;re not interested in the values.  We put <code>north_zulch</code> in our MODULES list in the Makefile, run make to compile it and then run <code>erl -pa ebin</code>, which fires up Erlang and looks in the <code>ebin</code> directory for .beam files.  Now we get</p>
<pre>
Erlang (BEAM) emulator version 5.5.5

Eshell V5.5.5  (abort with ^G)
1> north_zulch:start(foo,bar).
north_zulch is starting
{ok,&lt;0.31.0>}
2> north_zulch:stop(foo).
north_zulch has stopped
ok
</pre>
<p>We give the two functions dummy values (since we aren&#8217;t using them), or we&#8217;ll get an error.  So, this seems to work.  However, the whole point is that this is an application callback module.  We want to be able to deal with it as an OTP application.  To do that we have to create an .app file, which we place in the <code>ebin</code> directory, named <code>north_zulch.app</code>.  This file tells the application what to do with us.</p>
<pre>
%% -*- erlang -*-
{application, north_zulch,
 [{description, "North Zulch Master"},
  {vsn, "1.0"},
  {modules, []},
  {registered, []},
  {applications, [kernel, stdlib]},
  {mod, {north_zulch, []}},
  {env, []},
  {start_phases, []}
 ]}.
</pre>
<p>I won&#8217;t go into detail about this, but the important bits are: the first thing in the tuple must be the term <code>application</code>, followed by the name of the application &#8211; which must also be the name of the file.  You can give it a description and a version number. You need to make sure to include the kernel and stdlib applications, because pretty much everything uses these.  The <code>mod</code> field needs to be your application callback module, along with the arguments that will eventually get handed to <code>start/2</code>. Also, for you folks that care about such things, the top line sends Emacs into Erlang-mode, which it would not be in by default for a file ending in .app.  Now, we can fire up our application like this:</p>
<pre>
Erlang (BEAM) emulator version 5.5.5

Eshell V5.5.5  (abort with ^G)
1> application:start(north_zulch).
north_zulch is starting
ok
2> application:stop(north_zulch).
north_zulch has stopped

=INFO REPORT==== 24-Jan-2008::14:32:32 ===
    application: north_zulch
    exited: stopped
    type: temporary
ok
</pre>
<p>Now I&#8217;m going to invoke (very slightly) deeper magic to allow us to run our application via &#8220;make run&#8221; on the command line like this:</p>
<pre>
$ make run
Running application north_zulch...
north_zulch is starting
north_zulch has stopped
$
</pre>
<p>The Makefile changes are:</p>
<pre>
APP       = north_zulch
MODULES   = $(APP)

--- SNIP ---

run: all
	@echo "Running application $(APP)..."
	@ $(ERL) -pa $(BINDIR) -eval 'application:start($(APP)).' \
               -noshell -s init stop
</pre>
<p>and remember &#8211; there are tabs before the commands, not spaces.</p>
<p>In the next installment, we&#8217;ll look at making the application actually do something &#8211; like run a supervisor, for instance.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.nonperiodic.net/blog/2008/01/24/starting-an-erlang-project-part-iii/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Starting an Erlang Project, Part II</title>
		<link>http://www.nonperiodic.net/blog/2008/01/24/starting-an-erlang-project-part-ii/</link>
		<comments>http://www.nonperiodic.net/blog/2008/01/24/starting-an-erlang-project-part-ii/#comments</comments>
		<pubDate>Thu, 24 Jan 2008 18:28:09 +0000</pubDate>
		<dc:creator>Ryan</dc:creator>
				<category><![CDATA[Computing]]></category>
		<category><![CDATA[Erlang]]></category>

		<guid isPermaLink="false">http://www.nonperiodic.net/blog/2008/01/24/starting-an-erlang-project-part-ii/</guid>
		<description><![CDATA[Continuing on with the previous Erlang post, there have been a couple of developments: 1) Programming Erlang arrived from Amazon, 2) trapexit.org came back online, and 3) I found this awesome blog. To remind you of my immediate goal: I want to figure out how to organize a large-scale Erlang project. I want to learn [...]]]></description>
			<content:encoded><![CDATA[<p>Continuing on with the <a href="http://www.nonperiodic.net/blog/2008/01/23/starting-an-erlang-project-part-i/">previous Erlang post</a>, there have been a couple of developments: 1) <a href="http://www.amazon.com/gp/product/193435600X?ie=UTF8&#038;tag=nonperiodicce-20&#038;linkCode=xm2&#038;camp=1789&#038;creativeASIN=193435600X">Programming Erlang</a> arrived from Amazon, 2) <a href="http://www.trapexit.org/">trapexit.org</a> came back online, and 3) I found <a href="http://blog.zhekov.net/tags/erlday">this awesome blog</a>.</p>
<p>To remind you of my immediate goal: I want to figure out how to organize a large-scale Erlang project.  I want to learn the conventional project directory/file structure and create a useful build environment.  Then I want to set up an infrastructure for configuration and logging.  My <a href="http://www.nonperiodic.net/blog/2008/01/23/starting-an-erlang-project-part-i/">initial stab</a> at this involved using some stub generator code to get up and running.  It seemed to do something pretty reasonable, and we walked through it up to the point where we implement the gen_server behaviour.  I have to say, though, that I&#8217;m not a huge fan of stub generation.  I like to know why every line of code is there, and for learning purposes, I want to set things up myself.  So I&#8217;m going to sort of ignore what I did the other day and start again.</p>
<p>First, directory structure: In his book, Joe Armstrong is very agnostic about directories.  He sort of has a &#8220;stick it where it makes sense&#8221; approach.  I can appreciate that, but I like a little more structure.  Stoyan Zhekov <a href="http://blog.zhekov.net/tags/erlday">has exactly the attitude I&#8217;m looking for</a> when he quotes the Ruby motto &#8220;Convention over configuration.&#8221;  He says, that the conventional way to go is:</p>
<ul>
<li><code>ebin/</code> for compiled BEAM files</li>
<li><code>src/</code> for .erl source files</li>
<li><code>include/</code> for .hrl include files</li>
<li><code>priv/</code> for application-specific configuration</li>
</ul>
<p>This is pretty much just like C/C++ development with regard to <code>src</code> and <code>include</code>, and also mirrors <a href=" http://www.kazmier.com/computer/port-howto/">tutorial by Pete Kazmier</a>, with the exception that he puts his external Python program in the <code>priv</code> directory.  Perhaps external programs and libraries would be better in <code>bin</code> and <code>lib</code> directories, respectively?  If it seems like I&#8217;m being pedantic, well, I am.  For me, a project is most fun when everything is still nice and beautiful and unhacky.  I try to hang on to that as long as I can, so I like to make decisions like these carefully so I know I can live with them.</p>
<p>Next up is build management. When I write C or C++, I use Make and when I write Java, I use ant.  They&#8217;ve got their quirks, but they&#8217;re well documented and you can cut-and-paste your build files from past projects with only a little bit of modification.  So what does Joe use for building Erlang projects? Make!  Stoyan does something that looks like Make, but actually defines an <code>Emakefile</code>, which is for <a href="http://www.erlang.org/doc/man/make.html">an Erlangified implementation of a make-like concept</a>.  What I like about the Erlang make module is that it is obviously Erlang-aware.  What I don&#8217;t like is that I expect to be integrating code from other languages, and it won&#8217;t be able to handle those dependencies.  Also, the man page is pretty sparse.  It doesn&#8217;t say anything about recursively using Emakefiles, etc. &#8211; things that are well-documented in Gnu Make.  So, I think I&#8217;m going to stick with good old Make for now then.  Without further ado, here is my basic Makefile (for Gnu Make only):</p>
<pre>
MODULES   = foo bar baz

BEAMS     = $(MODULES:%=%.beam)

BINDIR    = ebin
SRCDIR    = src
INCDIR    = include
VPATH     = $(BINDIR):$(SRCDIR):$(INCDIR)

ERL       = erl
ERLC      = erlc
ERLCFLAGS = -W -smp

all: $(BEAMS)

%.beam : %.erl %.hrl
	$(ERLC) -b beam $(ERLCFLAGS) -I $(INCDIR) -o $(BINDIR) $< .PHONY: clean

clean:
	rm -rf $(BINDIR)/*.beam $(INCDIR)/*~ $(SRCDIR)/*~ *~
</pre>
<p>This uses a couple of features: it remaps the list of modules to have .beam extensions, it uses VPATH to search directories for dependencies, and it uses the pattern-matching rules to enforce dependencies on .erl and .hrl files.  Also, I always like to remove all the Emacs backup files when I clean things up.  I use Subversion and am a compulsive committer, so it has almost never come up that I've found these files useful.</p>
<p>In the next installment, we'll look (again) at setting up an application in our nice new project structure.</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.nonperiodic.net/blog/2008/01/24/starting-an-erlang-project-part-ii/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Starting an Erlang Project, Part I</title>
		<link>http://www.nonperiodic.net/blog/2008/01/23/starting-an-erlang-project-part-i/</link>
		<comments>http://www.nonperiodic.net/blog/2008/01/23/starting-an-erlang-project-part-i/#comments</comments>
		<pubDate>Wed, 23 Jan 2008 04:05:27 +0000</pubDate>
		<dc:creator>Ryan</dc:creator>
				<category><![CDATA[Computing]]></category>
		<category><![CDATA[Erlang]]></category>
		<category><![CDATA[Gaming]]></category>
		<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://www.nonperiodic.net/blog/2008/01/23/starting-an-erlang-project-part-i/</guid>
		<description><![CDATA[Per my previous post, I&#8217;m going to start a little Erlang project. I&#8217;ll call it &#8220;North Zulch,&#8221; or &#8220;NZ&#8221; in reference to the tiny little place where the family ranch is located. There are three things that I&#8217;ve had to solve over and over (or at least cut and paste over and over), in every [...]]]></description>
			<content:encoded><![CDATA[<p>Per <a href="http://www.nonperiodic.net/blog/2008/01/22/off-on-an-erlang-adventure/">my previous post</a>, I&#8217;m going to start a little Erlang project.  I&#8217;ll call it &#8220;North Zulch,&#8221; or &#8220;NZ&#8221;  in reference to the <a href="http://maps.google.com/maps?f=q&#038;hl=en&#038;geocode=&#038;time=&#038;date=&#038;ttype=&#038;q=North+Zulch,+TX&#038;ie=UTF8&#038;om=0&#038;ll=30.899279,-96.075783&#038;spn=0.209752,0.458679&#038;z=12&#038;iwloc=addr">tiny little place</a> where the family ranch is located.</p>
<p>There are three things that I&#8217;ve had to solve over and over (or at least cut and paste over and over), in every development project I&#8217;ve ever done.  These things are: build management, configuration, and logging.  These things have led me down every path one can imagine, in C/C++, Perl, Python and Java: <a href="http://www.gnu.org/software/make/">make</a>, <a href="http://ant.apache.org/">ant</a>, <a href="http://perldoc.perl.org/ExtUtils/MakeMaker.html">MakeMaker</a>, <a href="http://www.boost.org/">Boost</a>, <a href="logging.apache.org/log4j/">log4j</a>, <a href="http://log4cpp.sourceforge.net/">log4cpp</a>, <a href="http://commons.apache.org/configuration/">Commons Configuration</a>, whatever, I&#8217;ve probably tried to use it in a project at some point, and maybe rolled my own version as well.</p>
<p>So, the first thing I want to learn is how to manage a large project correctly in Erlang.  There seem to be two concepts for this sort of thing: <a href="http://www.erlang.org/doc/design_principles/applications.html">Applications</a> and <a href="http://www.erlang.org/doc/design_principles/release_structure.html">Releases</a>.  My understanding is that Applications let you bundle processes together into a coherent whole, while Releases let you make something &#8220;turn-key&#8221; and ready to run.  I should also mention that I want this to be a distributed project.  There are two basic reasons why you might want to have a distributed application: 1) reliability, and 2) scalability.  For the hypothetical MMO framework we want, we need both.  Sure, we don&#8217;t need the <a href="http://www.cincomsmalltalk.com/userblogs/ralph/blogView?showComments=true&#038;entry=3364027251">&#8220;Nine Nines&#8221;</a> of the telecom world, but if the MMO is successful people will want to get their fix, so maybe we want three nines.  Scalability is much more important.  Since we&#8217;re fantasizing anyway, let&#8217;s imagine that we want to be able to have around a million users on an unsharded world.  Obviously this is going to require a pretty hefty cluster of the sort of machines that are cheap to maintain and replace.  Anyway, regardless of the stupidity of these numbers, the point is that NZ needs to be a distributed application.</p>
<p>In practical terms, the most useful things I&#8217;ve seen for getting started have been <a href="http://www.kazmier.com/computer/port-howto/">this page</a> by Pete Kazmier, which talks about building an application using OTP principles, and <a href="http://www.trapexit.org/Building_An_OTP_Application">this page</a> at TrapExit, which has been down for several days.  Also, there seems to be a lot of stuff going on at <a href="http://www.erlware.org/erlware/index.html">Erlware</a>.  The goal there seems to be to make a unified system like <a href=" http://sourceware.org/autobook/">autotools</a> for making Erlang code available to the public.  That is a noble goal to be sure, but at this point <a href="http://www.erlware.org/tools/sinan/index.html">Sinan</a> and friends just seem like another learning curve to climb.  In addition, the only <a href="http://www.erlware.org/erlware/tutorial.html">tutorial</a> around for the build system claims that the tool is broken.</p>
<p>The TrapExit page says</p>
<blockquote><p>
You will need to download the reference build system for this tutorial, this can be found at www.erlware.org under downloads otp_base-vsn
</p></blockquote>
<p>but it doesn&#8217;t look to me like there&#8217;s a downloads section at <a href="http://www.erlware.org/">erlware.org</a>.  After some digging it appears that you can get the OTP base from <a href="http://code.google.com/p/otp-base/">Google Code</a>.  To complicate matters, there are two versions there.  It seems that <a href="http://otp-base.googlecode.com/files/otp_base-R1-1.tgz">otp_base-R1-1.tgz</a> is the stable release.  I untarred this file and got an <code>otp</code> directory and various directories beneath it.  I <code>cd otp/tools/utilities</code> and execute <code>./appgen north_zulch nz</code> (the first argument is the application name and the second argument is going to be prefixed to everything), which spewed out a bunch of osbcenities:</p>
<pre>
[: 11: ==: unexpected operator
[: 24: ==: unexpected operator
[: 18: ==: unexpected operator
[: 32: ==: unexpected operator
-- SNIP --
[: 18: ==: unexpected operator
[: 32: ==: unexpected operator
rm: missing operand
Try `rm --help' for more information.

north_zulch has been generated and placed under lib/north_zulch
north_zulch_rel has been generated and placed under release/north_zulch_rel
</pre>
<p>I'm on Ubuntu Gutsy Gibbon, and it turns out that these are because the shell scripts start with <code>#!/bin/sh</code> when they really want <code>#!/bin/bash</code>.  The error about <code>rm: missing operand</code> is because there's a command to remove Subversion directories and there aren't any in the tarball.  So I went through and changed the shebang line in <code>otp/tools/.appgen/subsitute.sh</code>, <code>otp/tools/.appgen/rename.sh</code>, and <code>otp/tools/utilities/appgen</code>.  Then I ran my command again and got</p>
<pre>
moving blank_app_rel.config.src to north_zulch_rel.config.src
moving blank_app_rel.rel.src to north_zulch_rel.rel.src
replacing %%APP_NAME%% with north_zulch in north_zulch_rel/north_zulch_rel.rel.src
moving ba_server.erl to nz_server.erl
moving ba_sup.erl to nz_sup.erl
moving blank_app.app.src to north_zulch.app.src
moving blank_app.appup.src to north_zulch.appup.src
moving blank_app.erl to north_zulch.erl
/home/rpa/Desktop/otp-diff2/tools/.appgen
replacing %%APP_NAME_UPPER_CASE%% with NORTH_ZULCH in north_zulch/Makefile
replacing %%APP_NAME_UPPER_CASE%% with NORTH_ZULCH in north_zulch/vsn.mk
replacing %%APP_NAME%% with north_zulch in north_zulch/src/Makefile
replacing %%APP_NAME_UPPER_CASE%% with NORTH_ZULCH in north_zulch/src/Makefile
replacing %%PFX%% with nz in north_zulch/src/Makefile
replacing %%APP_NAME%% with north_zulch in north_zulch/src/north_zulch.erl
replacing %%PFX%% with nz in north_zulch/src/north_zulch.erl
replacing %%PFX%% with nz in north_zulch/src/nz_sup.erl
replacing %%APP_NAME%% with north_zulch in north_zulch/src/nz_sup.erl
replacing %%PFX%% with nz in north_zulch/src/nz_server.erl
replacing %%APP_NAME%% with north_zulch in north_zulch/src/nz_server.erl
north_zulch has been generated and placed under lib/north_zulch
north_zulch_rel has been generated and placed under release/north_zulch_rel
</pre>
<p>which I am assuming means success.  As promised, this created directories <code>otp/lib/north_zulch</code> and <code>otp/release/north_zulch/rel</code> with various things beneath them.  A significant file here is <code>otp/lib/north_zulch/vsn.mk</code> which contains the version number.  I'm going to leave it at <code>1.0</code> for now.  In that same directory are <code>include</code> which are for shared macro and record definitions, and <code>src</code> where all the Erlang code files go.  Significantly, I'm going to include <code>north_zulch</code> and <code>nz</code> in everything I write here, but you'll obviously want to change that for your application.</p>
<p>In the <code>src</code> directory are various stubs.  The <code>north_zulch.erl</code> defines the "application callback module."  You can think of a callback module as an approximation to deriving from an asbract base class with virtual functions.  The function names are there, and they'll get called under certain well-defined circumstances.  It's up to you to make them do something reasonable.  There are three functions exported so that the application OTP module knows what to do with us.  <code>start/2</code> is called to get us going, <code>shutdown/0</code> is called to get us to end, and <code>stop/1</code> is called when we're all done. We look at these and compare them to the docs <a href="http://www.erlang.org/doc/design_principles/applications.html">here</a>.</p>
<pre>
start(Type, StartArgs) ->
    case nz_sup:start_link(StartArgs) of
	{ok, Pid} ->
	    {ok, Pid};
	Error ->
	    Error
    end.
</pre>
<p>We get two arguments.  <code>Type</code> is an atom that will generally be <code>normal</code> for non-distributed applications. The distributed case is more complicated, so we'll look at that later down the road.  We see that the default thing to do is to just try to run <code>nz_sup:start_link(StartArgs)</code> which starts up a Supervisor, regardless of the atom in <code>Type</code>.  This appears to be the only value that the <a href="http://www.erlang.org/doc/apps/kernel/index.html">spec</a> identifies in the non-distributed case, so we'll roll with it.  In any case, if all goes well, we have to return <code>{ok, Pid, State}</code>.  If <code>State</code> is left out, then it just uses <code>[]</code>.  We'll ignore <code>State</code> for now.  <code>Pid</code> is the process id of the main Supervisor, the boss.  If <code>start_link</code> (which we'll talk about in a sec) goes well, it gives us <code>Pid</code>.  The <code>stop/1</code> function is pretty trivial and is called after everything is done.  As far as I can tell, <code>shutdown/0</code> is not actually part of the Application interface, and is just a convenient way for you to shut down your application if you want to.  It just goes up and tells the Application module that it wants to be turned off:</p>
<pre>
shutdown() ->
    application:stop(north_zulch).
</pre>
<p>With that big file under our belt, we now look at <code>nz_sup.erl</code> which contains the code for the supervisor.  The <a href="http://www.erlang.org/doc/design_principles/sup_princ.html">Supervisor</a> (also, the <a href="http://www.erlang.org/doc/man/supervisor.html">spec</a>) is a great idea to build as a system primitive.  I think I've implemented it at least five times in various projects.  The basic idea is, manage some underlings and make sure they do their thing, while isolating yourself from their errors.  If one fails, start up another, modulo your configurable policy about such things.  The docs have more info on restart behaviors.  We export, for our own purposes, the function <code>start_link/1</code>, which got called by <code>start/1</code> in the previous file:</p>
<pre>
start_link(StartArgs) ->
    supervisor:start_link({local, ?SERVER}, ?MODULE, []).
</pre>
<p>This just turns around and tells the Supervisor API that we want to be fired up as a supervisor callback module. <code>supervisor:start_link/3</code> has three arguments.  The first is a tuple that tells the Supervisor module who we are.  The first bit of the tuple can be <code>local</code> or <code>global</code>.  The second is the name of the appropriate callback module, which in this case is <code>?SERVER</code>.  What does that mean? Well, things that start with a question mark in Erlang are macros. Up at the top of the file is</p>
<pre>
-define(SERVER, ?MODULE).
</pre>
<p>which defines it.  <code>?MODULE</code> <a href="http://erlang.org/doc/reference_manual/macros.html">is a special one</a> with the module name.  Back to <code>start_link/3</code>, we also specify the name of the callback module - this one - using <code>?MODULE</code>, and any arguments we want to pass along to <code>init/1</code>, which is the other significant function we need to export to use the supervisor:</p>
<pre>
init([]) ->
    RestartStrategy    = one_for_one,
    MaxRestarts        = 1000,
    MaxTimeBetRestarts = 3600,

    SupFlags = {RestartStrategy, MaxRestarts, MaxTimeBetRestarts},

    ChildSpecs =
	[
	 {nz_server,
	  {nz_server, start_link, []},
	  permanent,
	  1000,
	  worker,
	  [nz_server]}
	 ],
    {ok,{SupFlags, ChildSpecs}}.
</pre>
<p>This is pretty much where all the guts of the supervisor's behavior are.  The one argument you get is whatever you handed to <code>start_link/3</code> before, so you could pass around various application data if you wanted.  We're not worrying about this at the moment, though, and we're just going to look at what this gets up to.  First off, we define some variables that control the supervisor's behavior. <code>RestartStrategy</code> determines what restarting should occur should a child fail.  If <code>MaxRestarts</code> failures occur before <code>MaxTimeBetRestarts</code> seconds, then all children are cancelled and the supervisor terminates itself.  We construct a list of child specifications, that in this case only contains one element: the specs for managing the <code>nz_server</code> process.   Within this specification are:</p>
<pre>
	 {nz_server,
	  {nz_server, start_link, []},
	  permanent,
	  1000,
	  worker,
	  [nz_server]}
</pre>
<p>The first component is a name that the supervisor uses to keep track of this child.  In this case, we use the term <code>nz_server</code>, since there's only one.  The second component is a Module-Function-Arguments triplet that tells the supervisor what function should be called in the child.  We're going to look at this later, but the function is <code>start_link/0</code> in the <code>nz_server</code> module.  The next argument can be <code>permanent</code>, <code>transient</code>, or <code>temporary</code> and specifies what should happen if it dies.  The fourth argument specifies how long we should wait around for a termination signal to be handled by a child.  We can create trees of supervisors, so the fifth argument specifies whether this is a worker or a supervisor itself.  The final element will generally be a single-element list with the name of the callback module of the worker, in this case <code>nz_server</code>.  We return a tuple with these two specs together and they tell the Supervisor how it should act, and how is should initialize its children.</p>
<p>The final source file we examine is <code>nz_server.erl</code>, which implements the application-specific work.  At the very top of the file, we see</p>
<pre>
-behaviour(gen_server).
</pre>
<p>which means that it implements the <a href="http://www.erlang.org/doc/man/gen_server.html">gen_server</a> (also, <a href="http://www.erlang.org/doc/design_principles/gen_server_concepts.html">here</a>) behaviour as a callback.  The callbacks we need to define for this module to do its thing are <code>init/1</code>, <code>handle_call/3</code>, <code>handle_cast/2</code>, <code>handle_info/2</code>, <code>terminate, and </code><code>code_change/3</code>.  Again, if you come from a background like C++ or Java, you can think of these approximately as virtual event-handling functions.  Rather than an <code>onMouseClick()</code> type override, we have various functions that are called when the server receives Erlang messages.  These are all exported so that the gen_server module can get to them.</p>
<p>There are also two interface functions that are defined that don't really have anything to do with gen_server.  The first is <code>start_link/0</code>, which we mentioned before.  This is called by the Supervisor to get things going:</p>
<pre>
start_link() ->
    gen_server:start_link({local, ?SERVER}, ?MODULE, [], []).
</pre>
<p>You can see that we immediately just hand control off to the generic server.  It takes a couple of arguments.  The first is a tuple that is like the previous <code>start_link</code> in that we're telling it to look for this module and to register a name locally.  The other "local" function is <code>stop/0</code> which provides an interface to shutting down gen_server by sending it an asynchronous message.  </p>
<p>To actually do anything interesting, we'll need to implement the gen_server functions.  I'll leave that to the next installment.  We'll also look at releases, configurations and logging, which is what we said we were after in the first place!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.nonperiodic.net/blog/2008/01/23/starting-an-erlang-project-part-i/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Off On an Erlang Adventure</title>
		<link>http://www.nonperiodic.net/blog/2008/01/22/off-on-an-erlang-adventure/</link>
		<comments>http://www.nonperiodic.net/blog/2008/01/22/off-on-an-erlang-adventure/#comments</comments>
		<pubDate>Tue, 22 Jan 2008 22:57:52 +0000</pubDate>
		<dc:creator>Ryan</dc:creator>
				<category><![CDATA[Computing]]></category>
		<category><![CDATA[Erlang]]></category>
		<category><![CDATA[Gaming]]></category>

		<guid isPermaLink="false">http://www.nonperiodic.net/blog/2008/01/22/off-on-an-erlang-adventure/</guid>
		<description><![CDATA[I have decided for some reason that it would be fun to play with massively scalable systems. In particular, I thought it would be a hilarious waste of time to work on an MMO engine. I&#8217;m not sure why this seems like a good idea, given that I have more than enough on my plate [...]]]></description>
			<content:encoded><![CDATA[<p>I have decided for some reason that it would be fun to play with massively scalable systems.  In particular, I thought it would be a hilarious waste of time to work on an MMO engine.  I&#8217;m not sure why this seems like a good idea, given that I have more than enough on my plate as it is, but I justified it by saying that time that I might&#8217;ve spent <i>playing</i> a game will now be spent <i>creating</i> a game.  We&#8217;ll see how it goes.</p>
<p>For scalability, and for an excuse to learn something new, I thought I&#8217;d play with <a href="http://erlang.org">Erlang</a>.  Erlang is a functional programming language that is completely geared toward concurrency.  It&#8217;s not so fast with the number-crunching we&#8217;d expect to do with a game for physics and collision detection, but it is really well-suited for having zillions of semi-independent entities wandering around.  Hopefully we can figure out a way to offload hard core number crunching to C via an FFI interface of some kind, but we&#8217;ll cross that bridge when we get to it.  For now, I&#8217;m just trying to learn how to build a real-life application in Erlang.</p>
<p>Most of the documentation on Erlang seems to revolve around learning functional programming.  I feel pretty good about FP already, due to having taken <a href="http://sicp.csail.mit.edu/">6.001</a> back in the day.  Tutorials about implementing the factorial function in Erlang aren&#8217;t really what I&#8217;m looking for.  I&#8217;ve ordered <a href="http://www.amazon.com/gp/product/193435600X?ie=UTF8&#038;tag=nonperiodicce-20&#038;linkCode=xm2&#038;camp=1789&#038;creativeASIN=193435600X">Programming Erlang</a> from Amazon and it&#8217;s due to arrive on Friday, so hopefully that&#8217;ll get me going.  Stay tuned and maybe this will all be useful to you, too.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.nonperiodic.net/blog/2008/01/22/off-on-an-erlang-adventure/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
