<?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>Marzhill Musings</title>
	<atom:link href="http://jeremy.marzhillstudios.com/index.php/feed/" rel="self" type="application/rss+xml" />
	<link>http://jeremy.marzhillstudios.com</link>
	<description>Talkin and Thinkin about Collaborative Technologies and Open Source</description>
	<lastBuildDate>Sat, 27 Jun 2009 18:13:20 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Really liking the new kde4</title>
		<link>http://jeremy.marzhillstudios.com/index.php/site-news/really-liking-the-new-kde4/</link>
		<comments>http://jeremy.marzhillstudios.com/index.php/site-news/really-liking-the-new-kde4/#comments</comments>
		<pubDate>Sat, 27 Jun 2009 18:13:20 +0000</pubDate>
		<dc:creator>zaphar</dc:creator>
				<category><![CDATA[Site News]]></category>
		<category><![CDATA[desktop enviroment]]></category>
		<category><![CDATA[gnome]]></category>
		<category><![CDATA[kde]]></category>

		<guid isPermaLink="false">http://jeremy.marzhillstudios.com/?p=326</guid>
		<description><![CDATA[I just recently upgraded my home desktop. It was nearing 10 years in age and desperately whispering to me in my sleep that it wasn&#8217;t going to last much longer.
The new machine is a Quad core AMD phenom with A Gigabyte board and 8 gig of ram.
This of course necessitated a new OS to go [...]]]></description>
			<content:encoded><![CDATA[<p>I just recently upgraded my home desktop. It was nearing 10 years in age and desperately whispering to me in my sleep that it wasn&#8217;t going to last much longer.</p>
<p>The new machine is a Quad core AMD phenom with A Gigabyte board and 8 gig of ram.</p>
<p>This of course necessitated a new OS to go along with the shiny new hardware, so along comes Ubuntu Jaunty with its 64-bit joy and the shiny new KDE4 desktop.</p>
<p>I had previously switched from kde to gnome despite being a kde fan for years because gnome had just begun to feel more cohesive. I still disliked the lack of configurability as compared to gnome but overall gnome felt better.</p>
<p>But with the new kde4 I&#8217;ve come back. Plasma and the kde desktop have really upped the game. The whole experience has vastly improved and kde no longer feels like it&#8217;s lagging behind but has leaped ahead of the competition. If you haven&#8217;t checked it out yet you should give it a try.</p>
]]></content:encoded>
			<wfw:commentRss>http://jeremy.marzhillstudios.com/index.php/site-news/really-liking-the-new-kde4/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Advanced Nitrogen Elements</title>
		<link>http://jeremy.marzhillstudios.com/index.php/site-news/advanced-nitrogen-elements/</link>
		<comments>http://jeremy.marzhillstudios.com/index.php/site-news/advanced-nitrogen-elements/#comments</comments>
		<pubDate>Wed, 17 Jun 2009 04:33:58 +0000</pubDate>
		<dc:creator>zaphar</dc:creator>
				<category><![CDATA[Site News]]></category>
		<category><![CDATA[erlang]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[nitrogen]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[web framework]]></category>

		<guid isPermaLink="false">http://jeremy.marzhillstudios.com/?p=301</guid>
		<description><![CDATA[In my last post I walked you through creating a basic nitrogen element. In this one I'll be covering some of the more advanced topics in nitrogen elements. 
<ul>
	<li>Event handlers and delegation</li>
	<li>scripts and dynamic javascript postbacks</li>
</ul>]]></description>
			<content:encoded><![CDATA[<p>In my <a href="http://jeremy.marzhillstudios.com/index.php/site-news/creating-custom-nitrogen-elements/">last post</a> I walked you through creating a basic nitrogen element. In this one I&#8217;ll be covering some of the more advanced topics in nitrogen elements.</p>
<ul>
<li>Event handlers and delegation</li>
<li>scripts and dynamic javascript postbacks</li>
</ul>
<h3>Nitrogen Event handlers</h3>
<p>Nitrogen event handlers get called for any nitrogen event. A nitrogen event is specified by assigning #event to an actions attribute of a nitrogen element. The event handler in the pages module will get called with the postback of the event. Postbacks are an attribute of the event record and define the event that was fired. To handle the event you create an event function in the target module that matches your postback. For Example:</p>
<p>[erlang light="true"]<br />
% given this event<br />
#event{ type=click, postback={click, Id} }</p>
<p>% this event function would handle it<br />
event({click, ClickedId}) -&gt;<br />
io:format(&quot;I [~p] was clicked&quot;, [ClickedId])<br />
.<br />
[/erlang]</p>
<p>Erlangs pattern matching makes it especially well suited for this kind of event based programming. The one annoying limitation of this event though is that each page has to handle it individually. You could of course create a dispatching module that handled the event for you but why when nitrogen already did it for you. You can delegate an event to a specific module by setting the delegate attribute to the atom identifying that module.</p>
<p>[erlang light="true"]<br />
% delgated event<br />
#event{ type=click, postback={click, Id}, delegate=my_module }<br />
[/erlang]</p>
<p>You can delgate to any module you want. I use the general rule of thumb that if the event affects other elements on the page then the page module should probably handle it. If, however, the event doesn&#8217;t affect other elements on the page then the element&#8217;s module can handle it.</p>
<h3>Scripts and Dynamic Postback</h3>
<p>Now lets get make it a little more interesting. Imagine a scenario where we want to interact with some javascript on a page and dynamically generate data to send back to nitrogen. As an example lets create a silly element that grabs the mouse coordinates of a click on the element and sends that back to nitrogen. A first attempt might look something like so:</p>
<p>[erlang light="true"]<br />
-record(silly, {?ELEMENT_BASE(element_silly)}).<br />
[/erlang]</p>
<p>And the module is likewise simple:</p>
<p>[erlang]<br />
-module(element_silly).<br />
-compile(export_all).</p>
<p>-include(&quot;elements.hrl&quot;).<br />
-include_lib(&quot;nitrogen/include/wf.inc&quot;).</p>
<p>render(ControlId, R) -&gt;<br />
    Id = wf:temp_id(),<br />
    %% wait!! where do we get the loc from?!<br />
    ClickEvent = #event{type=click, postback={click, Loc}}<br />
    Panel = #panel{id=Id, style=&quot;width:&#8217;100px&#8217;; height=&#8217;100px&#8217;&quot;,<br />
    actions=ClickEvent},<br />
    element_panel:render(Panel)<br />
.</p>
<p>event({click, Loc}) -&gt;<br />
    wf:update(body, wf:f(&quot;you clicked at point: ~s&quot;, Loc))<br />
.<br />
[/erlang]</p>
<p>Well of course you spot the problem here. Since the click happens client side we don&#8217;t know what to put in the Loc variable for the postback. A typical postback won&#8217;t work because the data will be generated in the client and not the Nitrogen server. So how could we get the value of the coordinates sent back?</p>
<p>The javascript to grab the coordinates with jquery looks like this:</p>
<p>[javascript light="true"]<br />
var coord = obj(&#8216;me&#8217;).pageX + obj(&#8216;me&#8217;).pageY;<br />
[/javascript]</p>
<p>To plug that in to the click event is pretty easy since action fields in an event can hold other events or javascript or a list combining both<br />
:</p>
<p>[erlang light="true"]<br />
Script = &quot;var coord = obj(&#8216;me&#8217;).pageX + obj(&#8216;me&#8217;).pageY;&quot;,<br />
ClickEvent = #event{type=click, postback={click, Loc}, actions=Script}<br />
[/erlang]</p>
<p>Now we&#8217;ve managed to capture the coordinates of the mouse click, but we still haven&#8217;t sent it back to the server.</p>
<p>This javascript needs a little help. What we need is a drop box. Lets enhance our element with a few helpers:</p>
<p>[erlang]<br />
-module(element_silly).<br />
-compile(export_all).</p>
<p>-include(&quot;elements.hrl&quot;).<br />
-include_lib(&quot;nitrogen/include/wf.inc&quot;).</p>
<p>render(ControlId, R) -&gt;<br />
    Id = wf:temp_id(),<br />
    DropBoxId = wf:temp_id(),<br />
    MsgId = wf:temp_id(),<br />
    Script = wf:f(&quot;var coord = obj(&#8216;me&#8217;).pageX + obj(&#8216;me&#8217;).pageY; $(&#8216;~s&#8217;).value = coord;&quot;,<br />
        [DropBoxId]),<br />
    ClickEvent = #event{type=click, postback={click, Id, MsgId}, actions=Script}<br />
    Panel = #panel{id=Id, style=&quot;width:&#8217;100px&#8217;; height=&#8217;100px&#8217;&quot;,<br />
    actions=ClickEvent, body=[#hidden{id=DropBoxId}, #panel{id=MsgId}]},<br />
    element_panel:render(Panel)<br />
.</p>
<p>event({click, Id, Msg}) -&gt;<br />
    Loc = hd(wf:q(Id)),<br />
    wf:update(Msg, wf:f(&quot;you clicked at point: ~s&quot;, Loc))<br />
.<br />
[/erlang]</p>
<p>Ahhh there we go. Now our element when clicked will:</p>
<ol>
<li>use javascript to grab the coordinates of the mouse click</li>
<li>use javascript to store those coordinates in the hidden element</li>
<li>use a postback to send the click event back to a nitrogen event handler with the id of the hidden element where it stored the coordinates.</li>
</ol>
<p>We have managed to grab dynamically generated data from the client side and drop it somehwere that nitrogen can retrieve it. In the process we have used an event handler, custom javascript, and dynamic javascript postbacks.</p>
<p><strong>Edit</strong>: Corrected typo &#8211; June 16, 2009 at 11:40 pm</p>
]]></content:encoded>
			<wfw:commentRss>http://jeremy.marzhillstudios.com/index.php/site-news/advanced-nitrogen-elements/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Creating Custom Nitrogen Elements</title>
		<link>http://jeremy.marzhillstudios.com/index.php/site-news/creating-custom-nitrogen-elements/</link>
		<comments>http://jeremy.marzhillstudios.com/index.php/site-news/creating-custom-nitrogen-elements/#comments</comments>
		<pubDate>Sat, 23 May 2009 00:05:57 +0000</pubDate>
		<dc:creator>zaphar</dc:creator>
				<category><![CDATA[Site News]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[erlang]]></category>
		<category><![CDATA[event driven]]></category>
		<category><![CDATA[nitrogen]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[web framework]]></category>

		<guid isPermaLink="false">http://jeremy.marzhillstudios.com/?p=232</guid>
		<description><![CDATA[Nitrogen is a web framework written in erlang for Fast AJAX Web applications. You can get Nitrogen on github Nitrogen comes with a set of useful controls, or elements in nitrogen parlance, but if you are going to do anything more fancy than a basic hello world you probably want to create some custom controls. [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://github.com/rklophaus/nitrogen/tree/master">Nitrogen</a> is a web framework written in erlang for Fast AJAX Web applications. You can get <a href="http://github.com/rklophaus/nitrogen/tree/master">Nitrogen on github</a> Nitrogen comes with a set of useful controls, or elements in nitrogen parlance, but if you are going to do anything more fancy than a basic hello world you probably want to create some custom controls. This tutorial will walk you through the ins and outs of writing a custom element for Nitrogen. We will be creating a simple notification element similar to one I use in the Iterate! project. It will need to be able to:</p>
<ul>
<li> show a message</li>
<li>have a way to dismiss it</li>
<li> and optionally expire and disappear after a configurable period of time</li>
</ul>
<p>Every Nitrogen element has two main pieces: the Record and the Module. I&#8217;ll go through each in order and walk you through creating our notification element.</p>
<h2>The Record</h2>
<p>The record defines all the state required to create a nitrogen element. Every record needs a certain base set of fields. These fields can be added to your record with the ?ELEMENT_BASE macro. The macro is available in the nitrogen include file wf.inc. That include file also gives you access to all the included nitrogen element records. Below you can see the record definition for our notify element. Since it is very simple in it&#8217;s design it only needs the base elements and two additional fields. expire to handle our optional expiration time and default to false to indicate no expiration. msg to hold the contents of our notification.</p>
<p>[erlang light="true"]<br />
%Put this line in an include file for your elements<br />
-record(notify, {?ELEMENT_BASE(element_notify), expire=false, msg}).<br />
[/erlang]</p>
<p>[erlang light="true"]<br />
% put these at the top of your elements module<br />
-include_lib(&quot;nitrogen/include/wf.inc&quot;).<br />
% the above mentioned include file you may call it whatever you want<br />
-include(&quot;elements.inc&quot;).<br />
[/erlang]</p>
<p>The ELEMENT_BASE macro gives your element several fields and identifies for the element which module handles the rendering of your nitrogen element. You can specify any module you want but the convention is to name the module with element_element_name. The fields provided are: id, class, style, actions, and show_if. You can use them as you wish when it comes time to render your element. Which brings us to the module.</p>
<h2>The Module</h2>
<p>Of the two pieces of a nitrogen element the module does the manual labor. It renders and in some cases defines the handlers for events fired by the element. The module must export a render/2 function. This function will be called whenever nitrogen needs to render a particular instance of your element. It&#8217;s two arguments are: The ControlId, and the Record defining this element instance. Of these the ControlID is probably the least understood. It is passed into your render method by nitrogen and is the assigned HTML Id for your particular element. This is important to understand because, when you call the next render method in your elements tree, you will have to pass an ID on. The rule of thumb I use is that if you want to use a different Id for your toplevel element then you can ignore the ControlId. Otherwise you should use it as the id for your toplevel element in the control.</p>
<p>So your element&#8217;s module should start out with something like this:</p>
<p>[erlang]<br />
-module(element_notify).<br />
-compile(export_all).</p>
<p>-include_lib(&quot;nitrogen/include/wf.inc&quot;).<br />
-include(&quot;elements.hrl&quot;).</p>
<p>% give us a way to inspect the fields of this elements record<br />
% useful in the shell where record_info isn&#8217;t available<br />
reflect() -&gt; record_info(fields, notify).</p>
<p>% Render the custom element<br />
render(ControlId, R) -&gt;<br />
    % get a temp id for our notify element instance<br />
    Id = ControlId,<br />
    % Our toplevel of the element will be a panel (div)<br />
    Panel = #panel{id=Id},<br />
    % the element_panel module is used to render the panel element<br />
    element_panel:render(Id, Panel),<br />
    % Or use the alternative method:<br />
    Module = Panel#panel.module,<br />
    Module:render(Id, Panel),<br />
.<br />
[/erlang]</p>
<p>Notice that the records module attribute tells us what module we should call to render the element in the alternative method. In our case we will just hardcode the module since it&#8217;s known to us.</p>
<p>So now we have a basic element that renders a div with a temp id to our page. That&#8217;s not terribly useful though. We actually need this element to render our msg, and with some events attached. Lets add the code to add our message to the panels contents.</p>
<p>[erlang light="true"]<br />
Panel = #panel{id=Id, body=R#notify.msg},<br />
element_panel:render(ControlId, Panel)<br />
[/erlang]</p>
<p>Now whatever is in the msg attribute of our notify record will be in the body of the panel when it gets rendered. All we need is a way to dismiss it. A link should do the trick. But now we have a slight problem. In order to add our dismiss link we need to add it to the body of the Panel. but the msg is already occupying that space. We could use a list and prepend the link to the end of the list for the body but that doesn&#8217;t really give us a lot of control over styling the element. what we really need is for the msg to be in an inner panel and the outer panel will hold any controls the element needs.</p>
<p>[erlang light="true"]<br />
Link = #link{text=&quot;dismiss&quot;},<br />
InnerPanel = #panel{body=R#notify.msg},<br />
Panel = #panel{id=Id, body=[InnerPanel,Link]}<br />
element_panel:render(ControlId, Panel)<br />
[/erlang]</p>
<p>Our link doesn&#8217;t actually dismiss the notification yet though. To add that we need to add a click event to the link. Nitrogen has a large set of events and effects available. You can find them . We will be using the click event and the hide effect.</p>
<p>[erlang light="true"]<br />
Event = #event{type=click, actions=#hide{effect=blind, target=Id}},<br />
Link = #link{text=&quot;dismiss&quot;, actions=Event},<br />
[/erlang]</p>
<p>Now our module should look something like this:</p>
<p>[erlang]<br />
-module(element_notify).</p>
<p>-compile(export_all).<br />
-include_lib(&quot;nitrogen/include/wf.inc&quot;).<br />
-include(&quot;elements.hrl&quot;).</p>
<p>% give us a way to inspect the fields of this elements record<br />
% useful in the shell where record_info isn&#8217;t available<br />
reflect() -&gt; record_info(fields, notify).</p>
<p>% Render the custom element<br />
render(ControlId, R) -&gt;<br />
    % get a temp id for our notify element instance<br />
    Id = ControlId,<br />
    % Our toplevel of the element will be a panel (div)<br />
    Event = #event{type=click, actions=#hide{effect=blind, target=Id}},<br />
    Link = #link{text=&quot;dismiss&quot;, actions=Event},<br />
    InnerPanel = #panel{body=R#notify.msg},<br />
    Panel = #panel{id=Id, body=[InnerPanel,Link]}<br />
    element_panel:render(ControlId, Panel)<br />
    % the element_panel module is used to render the panel element<br />
    element_panel:render(Id, Panel)<br />
.<br />
[/erlang]</p>
<p>This is a fully functional nitrogen element. But it&#8217;s missing a crucial feature to really shine. Our third feature for this element was an optional expiration for the notification. Right now you have to click dismiss to get rid of the element on the page. But sometimes we might want the element to go away after a predetermined time. This is what our expire record field is meant to determine for us. There are three possible cases for this field.</p>
<ul>
<li>set to false (the default)</li>
<li>set to some integer (the number of seconds after which we want to go away)</li>
<li>set to anything else (the error condition)</li>
</ul>
<p>This is the kind of thing erlang&#8217;s case statement was made for:</p>
<p>[erlang light="true"]<br />
case R#notify.expire of<br />
    false -&gt;<br />
        undefined;<br />
    N when is_integer(N) -&gt;<br />
        % we expire in this many seconds<br />
        wf:wire(Id, #event{type=&#8217;timer&#8217;, delay=N,<br />
            actions=#hide{effect=blind, target=Id}});<br />
    _ -&gt;<br />
        % log error and don&#8217;t expire<br />
        undefined<br />
end<br />
[/erlang]</p>
<p>Notice the wf:wire statement. wf:wire is an alternate way to add events to a nitrogen element. Just specify the id and then the event record/javascript string you want to use. I&#8217;ve noticed that for events of type timer wf:wire works better than assigning them to the actions field of the event record. No idea why because I have not looked into it real closely yet.</p>
<p>Now our module looks like this:</p>
<p>[erlang]<br />
-module(element_notify).</p>
<p>-compile(export_all).<br />
-include_lib(&quot;nitrogen/include/wf.inc&quot;).<br />
-include(&quot;elements.hrl&quot;).</p>
<p>% give us a way to inspect the fields of this elements record<br />
% useful in the shell where record_info isn&#8217;t available<br />
reflect() -&gt; record_info(fields, notify).</p>
<p>% Render the custom element<br />
render(_, R) -&gt;<br />
    % get a temp id for our notify element instance<br />
    Id = ControlId,<br />
    % Our toplevel of the element will be a panel (div)<br />
    case R#notify.expire of<br />
        false -&gt;<br />
            undefined;<br />
        N when is_integer(N) -&gt;<br />
            % we expire in this many seconds<br />
            wf:wire(Id, #event{type=&#8217;timer&#8217;, delay=N,<br />
                actions=#hide{effect=blind, target=Id}});<br />
        _ -&gt;<br />
            % log error and don&#8217;t expire<br />
            undefined<br />
    end,<br />
    Event = #event{type=click, actions=#hide{effect=blind, target=Id}},<br />
    Link = #link{text=&quot;dismiss&quot;, actions=Event},<br />
    InnerPanel = #panel{body=R#notify.msg},<br />
    Panel = #panel{id=Id, body=[InnerPanel,Link]}<br />
    element_panel:render(ControlId, Panel)<br />
    % the element_panel module is used to render the panel element<br />
    element_panel:render(Id, Panel)<br />
.<br />
[/erlang]</p>
<p>We have now fulfilled all of our criteria for the element. It shows a message of our choosing. It can be dismissed with a click. And it has an optional expiration. One last thing to really polish it off though would to allow styling through the use of css classes. The ELEMENT_BASE macro we used in our record definition gives our element a class field. We can use that to set our Panel&#8217;s class, allowing any user of the element to set the class as they wish like so:</p>
<p>[erlang light="true"]<br />
Panel = #panel{id=Id, class=[&quot;notify &quot;, R#notify.class],<br />
body=[InnerPanel,Link]},<br />
[/erlang]</p>
<p>This gives us the final module for our custom element:</p>
<p>[erlang]<br />
-module(element_notify).<br />
-compile(export_all).&lt;/p&gt;</p>
<p>-include_lib(&quot;nitrogen/include/wf.inc&quot;).<br />
-include(&quot;elements.hrl&quot;).</p>
<p>% give us a way to inspect the fields of this elements record<br />
% useful in the shell where record_info isn&#8217;t available<br />
reflect() -&gt; record_info(fields, notify).</p>
<p>% Render the custom element<br />
render(_, R) -&gt;<br />
    % get a temp id for our notify element instance<br />
    Id = ControlId,<br />
    % Our toplevel of the element will be a panel (div)<br />
    case R#notify.expire of<br />
        false -&gt;<br />
            undefined;<br />
        N when is_integer(N) -&gt;<br />
            % we expire in this many seconds<br />
            wf:wire(Id, #event{type=&#8217;timer&#8217;, delay=N,<br />
                actions=#hide{effect=blind, target=Id}});<br />
        _ -&gt;<br />
            % log error and don&#8217;t expire<br />
            undefined<br />
    end,<br />
    Event = #event{type=click, actions=#hide{effect=blind, target=Id}},<br />
    Link = #link{text=&quot;dismiss&quot;, actions=Event},<br />
    InnerPanel = #panel{body=R#notify.msg},<br />
    Panel = #panel{id=Id, class=[&quot;notify &quot;, R#notify.class],<br />
    body=[InnerPanel,Link]},<br />
    element_panel:render(ControlId, Panel)<br />
    % the element_panel module is used to render the panel element<br />
    element_panel:render(Id, Panel)<br />
.<br />
[/erlang]</p>
<p>I will cover delegated events and more advanced topics in a later tutorial.</p>
]]></content:encoded>
			<wfw:commentRss>http://jeremy.marzhillstudios.com/index.php/site-news/creating-custom-nitrogen-elements/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>erlang datetime utility functions</title>
		<link>http://jeremy.marzhillstudios.com/index.php/site-news/erlang-datetime-utility-functions/</link>
		<comments>http://jeremy.marzhillstudios.com/index.php/site-news/erlang-datetime-utility-functions/#comments</comments>
		<pubDate>Fri, 01 May 2009 06:17:21 +0000</pubDate>
		<dc:creator>zaphar</dc:creator>
				<category><![CDATA[Site News]]></category>
		<category><![CDATA[datetime]]></category>
		<category><![CDATA[erlang]]></category>
		<category><![CDATA[utility functions]]></category>

		<guid isPermaLink="false">http://jeremy.marzhillstudios.com/?p=227</guid>
		<description><![CDATA[I&#8217;ve been doing some work on timeseries data in erlang for iterate graphs and found the calendar module in stdlib to be lacking in some useful features. So being the helpful hacker I am I created a utility module to wrap calendar and be a little more userfriendly. May I present date_util.erl: [gist id="104903"]
]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been doing some work on timeseries data in erlang for iterate graphs and found the calendar module in stdlib to be lacking in some useful features. So being the helpful hacker I am I created a utility module to wrap calendar and be a little more userfriendly. May I present date_util.erl: [gist id="104903"]</p>
]]></content:encoded>
			<wfw:commentRss>http://jeremy.marzhillstudios.com/index.php/site-news/erlang-datetime-utility-functions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Functional Programming vs OO Programming</title>
		<link>http://jeremy.marzhillstudios.com/index.php/site-news/fp-vs-oo-programming/</link>
		<comments>http://jeremy.marzhillstudios.com/index.php/site-news/fp-vs-oo-programming/#comments</comments>
		<pubDate>Mon, 27 Apr 2009 01:52:39 +0000</pubDate>
		<dc:creator>zaphar</dc:creator>
				<category><![CDATA[Site News]]></category>
		<category><![CDATA[comparison]]></category>
		<category><![CDATA[erlang]]></category>
		<category><![CDATA[functional programming]]></category>
		<category><![CDATA[insanity]]></category>
		<category><![CDATA[OO]]></category>

		<guid isPermaLink="false">http://jeremy.marzhillstudios.com/?p=211</guid>
		<description><![CDATA[I&#8217;ve been thinking lately about the differences between OO and FP. FP languages don&#8217;t really support the OO model because of a difference in design. Some try but the &#8220;true&#8221; functional languages make no such effort and for good reason. One of the primary principles of OO programming is the black box. An object is [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been thinking lately about the differences between <abbr title="Object Oriented">OO</abbr> and <abbr title="Functional programming">FP</abbr>. FP languages don&#8217;t really support the OO model because of a difference in design. Some try but the &#8220;true&#8221; functional languages make no such effort and for good reason. One of the primary principles of OO programming is the black box. An object is meant to represent some entity in the system. All the state and valid actions for that entity are encapsulated in the Object and the only visibility you have into them is the interface the object provides to the outside world. Programs tend to be defined as a set of interactions between objects. FP takes a different approach. In FP data is not modifiable only transformable by functions. In FP the functions expect certain input and give back certain output for that input. They certainly don&#8217;t maintain any state on their own. You can&#8217;t have an object if you can&#8217;t have modifiable internal state.</p>
<p>In OO you are encouraged to group together state and activity on that state. In OO you don&#8217;t think so much about state as you do about entities. Person, Car, ATM machine. All of these are commonly referenced objects in an OO tutorial or textbook. Consumers of your object are encouraged not to think about the state of a person or a car or an ATM machine. Instead they think in terms of allowable interactions with that object: Talk, Drive, Withdraw Money. Within OO code there are a huge number of possible orders of various interactions possible. So large they are just about impossible to completely test or even visualize.</p>
<p>For example say I&#8217;m programming a person object. I&#8217;ve given the person object a handshake method. However, depending on the internal state of the person object that method may or may not work the same way or be supposed to be called. Maybe the person object is in a bad mood, in which case the handshake method is non-functional. How do we handle that? Hrmm, so first before calling handshake on the person object we should call the offer hand method. No wait, before we call the offer hand method, perhaps we should look at their face first to gauge their mood. This could get complicated pretty quickly. Furthermore there is nothing in the OO language that allows us to specify that the offer hand method should happen first. We obviously need to know quite a bit about the state of that person object in order to properly interact with it.</p>
<p>Contrast that with an FP approach. This gets a little bit simpler for some people to visualize suddenly. Rather than an object, they see state and  a set of possible transformations of that state. the state may be something like this. person1 mood, person2 mood. and there is an interact function. If the person1 and person2 mood is good then the interact function offers hand for handshake and the two shake hands then interact returns the new person1 mood and person2 mood. Or if the mood of one of them is bad then do some other action then return new person1 mood and person 2 mood. By placing the emphasis on the state involved the coder has reduced the problem to a set of possible transformations based on that state.</p>
<p>In OO, an object&#8217;s methods define the interface. but passing the same input to an object will not always result in the same output. Most of the time methods modify internal state and the return depends on the internal state. At any time in your code the internal state of an object must be treated as an unknown. This means the return of your objects method must also be treated as an unknown. Every object has to treat every other object like it has some sort of mental disease and could have a psychotic break any moment. It could do just about anything and if you didn&#8217;t define the proper response to what they do then who knows what might happen.</p>
<p>In FP you are encouraged to think in terms of state transformations. You are forced to consider what the state you are dealing with is and then transform that state appropriately. Since the state is of primary importance after a while FP feels more natural than OO to certain mindsets. I&#8217;m discovering that I rather like the FP mindset and miss OO less and less these days.</p>
<hr />
Glossary:</p>
<dl>
<dt>FP</dt>
<dd>Functional Programming</dd>
<dt>OO</dt>
<dd>Object Oriented</dd>
</dl>
]]></content:encoded>
			<wfw:commentRss>http://jeremy.marzhillstudios.com/index.php/site-news/fp-vs-oo-programming/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Mnesia and Schema upgrades.</title>
		<link>http://jeremy.marzhillstudios.com/index.php/site-news/mnesia-and-schema-upgrades/</link>
		<comments>http://jeremy.marzhillstudios.com/index.php/site-news/mnesia-and-schema-upgrades/#comments</comments>
		<pubDate>Fri, 17 Apr 2009 00:41:41 +0000</pubDate>
		<dc:creator>zaphar</dc:creator>
				<category><![CDATA[Site News]]></category>
		<category><![CDATA[databases]]></category>
		<category><![CDATA[erlang]]></category>
		<category><![CDATA[mnesia]]></category>
		<category><![CDATA[upgrades]]></category>

		<guid isPermaLink="false">http://jeremy.marzhillstudios.com/?p=183</guid>
		<description><![CDATA[I had an epiphany or sorts the other day. While working on iterate I realized that I was going to need to upgrade the schema of my mnesia tables. Schema changes on databases often mean bringing down the application. At least they usually have in my experience anyway. I hate to upgrade databases. That is [...]]]></description>
			<content:encoded><![CDATA[<p>I had an epiphany or sorts the other day. While working on iterate I realized that I was going to need to upgrade the schema of my mnesia tables. Schema changes on databases often mean bringing down the application. At least they usually have in my experience anyway. I hate to upgrade databases. That is I did until I met erlang and mnesia.</p>
<p>The issue is that my mnesia schema for some tables was using a user provided name for the primary key. This was fine while it was just a prototype but now it was time for it to grow up. The record describing the table had to change and all the records in a table had to change. Now no one is really using this right now so I had a choice.</p>
<ul>
<li>Blow away the database and rebuild it.</li>
<li>Be all erlang&#8217;y and stuff and do it live.</li>
</ul>
<p>Wait a minute did he just say &#8220;live&#8221;? You can&#8217;t update the schema and convert all the records live. That&#8217;s crazy! </p>
<p>Ahhh but this is erlang we do things different here. Witness the glory of iterate&#8217;s db_migrate_tools:</p>
<p>[gist id='96772']</p>
<p>Notice, the transform_stories function. It defines an anonymous fun it uses to transform the mnesia table with. Currently this function only has one signature. There is no reason it can&#8217;t have more thoug. Since, erlang allows multiple signatures for anonymous functions, I can specify a signature for the next version of the mnesia table if/when it changes again. </p>
<p>Here&#8217;s the epiphany part. I can keep updating that fun with more signatures for each version of the table. Theoretically ,if I were to end up with a table that had  records of multiple different historical types in it, I would be able to use this one transform function to get them all updated to the new record type. And I can do this all live without taking down the database or app. I can ship each iterate version with a module capable of updating the database live from any previous version. Now that&#8217;s power that&#8217;s useful. Try doing that with another platform.</p>
]]></content:encoded>
			<wfw:commentRss>http://jeremy.marzhillstudios.com/index.php/site-news/mnesia-and-schema-upgrades/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Demo of Iterate! erlang project number two is up</title>
		<link>http://jeremy.marzhillstudios.com/index.php/site-news/demo-of-iterate-erlang-project-number-two-is-up/</link>
		<comments>http://jeremy.marzhillstudios.com/index.php/site-news/demo-of-iterate-erlang-project-number-two-is-up/#comments</comments>
		<pubDate>Sun, 12 Apr 2009 03:08:25 +0000</pubDate>
		<dc:creator>zaphar</dc:creator>
				<category><![CDATA[Site News]]></category>
		<category><![CDATA[erlang]]></category>
		<category><![CDATA[iterate]]></category>
		<category><![CDATA[nitrogen]]></category>

		<guid isPermaLink="false">http://jeremy.marzhillstudios.com/?p=179</guid>
		<description><![CDATA[Iterate! is my Scrum style project management tool. Inspired by my dislike for XPlanners UI. Iterate! was started about a month ago and is coded in erlang using mochiweb, and nitrogen.
Kick the tires and whatnot if you want to see it in action:
http://iterate.marzhillstudios.com:8001/
]]></description>
			<content:encoded><![CDATA[<p>Iterate<em>!</em> is my Scrum style project management tool. Inspired by my dislike for XPlanners UI. Iterate<em>!</em> was started about a month ago and is coded in <a href="http://erlang.org/">erlang</a> using <a href="http://code.google.com/p/mochiweb/">mochiweb</a>, and <a href="http://nitrogenproject.com/">nitrogen</a>.<br />
Kick the tires and whatnot if you want to see it in action:</p>
<p><a href="http://iterate.marzhillstudios.com:8001/">http://iterate.marzhillstudios.com:8001/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://jeremy.marzhillstudios.com/index.php/site-news/demo-of-iterate-erlang-project-number-two-is-up/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Error handling (Erlang vs Other languages)</title>
		<link>http://jeremy.marzhillstudios.com/index.php/site-news/error-handling-erlang-vs-other-languages/</link>
		<comments>http://jeremy.marzhillstudios.com/index.php/site-news/error-handling-erlang-vs-other-languages/#comments</comments>
		<pubDate>Sat, 11 Apr 2009 14:59:12 +0000</pubDate>
		<dc:creator>zaphar</dc:creator>
				<category><![CDATA[Site News]]></category>
		<category><![CDATA[best practices]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[erlang]]></category>
		<category><![CDATA[functional programming]]></category>

		<guid isPermaLink="false">http://jeremy.marzhillstudios.com/?p=168</guid>
		<description><![CDATA[When I'm in Perl, Javascript, Java, or any other programming language I prefer to throw exceptions rather than return errors. This is because I've long since gotten tired of losing errors 5 calls deep in the code because I forgot to check the return and handle it.
...
In erlang however returning errors actually turns out to be useful. This is because in erlang returning errors actually has the desired effect.]]></description>
			<content:encoded><![CDATA[<p>When I&#8217;m in Perl, Javascript, Java, or any other programming language I prefer to throw exceptions rather than return errors. This is because I&#8217;ve long since gotten tired of losing errors 5 calls deep in the code because I forgot to check the return and handle it. Nothing is more annoying than trying to debug a problem that is actually caused somewhere else, but you don&#8217;t know because the error vanished into the that Great Heap in the Sky around about 5 calls down. You&#8217;ve been there before. That&#8217;s when you start adding print statements followed by an exit or, if your lucky enough to have one, firing up the debugger and using break statements to narrow down the actual source of the problem. This process could take days depending on how far removed from the breaking code the actual problem is. In erlang, however, returning errors actually turns out to be useful. This is because in erlang returning errors actually has the desired effect.</p>
<p>Usually, when you return errors in an app, it is because you don&#8217;t want to kill the whole program when something breaks. What you intend is for the caller to inspect the return and do the appropriate thing. This however runs smack into the whole</p>
<blockquote><p>programmers are fallible people, who sometimes stay up late coding at 3am, when they can hardly see the screen anymore</p></blockquote>
<p>problem. In short you are depending on the caller to honor your contract and do the right thing even though we often do exactly the wrong thing. Even when you are the caller, sometimes you don&#8217;t honor that contract. Then a month later you are doing that print statement and die or perhaps the debugger dance again. All of this because of one night when your judgement lapsed.  Companies will often develop elaborate style guides, testing strategy, and code-review cultures to prevent this, but in the end most developers I know come to love throwing exceptions&#8230; unless they are coding in erlang. This is because of two elements of the erlang language design:</p>
<ul>
<li>Pattern Matching</li>
<li>and Fail Fast.</li>
</ul>
<p>In erlang returning errors <strong>requires</strong> the caller to handle them. If I try to store the return of a function and it doesn&#8217;t match what I told it to expect then <strong>bang,</strong> an automatic exception. However, if I try to store the return and explicitely handle the error case then no exception is thrown. This has the wonderful effect of forcing me to think about exactly what I expect this function to return, and handling or ignoring at my choice. The big benefit is that I had to think about it. The below example illustrates the difference.</p>
<p>[gist: id="93574"]</p>
<p>The combination of Pattern Matching and Fail Fast in erlang forces the programmer to honor the contract, whether he wants to or not. This is one case where Erlang follows the &#8220;Do What I Need Not What I Want&#8221; principle in a language properly.</p>
]]></content:encoded>
			<wfw:commentRss>http://jeremy.marzhillstudios.com/index.php/site-news/error-handling-erlang-vs-other-languages/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Twitter and the Saga in 140 character chunks</title>
		<link>http://jeremy.marzhillstudios.com/index.php/site-news/twitter-and-the-saga-in-140-character-chunks/</link>
		<comments>http://jeremy.marzhillstudios.com/index.php/site-news/twitter-and-the-saga-in-140-character-chunks/#comments</comments>
		<pubDate>Fri, 10 Apr 2009 18:47:53 +0000</pubDate>
		<dc:creator>zaphar</dc:creator>
				<category><![CDATA[Site News]]></category>
		<category><![CDATA[sagas]]></category>
		<category><![CDATA[twitter]]></category>

		<guid isPermaLink="false">http://jeremy.marzhillstudios.com/?p=163</guid>
		<description><![CDATA[I typically don't try to connect tweets to previous tweets, but I'm fascinated by the people who do.]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been on <a href="http://twitter.com/zaphar">twitter</a> for a while now andam currently up to 1789 posts. I&#8217;m a snippet twitterer. I typically don&#8217;t try to connect tweets to previous tweets, but I&#8217;m fascinated by the people who do. <a href="http://twitter.com/brentspiner">Brent Spiner</a> for instance is at this moment twittering a saga of two women in chunks of 140 characters or less. I&#8217;m actually somewhat on the edge of my seat. Which is pretty decent for twittering. Perhaps I should consider doing some saga&#8217;s of my own. First though I&#8217;ll need to have something saga worthy happen to me.</p>
]]></content:encoded>
			<wfw:commentRss>http://jeremy.marzhillstudios.com/index.php/site-news/twitter-and-the-saga-in-140-character-chunks/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Oh my goodness he just updated his blog!!</title>
		<link>http://jeremy.marzhillstudios.com/index.php/site-news/oh-my-goodness-he-just-updated-his-blog/</link>
		<comments>http://jeremy.marzhillstudios.com/index.php/site-news/oh-my-goodness-he-just-updated-his-blog/#comments</comments>
		<pubDate>Mon, 06 Apr 2009 01:29:18 +0000</pubDate>
		<dc:creator>zaphar</dc:creator>
				<category><![CDATA[Site News]]></category>
		<category><![CDATA[ECMAScript (javascript)]]></category>
		<category><![CDATA[etap]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[joose]]></category>
		<category><![CDATA[life]]></category>
		<category><![CDATA[updates]]></category>
		<category><![CDATA[whirlwind]]></category>

		<guid isPermaLink="false">http://jeremy.marzhillstudios.com/?p=153</guid>
		<description><![CDATA[Whoah!!! I know what you're thinking. Is this an honest to God update on Jeremy's blog? Is he actually going to let us know what he's been up to for the last.... lets see.... 2 years?!? Yep. That's exactly what this is.]]></description>
			<content:encoded><![CDATA[<p>Hi there! Honestly I&#8217;m not dead, I&#8217;ve just been all wrapped up in this whole life thing. You know&#8230; that whole, &#8220;Holy cow!!!! I work at Google now!! When did this happen exactly?&#8221; thing, where you&#8217;re incredibly busy just trying to get up to speed on it all and catch your breath? Well anyway, I feel bad since I&#8217;ve been silent for so long, so here goes. An update from the trenches of the Life of Jeremy Wall. Since I wrote last I have</p>
<ul>
<li> been &#8220;acquired by Google&#8221;</li>
<li> had my first &#8220;truly successful&#8221; Open Source Project</li>
<li> and actually got my Student Loan back under control.</li>
</ul>
<p>I&#8217;m actually absurdly proud of that last one&#8230; And still a bit bewildered by the first one. So lets go down the list one at a time shall we?</p>
<h2>&#8220;The Acquisition&#8221;</h2>
<p>The company I worked for DoubleClick Performics got bought by Google. Who would have thought it? Somehow I landed an actual job at Google doing what I love. Crafting Code. I have to say, I think this has to have been a &#8220;God thing&#8221;. I can&#8217;t see any other way to explain it. Google of course is an awesome place to work. Free food, Smart people, Gameroom (strangely I almost never make into there though), Snacks, and really interesting technology to play with. I&#8217;m learning a lot about working in Highly Available, Highly Scalable environments. I keep waiting to wake up and find out it was all a dream.</p>
<h2>&#8220;The Open Source Project&#8221;</h2>
<p>My last post was about etap, my learn erlang project. I had no idea that the project would get the attention of Nick, a coder with EA, who was looking for a TAP compliant testing framework for their erlang code. He contacted me and asked if he could take over management of the code. I said&#8221; sure&#8221;, as long as I still got to contribute when I had time. Before I knew it EA was using etap internally and I had what I consider to be my first truly successful open source project. etap has now gotten used commercially, traveled to conferences, and is soon to be featured in a book. Not bad for a learners project huh?</p>
<h2>&#8220;The School Loan&#8221;</h2>
<p>And perhaps most awesome of all I&#8217;m making headway on the whole credit repair thing. The school loan is back under control and no longer has a devestating impact on my credit report. This is an accomplishment that makes me really wonder if I&#8217;m in some kind of awesome dream or something.</p>
<p>Life is really looking up around here. I&#8217;ll try to get more regular on my posting again as I play with more erlang, think about writing a book, and Oh almost forgot to mention &#8220;Joose&#8221; the meta-object protocol for javascript. I&#8217;ll write more about that later.</p>
]]></content:encoded>
			<wfw:commentRss>http://jeremy.marzhillstudios.com/index.php/site-news/oh-my-goodness-he-just-updated-his-blog/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
