<?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>Along Came Betty</title>
	<atom:link href="http://blog.darevay.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.darevay.com</link>
	<description>You know, software and some other stuff like maybe guitar or something</description>
	<lastBuildDate>Sun, 03 Mar 2013 17:07:05 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.6.6</generator>
	<item>
		<title>Clawk = Awk cut with Clojure</title>
		<link>http://blog.darevay.com/2013/03/clawk-awk-cut-with-clojure/</link>
		<comments>http://blog.darevay.com/2013/03/clawk-awk-cut-with-clojure/#respond</comments>
		<pubDate>Sun, 03 Mar 2013 17:07:05 +0000</pubDate>
		<dc:creator><![CDATA[dave]]></dc:creator>
				<category><![CDATA[clojure]]></category>

		<guid isPermaLink="false">http://blog.darevay.com/?p=619</guid>
		<description><![CDATA[I know Clojure pretty well. I don&#8217;t know Awk quite as well and don&#8217;t need it quite enough to ever learn it deeply. I don&#8217;t want Perl either. I&#8217;d rather just write Clojure code for simple text processing. So, lately I&#8217;ve been using Clawk. It works for me. Bad idea, or worst idea? A tiny [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>I know Clojure pretty well. I don&#8217;t know <a href="http://en.wikipedia.org/wiki/AWK">Awk </a>quite as well and don&#8217;t need it quite enough to ever learn it deeply. I don&#8217;t want Perl either. I&#8217;d rather just write Clojure code for simple text processing. So, lately I&#8217;ve been using <a href="https://github.com/daveray/clawk">Clawk</a>. It works for me. Bad idea, or worst idea? A tiny example:</p>
<pre>$ echo -e "1\n2\n3\n" | clawk -r '(* $ $)'
1
4
9</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.darevay.com/2013/03/clawk-awk-cut-with-clojure/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using a Wysiwyg Forms with Seesaw and Clojure</title>
		<link>http://blog.darevay.com/2012/03/using-a-wysiwyg-forms-with-seesaw-and-clojure/</link>
		<comments>http://blog.darevay.com/2012/03/using-a-wysiwyg-forms-with-seesaw-and-clojure/#respond</comments>
		<pubDate>Wed, 21 Mar 2012 02:34:53 +0000</pubDate>
		<dc:creator><![CDATA[dave]]></dc:creator>
				<category><![CDATA[clojure]]></category>
		<category><![CDATA[seesaw]]></category>

		<guid isPermaLink="false">http://blog.darevay.com/?p=606</guid>
		<description><![CDATA[At Clojure/West I mentioned that it was pretty easy to use forms built with wysiwyg UI editors seamlessly with Seesaw. I added an example and a section to the wiki that describes building a simple form with WindowBuilder in Eclipse. The basic principle should apply equally well to the ui tools in NetBeans and IntelliJ. [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>At Clojure/West I mentioned that it was pretty easy to use forms built with wysiwyg UI editors seamlessly with Seesaw. I added an example and a<a href="https://github.com/daveray/seesaw/wiki/Window-Builder"> section to the wiki</a> that describes building a simple form with WindowBuilder in Eclipse. The basic principle should apply equally well to the ui tools in NetBeans and IntelliJ.</p>
<p>For someone that knows <a href="http://code.google.com/p/counterclockwise/">CounterClockwise</a> well (that doesn&#8217;t describe me), I imagine the setup would be even more pleasant since changes to forms could be reused immediately from Clojure code without leaving Eclipse.</p>
<p>Finally, because everyone likes screenshots:</p>
<p><a href="https://github.com/daveray/seesaw/wiki/Window-Builder"><img class="aligncenter size-full wp-image-607" title="window-builder" src="http://blog.darevay.com/wp-content/uploads/2012/03/window-builder.png" alt="" width="939" height="450" srcset="http://blog.darevay.com/wp-content/uploads/2012/03/window-builder.png 939w, http://blog.darevay.com/wp-content/uploads/2012/03/window-builder-300x143.png 300w" sizes="(max-width: 939px) 100vw, 939px" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.darevay.com/2012/03/using-a-wysiwyg-forms-with-seesaw-and-clojure/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Best of ClojureWest 2012</title>
		<link>http://blog.darevay.com/2012/03/best-of-clojurewest-2012/</link>
		<comments>http://blog.darevay.com/2012/03/best-of-clojurewest-2012/#comments</comments>
		<pubDate>Mon, 19 Mar 2012 16:11:31 +0000</pubDate>
		<dc:creator><![CDATA[dave]]></dc:creator>
				<category><![CDATA[clojure]]></category>
		<category><![CDATA[clojurewest]]></category>

		<guid isPermaLink="false">http://blog.darevay.com/?p=598</guid>
		<description><![CDATA[I sat down to go over my Clojure/West notes and write some thoughts. An hour later, I had several long paragraphs and had only covered two talks. Clearly this process wasn&#8217;t going to scale. So I pondered a bit on how to express the awesomeness of Clojure/West without writing &#8220;War and Peace&#8221;. Based on a [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>I sat down to go over my <a href="http://clojurewest.org">Clojure/West</a> notes and write some thoughts. An hour later, I had several long paragraphs and had only covered two talks. Clearly this process wasn&#8217;t going to scale. So I pondered a bit on how to express the awesomeness of Clojure/West without writing &#8220;War and Peace&#8221;. Based on a couple tweets I saw, I settled on a &#8220;Best of&#8221; approach.</p>
<p>Doing it this way is deeply shallow (?!) and silly. Hopefully, it&#8217;s also more fun than paragraphs of my incoherent ramblings on Datomic.</p>
<p>So, in rough chronological order, my &#8220;Best of Clojure/West 2012&#8221;:</p>
<ul>
<li> Best conference organizer: <a href="http://twitter.com/puredanger">@puredanger</a> aka Alex Miller
<li> Best design advice: &#8220;Choose immutability and see where it takes you.&#8221; &ndash; <a href="http://twitter.com/richhickey">@richhickey</a>
<li> Most difficult word to type: datamic, er, <a href="http://datomic.com">datomic</a>.
<li> Best hair: if you have to ask, stop reading now.
<li> Most overheard: &#8220;Do you get to use Clojure at work?&#8221;
<li> Most thoughtful reflection on Rich&#8217;s keynote: &#8220;Holy Shit!&#8221; &ndash; <a href="http://twitter.com/craigandera">@craigandera</a>
<li> Special award for stepping into the den of the <code>(ns)</code> macro and emerging, mostly, unscathed: <a href="http://twitter.com/craigandera">@craigandera</a>
<li> Best talk title: <a href="https://github.com/strangeloop/clojurewest2012-slides/raw/master/monadWritingDesk.pdf">&#8220;Why is a monad like a writing desk?&#8221;</a> &ndash; <a href="http://twitter.com/carinmeier">@carinmeier</a>
<li> Best place to ask Rich about changes in Clojure 1.4: <a href="https://twitter.com/#!/geoffeg/status/181148777569206272">Men&#8217;s room</a>. Sorry ladies.
<li> Best feedback on <a href="http://darevay.com/talks/clojurewest2012/">my talk</a>: &#8220;I didn&#8217;t really want to go to your talk, but my boss made me. I&#8217;m glad he did.&#8221;
<li> Best meme: <a href="https://twitter.com/#!/stuartsierra/status/181144084545671168">&#8220;Don&#8217;t build frameworks; build small, composable libraries.&#8221;</a>
<li> Best new development paradigm: Wikipedia Driven Development &ndash; <a href="http://twitter.com/stuartsierra">@stuartsierra</a>
<li> Best testing quote: &#8220;Unless your CI server has an unlimited supply of missiles, this is going to be difficult to test&#8221; &ndash; <a href="http://twitter.com/stuartsierra">@stuartsierra</a>
<li> Best <a href="http://anathem.wikia.com/wiki/Lorite">Lorite</a>: <a href="http://twitter.com/rpg">@rpg</a> aka Richard P Gabriel
<li> Most incongruous moment: <a href="http://www.homestarrunner.com/sbemail20.html">Strongbad yelling &#8220;Deleted!&#8221;</a> in the middle of Richard Gabriel&#8217;s lecture
<li> Best way to get rhythm in <a href="http://overtone.github.com/">Overtone</a>: &#8220;Probably by creating a small function&#8221; &ndash; <a href="http://twitter.com/samaaron">@samaaron</a>
<li> Best lifehack and use of duct tape: <a href="http://twitter.com/tavisrudd">@tavisrudd&#8217;s</a> voice-driven Emacs setup, <a href="https://twitter.com/#!/tavisrudd/status/181080817425055744">&#8220;via dragon natspeak + the python &#8216;natlink&#8217; bindings and several layers of duct tape&#8221;</a>
<li> Best observation of own demo: &#8220;It might not seem like a big deal, but that&#8217;s really hard to do. I just wanna be sure we&#8217;re clear. That was awesome.&#8221; &ndash; <a href="http://twitter.com/bradfordcross">@bradfordcross</a>
<li> Best swarm-assisted discovery: <a href="https://twitter.com/#!/technomancy/status/181143412664311809">&#8220;Go is a reduce of place-stone over a board and a seq of inputs.&#8221;</a> &ndash; <a href="http://twitter.com/technomancy">@technomancy</a>
<li> Best source of swag: <a href="http://twitter.com/ghoseb">@ghoseb</a>. Just ask and he&#8217;ll hook you up. Stickers, buttons, mugs, penants, dog sweaters, tea cozies, he&#8217;s got everything, and not just Clojure stuff. :)
<li> Best leaf-smuggling-hobbit-inspired project name: <a href="https://github.com/strangeloop/clojurewest2012-slides/blob/master/StackTraces-Longbottom-Chouser.svg">Longbottom</a> &ndash; <a href="http://twitter.com/chouser">@chouser</a>
<li> Best channeling of Woody Allen while showing a picture of <a href="https://github.com/strangeloop/clojurewest2012-slides/blob/master/CLJS_clojure-west-FOGUS.pdf">Batman riding a unicorn</a> and telling a <a href="https://twitter.com/#!/fogus/status/181171644939763712">recycled</a> joke comparing JavaScript to Russian literature: <a href="http://twitter.com/fogus">@fogus</a>
<li> Best beer-driven keynote: <a href="http://twitter.com/stuarthalloway">@stuarthalloway</a>
<li>And, of coure, best of the best: DATA!
</ul>
<p><em>All (most) of the slides for Clojure/West can be found on <a href="https://github.com/strangeloop/clojurewest2012-slides/">github</a>. If you get &#8220;blob is too big&#8221; for a file, you&#8217;ll have to clone the repo and view locally :(</em></p>
<p>As a three-track conference, I missed at least 2/3 of the awesomeness of Clojure/West. What were your &#8220;Best of&#8221; moments?</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.darevay.com/2012/03/best-of-clojurewest-2012/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Regenemies: A very simple game in Clojure</title>
		<link>http://blog.darevay.com/2012/02/regenemies-a-very-simple-game-in-clojure/</link>
		<comments>http://blog.darevay.com/2012/02/regenemies-a-very-simple-game-in-clojure/#comments</comments>
		<pubDate>Sun, 26 Feb 2012 16:37:17 +0000</pubDate>
		<dc:creator><![CDATA[dave]]></dc:creator>
				<category><![CDATA[clojure]]></category>
		<category><![CDATA[seesaw]]></category>

		<guid isPermaLink="false">http://blog.darevay.com/?p=582</guid>
		<description><![CDATA[Lately I&#8217;ve been working on several things in Clojure with the goal of getting a better handle on general app development as opposed to library dev. Working on Seesaw and other libraries is fun and an interesting challenge in API design, but wrapping up Java interop is quite different from building a functioning app. Anyway, [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Lately I&#8217;ve been working on several things in Clojure with the goal of getting a better handle on general app development as opposed to library dev. Working on <a href="https://github.com/daveray/seesaw">Seesaw</a> and <a href="https://github.com/daveray/dorothy">other</a> <a href="https://github.com/daveray/upshot">libraries</a> is fun and an interesting challenge in API design, but wrapping up Java interop is quite different from building a functioning app.</p>
<p>Anyway, one of my little experiments is a game called <a href="http://darevay.com/regenemies/">Regenemies</a>. A long time ago a friend and I had the idea for &#8220;regex invaders&#8221; where regular expressions fall down the screen and you have to type in matches for them to &#8220;kill&#8221; them as fast as you can. Well, I finally got around to it this weekend. The whole falling regex thing didn&#8217;t work that well, so I opted for just showing 1 or more expressions in a grid, each with a little countdown timer to tell you how long you&#8217;ve got.</p>
<p>The game itself isn&#8217;t really that fun. In fact, it&#8217;s a little stressful since every missed pattern is a strike against your skills as a programmer, and therefore, your worth as a human being. But it was a useful exercise in building up the game representation and defining state transitions in a mostly functional way.</p>
<p>The UI, which is rudimentary in the extreme, is currently implemented in Seesaw, but I will probably give porting it to ClojureScript and canvas a try.</p>
<p>The game is hosted via JavaWebStart <a href="http://darevay.com/regenemies/">here</a>, the code&#8217;s on <a href="https://github.com/daveray/regenemies">github</a>, and here&#8217;s a screenshot since people like those:</p>
<p><a href="http://darevay.com/regenemies/"><img class="aligncenter" title="Regenemies" src="http://darevay.com/regenemies/regenemies.png" alt="" width="546" height="337" /></a></p>
<p>Comment and criticism welcome, especially on the game state representation. Regex generation could also use a little more love as well.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.darevay.com/2012/02/regenemies-a-very-simple-game-in-clojure/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>ClojureScript One Execution Flow</title>
		<link>http://blog.darevay.com/2012/01/clojurescript-one-execution-flow/</link>
		<comments>http://blog.darevay.com/2012/01/clojurescript-one-execution-flow/#respond</comments>
		<pubDate>Sat, 28 Jan 2012 13:27:57 +0000</pubDate>
		<dc:creator><![CDATA[dave]]></dc:creator>
				<category><![CDATA[clojure]]></category>
		<category><![CDATA[clojurescript]]></category>

		<guid isPermaLink="false">http://blog.darevay.com/?p=568</guid>
		<description><![CDATA[Last night I puzzled through the execution flow of the ClojureScript One sample app. I even took notes while I was doing it. The results are here. I have to say ClojureScript One is an impressive achievement. Someone should build &#8220;Clojure One&#8221; now :)]]></description>
				<content:encoded><![CDATA[<p>Last night I puzzled through the execution flow of the ClojureScript One sample app. I even took notes while I was doing it.</p>
<p style="text-align: center;"><a href="https://gist.github.com/1692791">The results are here</a>.</p>
<p style="text-align: left;">I have to say ClojureScript One is an impressive achievement. Someone should build &#8220;Clojure One&#8221; now :)</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.darevay.com/2012/01/clojurescript-one-execution-flow/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A Seesaw Tutorial</title>
		<link>http://blog.darevay.com/2011/12/a-seesaw-tutorial/</link>
		<comments>http://blog.darevay.com/2011/12/a-seesaw-tutorial/#comments</comments>
		<pubDate>Thu, 08 Dec 2011 03:47:18 +0000</pubDate>
		<dc:creator><![CDATA[dave]]></dc:creator>
				<category><![CDATA[clojure]]></category>
		<category><![CDATA[seesaw]]></category>

		<guid isPermaLink="false">http://blog.darevay.com/?p=557</guid>
		<description><![CDATA[It was recently pointed out to me that Seesaw&#8217;s &#8220;amazing and wonderful&#8221;, but not still not that friendly for developers with no background in Java or Swing. By coincidence, I was scheduled to give a talk on Seesaw at Ann Arbor&#8217;s CraftsmanGuild, so I took the opportunity to try to improve the situation. I&#8217;m usually [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>It was recently <a href="https://twitter.com/#!/IORayne/status/143222063950336000">pointed out to me</a> that <a href="https://github.com/daveray/seesaw">Seesaw&#8217;s</a> &#8220;amazing and wonderful&#8221;, but not still not that friendly for developers with no background in Java or Swing. By coincidence, I was scheduled to give a talk on Seesaw at Ann Arbor&#8217;s <a href="http://craftsmanguild.herokuapp.com/">CraftsmanGuild</a>, so I took the opportunity to try to improve the situation.</p>
<p>I&#8217;m usually <a href="http://blog.darevay.com/2011/04/here-comes-clojure-a-clojure-talk-in-clojure/">not a fan of slides</a>, so I did the talk completely in the REPL. The result was, I think, a nice introduction that assumes no Java or Swing knowledge and shows off some of Seesaw&#8217;s cool high-level features.</p>
<p><em>You might want to <a href="https://gist.github.com/1441520">view it in its native habitat</a> since this dumb fixed-width layout will hide some of the text. Also, depending on your fonts, my lovingly crafted screenshots might look like crap. Sorry about that.</em></p>
<p>In any case, here it is. Feedback welcome and encouraged.</p>
<p><script src="https://gist.github.com/1441520.js?file=seesaw-repl-tutorial.clj"></script></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.darevay.com/2011/12/a-seesaw-tutorial/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>VimClojure &#8211; Easy</title>
		<link>http://blog.darevay.com/2011/10/vimclojure-easy/</link>
		<comments>http://blog.darevay.com/2011/10/vimclojure-easy/#comments</comments>
		<pubDate>Thu, 13 Oct 2011 02:56:40 +0000</pubDate>
		<dc:creator><![CDATA[dave]]></dc:creator>
				<category><![CDATA[clojure]]></category>
		<category><![CDATA[vim]]></category>
		<category><![CDATA[vimclojure]]></category>

		<guid isPermaLink="false">http://blog.darevay.com/?p=545</guid>
		<description><![CDATA[Update 1/2013: The future of Clojuring with Vim is tpope&#8217;s foreplay.vim. You can find a tutorial here. I promise this is the last VimClojure post for a while. I get the feeling that my post describing my VimClojure setup is a little too involved, especially for someone that just wants something working quickly. Also, from [&#8230;]]]></description>
				<content:encoded><![CDATA[<p><strong>Update 1/2013: <em>The future of Clojuring with Vim is tpope&#8217;s <a href="https://github.com/tpope/vim-foreplay">foreplay.vim</a>. You can find a tutorial <a href="http://clojure-doc.org/articles/tutorials/vim_foreplay.html">here</a></em>.</strong></p>
<p><em>I promise this is the last VimClojure post for a while.</em></p>
<p>I get the feeling that <a href="http://blog.darevay.com/2010/10/how-i-tamed-vimclojure/">my post describing my VimClojure setup</a> is a little too involved, especially for someone that just wants something working quickly. Also, from what I&#8217;ve seen on <a href="http://clojure-log.n01se.net/">#clojure</a>, there&#8217;s some frustration out there. With that in mind, I put together a minimal example configuration with instructions.</p>
<p>So, without further ado, <a href="https://github.com/daveray/vimclojure-easy">vimclojure-easy</a>.</p>
<p>Feedback welcome.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.darevay.com/2011/10/vimclojure-easy/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Familiar: Clojure plus Ruby</title>
		<link>http://blog.darevay.com/2011/10/familiar-clojure-plus-ruby/</link>
		<comments>http://blog.darevay.com/2011/10/familiar-clojure-plus-ruby/#comments</comments>
		<pubDate>Mon, 10 Oct 2011 02:37:36 +0000</pubDate>
		<dc:creator><![CDATA[dave]]></dc:creator>
				<category><![CDATA[clojure]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[jruby]]></category>

		<guid isPermaLink="false">http://blog.darevay.com/?p=537</guid>
		<description><![CDATA[Last week I had three separate conversations with people about using Clojure&#8217;s data structures and concurrency primitives from a language that&#8217;s not Clojure. Something about parens or insisting on using a less capable language :) So, this weekend I played around with using Clojure from Ruby, in particular JRuby. I haven&#8217;t done much Ruby in [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Last week I had three separate conversations with people about using Clojure&#8217;s data structures and concurrency primitives from a language that&#8217;s not Clojure. Something about parens or insisting on using a less capable language :)</p>
<p>So, this weekend I played around with using Clojure from Ruby, in particular <a href="http://jruby.org">JRuby</a>. I haven&#8217;t done much Ruby in about a year, so I spent most of my time remembering that. Anyway, I ended up with a proof of concept: <a href="https://github.com/daveray/familiar">Familiar</a>. See the readme there. Here&#8217;s an example:</p>
<p><script src="https://gist.github.com/1274510.js"> </script></p>
<p>That&#8217;s it. This gives full access to the <code>clojure.core</code> API including lazy seqs, STM, and all those goodies. Good idea? Idiotic? I don&#8217;t know, but it was a fun exercise.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.darevay.com/2011/10/familiar-clojure-plus-ruby/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Taming VimClojure 2.3.0</title>
		<link>http://blog.darevay.com/2011/10/taming-vimclojure-2-3-0/</link>
		<comments>http://blog.darevay.com/2011/10/taming-vimclojure-2-3-0/#respond</comments>
		<pubDate>Sat, 08 Oct 2011 01:28:28 +0000</pubDate>
		<dc:creator><![CDATA[dave]]></dc:creator>
				<category><![CDATA[clojure]]></category>
		<category><![CDATA[vim]]></category>
		<category><![CDATA[vimclojure]]></category>

		<guid isPermaLink="false">http://blog.darevay.com/?p=533</guid>
		<description><![CDATA[Update 1/2013: The future of Clojuring with Vim is tpope&#8217;s foreplay.vim. You can find a tutorial here. In honor of the release of VimClojure 2.3.0, I&#8217;ve updated my post on taming VimClojure. Thankfully, very little has changed in the setup. Cheers.]]></description>
				<content:encoded><![CDATA[<p><strong>Update 1/2013: <em>The future of Clojuring with Vim is tpope&#8217;s <a href="https://github.com/tpope/vim-foreplay">foreplay.vim</a>. You can find a tutorial <a href="http://clojure-doc.org/articles/tutorials/vim_foreplay.html">here</a></em>.</strong></p>
<p>In honor of the <a href="https://groups.google.com/group/vimclojure/browse_thread/thread/a1b649b095e26c65">release of VimClojure 2.3.0</a>, I&#8217;ve updated <a href="http://blog.darevay.com/2010/10/how-i-tamed-vimclojure/">my post on taming VimClojure</a>. Thankfully, very little has changed in the setup. Cheers.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.darevay.com/2011/10/taming-vimclojure-2-3-0/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Clojure Update Literacy</title>
		<link>http://blog.darevay.com/2011/10/clojure-update-literacy/</link>
		<comments>http://blog.darevay.com/2011/10/clojure-update-literacy/#comments</comments>
		<pubDate>Wed, 05 Oct 2011 03:20:45 +0000</pubDate>
		<dc:creator><![CDATA[dave]]></dc:creator>
				<category><![CDATA[clojure]]></category>

		<guid isPermaLink="false">http://blog.darevay.com/?p=523</guid>
		<description><![CDATA[I want to write briefly (ok, not that briefly) about my understanding of Clojure&#8216;s various &#8220;update&#8221; functions, in other words, functions that take a function argument, apply it to some value and do something with the result. These include swap!, alter, commute, send, send-off, alter-var-root, update-in, alter-meta!, vary-meta, and probably several more. From here on [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>I want to write briefly (ok, not that briefly) about my understanding of <a href="http://clojure.org">Clojure</a>&#8216;s various &#8220;update&#8221; functions, in other words, functions that take a function argument, apply it to some value and do something with the result. These include <code><a href="http://clojure.github.com/clojure/clojure.core-api.html#clojure.core/swap!">swap!</a></code>, <code><a href="http://clojure.github.com/clojure/clojure.core-api.html#clojure.core/alter">alter</a></code>, <code><a href="http://clojure.github.com/clojure/clojure.core-api.html#clojure.core/commute">commute</a></code>, <code><a href="http://clojure.github.com/clojure/clojure.core-api.html#clojure.core/send">send</a></code>, <code><a href="http://clojure.github.com/clojure/clojure.core-api.html#clojure.core/send-off">send-off</a></code>, <code><a href="http://clojure.github.com/clojure/clojure.core-api.html#clojure.core/alter-var-root">alter-var-root</a></code>, <code><a href="http://clojure.github.com/clojure/clojure.core-api.html#clojure.core/update-in">update-in</a></code>, <code><a href="http://clojure.github.com/clojure/clojure.core-api.html#clojure.core/alter-meta!">alter-meta!</a></code>, <code><a href="http://clojure.github.com/clojure/clojure.core-api.html#clojure.core/vary-meta">vary-meta</a></code>, and probably several more. From here on out, I&#8217;ll call a function in this family an <b>update function</b> and the function passed to it a <b>transform function</b>.</p>
<p>Note that update functions are most commonly encountered when using Clojure&#8217;s reference types, i.e. <a href="http://clojure.org/vars">vars</a>, <a href="http://clojure.org/refs">refs</a>, <a href="http://clojure.org/atoms">atoms</a>, and <a href="http://clojure.org/agents">agents</a>. Their signatures are all very consistent:</p>
<pre>
    (&lt;update-fn&gt; old-state &lt;tranform-fn&gt; &amp; args)
    ;=> new-state
</pre>
<p>That they&#8217;re so consistent is a testament to the thought that has gone into the design of Clojure&#8217;s core API.</p>
<p>Nonetheless, a newcomer to Clojure, overwhelmed by all the other new concepts they&#8217;re learning, might find update functions a little confusing. They might find themselves calling <code><a href="">reset!</a></code> a lot because <code>swap!</code> is scary. Of course, if the value passed to <code>reset!</code> (or <code><a href="">ref-set</a></code>) depends on the previous value of the ref, you&#8217;ve thrown away all the nice concurrency guarantees that atoms and refs are supposed to give you. For example, the prototypical id generator:</p>
<pre>
  ; BADBAD Don't do this!
  (defn id-generator []
    (let [id (atom 0)]
     (fn []
       (reset! id (inc @id)))))
</pre>
<p><b><a href="https://gist.github.com/1263503">No No No No No</a></b></p>
<p>Of course, everyone knows to use <code>(swap! id inc)</code> for a canonical example like this, but in the thick of a larger app, feeling like you&#8217;re <a href="http://blog.fogus.me/2011/04/21/never-feel-safe/">in over your head</a>, it&#8217;s easier to make mistakes.</p>
<hr>
<p><b>So</b>, learning to read (and write) an update function can take you a long way along the road toward writing more idiomatic Clojure.  For someone with an OO background, it might be easier if we mentally re-wrote the signature above like this:</p>
<pre>
   state = transform_fn(state, arg0, arg1, ...);
</pre>
<p>that is, we&#8217;re applying some <b>transformation</b> to the current value of <code>state</code> and storing the value back in <code>state</code>. See, <code>swap!</code> and friends are <b>just a function call in disguise</b>. Their signatures are completely consistent with Clojure&#8217;s <a href="http://kotka.de/blog/2010/08/Did_you_know_VII.html">argument order conventions</a>, but they slightly obscure what&#8217;s going on because the state and transform function are switched. This makes sense since <code>state</code> is the <em>important argument</em>, but it took me a little while to realize this and make the mental adjustment.</p>
<p>Once I reached this conclusion, I found writing in a functional style with state transitions much more straightforward. </p>
<p><em>Note that I find this a useful way to *read* update functions. It&#8217;s not a replacement for thinking hard about the semantics of the update function you&#8217;re using</em></p>
<hr>
<p>Here are some general guidlines that I find helpful:</p>
<ul>
<li>Always write <b>pure</b> functions that represent state transitions or transformations. They take in the current state and maybe some additional arguments and calculate a new state. This is obvious, but sometimes I have to keep repeating these things to myself. Kind of like in <a href="http://www.tcl.tk/">Tcl</a>, &#8220;everything&#8217;s a string, everything&#8217;s a string, everything&#8217;s a string, &#8230;&#8221;
<li><code>reset!</code> (and its cousin <code>ref-set</code>) is for exactly what its name says: &#8220;reset this atom back to some initial state dammit!&#8221; Only use it if you&#8217;re resetting your app, or if the new value truly doesn&#8217;t depend on the old value. In the latter case, randomly generated values or user input come to mind.
<li>Always give your transform functions a name. Passing an anonymous function to <code>swap!</code> means you just wrote a function that&#8217;s harder to test or experiment with at the repl. Besides, a descriptive name is more readable than most anonymous functions.
<li>Limit the number of call sites for update functions in your app. A system that&#8217;s sprinkled liberally with <code>(dosync)</code> blocks and calls to <code>swap!</code> will be more difficult to reason about than one where the state transitions are localized.
<li>Don&#8217;t forget the <code>args</code>! I&#8217;ve often fallen into the trap of passing an anonymous function when I needed to pass args to my state transition function.
<li>Don&#8217;t forget that most things are functions and, therefore, candidates for transform functions!
<pre>
    ; A contrived example
    (def signal (atom :red))
    (def transitions { :red :green, :green :yellow, :yellow :red })
    (swap! signal #(get transitions %)) ; &lt;- NO
    (swap! signal transitions) ; &lt;- YES
</pre>
</li>
</ul>
<p>and finally, as a wise man once said <b>&#8220;functions and data!&#8221;</b></p>
<hr>
<p>In conclusion, I hope this sheds some light on an area of Clojure that I&#8217;ve personally found to require a great deal of mental deprogramming. As I&#8217;ve gained confidence with these concepts, my code has been easier to read, easier to test, and easier to reason about. Happy Clojuring.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.darevay.com/2011/10/clojure-update-literacy/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic page generated in 0.337 seconds. -->
<!-- Cached page generated by WP-Super-Cache on 2017-09-18 23:09:25 -->
