<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">

	<title type="text">Planet Clojure</title>
	
	<link href="http://planet.clojure.in/" />
	<id>http://planet.clojure.in/atom.xml</id>
	<updated>2010-09-03T21:02:15+00:00</updated>
	<generator uri="http://www.planetplanet.org/">Planet/2.0 +http://www.planetplanet.org</generator>

	<feedburner:info uri="clojure" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><subtitle type="html">Planet Clojure is a meta blog that collects posts from the blogs of various Clojure hackers and contributors.</subtitle><logo>http://clojure.org/file/view/clojure-icon.gif</logo><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/clojure" /><feedburner:feedFlare href="http://add.my.yahoo.com/rss?url=http%3A%2F%2Ffeeds.feedburner.com%2Fclojure" src="http://us.i1.yimg.com/us.yimg.com/i/us/my/addtomyyahoo4.gif">Subscribe with My Yahoo!</feedburner:feedFlare><feedburner:feedFlare href="http://fusion.google.com/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2Fclojure" src="http://buttons.googlesyndication.com/fusion/add.gif">Subscribe with Google</feedburner:feedFlare><feedburner:feedFlare href="http://www.plusmo.com/add?url=http%3A%2F%2Ffeeds.feedburner.com%2Fclojure" src="http://plusmo.com/res/graphics/fbplusmo.gif">Subscribe with Plusmo</feedburner:feedFlare><feedburner:feedFlare href="http://www.thefreedictionary.com/_/hp/AddRSS.aspx?http%3A%2F%2Ffeeds.feedburner.com%2Fclojure" src="http://img.tfd.com/hp/addToTheFreeDictionary.gif">Subscribe with The Free Dictionary</feedburner:feedFlare><feedburner:feedFlare href="http://www.bitty.com/manual/?contenttype=rssfeed&amp;contentvalue=http%3A%2F%2Ffeeds.feedburner.com%2Fclojure" src="http://www.bitty.com/img/bittychicklet_91x17.gif">Subscribe with Bitty Browser</feedburner:feedFlare><feedburner:feedFlare href="http://www.live.com/?add=http%3A%2F%2Ffeeds.feedburner.com%2Fclojure" src="http://tkfiles.storage.msn.com/x1piYkpqHC_35nIp1gLE68-wvzLZO8iXl_JMledmJQXP-XTBOLfmQv4zhj4MhcWEJh_GtoBIiAl1Mjh-ndp9k47If7hTaFno0mxW9_i3p_5qQw">Subscribe with Live.com</feedburner:feedFlare><feedburner:feedFlare href="http://mix.excite.eu/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2Fclojure" src="http://image.excite.co.uk/mix/addtomix.gif">Subscribe with Excite MIX</feedburner:feedFlare><feedburner:feedFlare href="http://www.webwag.com/wwgthis.php?url=http%3A%2F%2Ffeeds.feedburner.com%2Fclojure" src="http://www.webwag.com/images/wwgthis.gif">Subscribe with Webwag</feedburner:feedFlare><feedburner:feedFlare href="http://www.podcastready.com/oneclick_bookmark.php?url=http%3A%2F%2Ffeeds.feedburner.com%2Fclojure" src="http://www.podcastready.com/images/podcastready_button.gif">Subscribe with Podcast Ready</feedburner:feedFlare><feedburner:feedFlare href="http://www.wikio.com/subscribe?url=http%3A%2F%2Ffeeds.feedburner.com%2Fclojure" src="http://www.wikio.com/shared/img/add2wikio.gif">Subscribe with Wikio</feedburner:feedFlare><feedburner:feedFlare href="http://www.dailyrotation.com/index.php?feed=http%3A%2F%2Ffeeds.feedburner.com%2Fclojure" src="http://www.dailyrotation.com/rss-dr2.gif">Subscribe with Daily Rotation</feedburner:feedFlare><entry xml:lang="en">
		<title type="html">Monkeying with Clojure&amp;#8217;s deftest</title>
		<link href="http://feedproxy.google.com/~r/clojure/~3/EOzBLD6jH50/" />
		<id>http://blog.fogus.me/?p=2352</id>
		<updated>2010-09-03T20:25:07+00:00</updated>
		<content type="html">Say you have a namespace a that needs to be tested: 1 (ns a) (defn ^{:private true} foo [] 42) Using Clojure&amp;#8217;s clojure.test libs you might think it would be as simple as the following: (ns b (:use [clojure.test :only [deftest is]])) (deftest test-foo (is (= 42 (a/foo)))) ; java.lang.IllegalStateException: var: #'a/foo is not public [...]&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/clojure?a=EOzBLD6jH50:0WaZm_vzUDk:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/clojure?a=EOzBLD6jH50:0WaZm_vzUDk:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/clojure/~4/EOzBLD6jH50" height="1" width="1"/&gt;</content>
		<author>
			<name>fogus</name>
			<uri>http://blog.fogus.me</uri>
		</author>
		<source>
			<title type="html">Send More Paramedics » clojure</title>
			<subtitle type="html">λ λ λ</subtitle>
			<link rel="self" href="http://blog.fogus.me/tag/clojure/feed/atom/" />
			<id>http://blog.fogus.me/feed/atom/</id>
			<updated>2010-09-03T20:30:18+00:00</updated>
		</source>
	<feedburner:origLink>http://blog.fogus.me/2010/09/03/monkeying-with-clojures-deftest/</feedburner:origLink></entry>

	<entry>
		<title type="html">Thinking in Clojure?</title>
		<link href="http://feedproxy.google.com/~r/clojure/~3/zQ7CqLhDzsQ/thinking-in-clojure" />
		<id>http://corfield.org/blog/post.cfm/thinking-in-clojure</id>
		<updated>2010-09-03T19:28:38+00:00</updated>
		<content type="html">&lt;p&gt;There's a discussion on the Clojure mailing list about how to learn to "think in Clojure" (or think in Lisp or, really, think in functional programming terms). A prominent recommendation is &lt;a href="http://joyofclojure.com/"&gt;The Joy Of Clojure&lt;/a&gt; by Michael Fogus and Chris Houser, which everyone says is a great book, but here are a couple of free online books that were also recommended:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://mitpress.mit.edu/sicp/"&gt;Structure and Interpretation of Computer Programs&lt;/a&gt; by Abelson, Sussman, and Sussman. It's the "entry-level subject in computer science at the Massachusetts Institute of Technology" and it uses a dialect of Lisp called Scheme, not Clojure, but it provides a good grounding in both computer science and functional programming.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.htdp.org/"&gt;How to Design Programs&lt;/a&gt; by Felleisen, Findler, Flatt and Krishnamurthi. This is another introduction to programming / computer science style book that also uses Scheme for its examples.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Enjoy!&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/clojure?a=zQ7CqLhDzsQ:dZo6JErMpnc:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/clojure?a=zQ7CqLhDzsQ:dZo6JErMpnc:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/clojure/~4/zQ7CqLhDzsQ" height="1" width="1"/&gt;</content>
		<author>
			<name>"An Architect's View"</name>
			<uri>http://corfield.org/blog/</uri>
		</author>
		<source>
			<title type="html">An Architect's View</title>
			<subtitle type="html">Sean Corfield, Software Architect, offers his views on the world of software development.</subtitle>
			<link rel="self" href="http://corfield.org/blog/feeds/rss.cfm/category/clojure" />
			<id>http://corfield.org/blog/feeds/rss.cfm/category/clojure</id>
			<updated>2010-09-03T21:01:17+00:00</updated>
		</source>
	<feedburner:origLink>http://corfield.org/blog/post.cfm/thinking-in-clojure</feedburner:origLink></entry>

	<entry>
		<title type="html">cfmljure - using Clojure from CFML</title>
		<link href="http://feedproxy.google.com/~r/clojure/~3/_WpSkoAvYDk/cfmljure-using-clojure-from-cfml" />
		<id>http://corfield.org/blog/post.cfm/cfmljure-using-clojure-from-cfml</id>
		<updated>2010-09-03T15:07:31+00:00</updated>
		<content type="html">&lt;p&gt;If you &lt;a href="http://twitter.com/seancorfield"&gt;follow me on Twitter&lt;/a&gt;, you'll have seen me posting about Clojure quite a bit recently. I really like the simplicity and elegance of Clojure. I like the function programming style. I like that it's a dynamic scripting language. I like that it can also be compiled to JVM bytecode and used in any mixed-language project on the JVM.&lt;/p&gt;
&lt;p&gt;About a month ago I helped someone get some Clojure code compiled and integrated into CFML, like any other Java-based project, but that set me thinking about being able to just use raw Clojure scripts from CFML without needing to go thru the compilation and deployment process. I asked on the Clojure mailing list how to load and run scripts from Java and that gave me what I needed to create a simple CFC wrapper that lets you write Clojure scripts and dynamically load and execute them from inside CFML.&lt;/p&gt;
&lt;p&gt;That's how &lt;a href="http://github.com/seancorfield/cfmljure"&gt;cfmljure&lt;/a&gt; was born on github! It's very early days for the project - I consider this an 'experimental' version - but I've created a &lt;a href="http://groups.google.com/group/cfmljure"&gt;Google mailing list for cfmljure&lt;/a&gt; and it's also &lt;a href="http://cfmljure.riaforg.org"&gt;listed on RIAForge&lt;/a&gt;). I don't expect it to be crazy popular (like FW/1 for example) but I expect to use it on production projects and thought it would be good to put out there for others to experiment with and provide feedback on.&lt;/p&gt;
&lt;p&gt;Things on the roadmap include making it more Leiningen friendly (Leiningen is the de facto standard build tool for Clojure and it definitely makes life simpler) as well as figuring out how to access Clojure variables from CFML. I may even try to figure out how to pass CFCs into Clojure and have them be callable (Clojure can call Java but I'll probably go the route of a Clojure proxy function initially).&lt;/p&gt;
&lt;p&gt;Have fun with it! Join the Google Group if you have questions / problems / suggestions!&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/clojure?a=_WpSkoAvYDk:LLQkhalLTXs:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/clojure?a=_WpSkoAvYDk:LLQkhalLTXs:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/clojure/~4/_WpSkoAvYDk" height="1" width="1"/&gt;</content>
		<author>
			<name>"An Architect's View"</name>
			<uri>http://corfield.org/blog/</uri>
		</author>
		<source>
			<title type="html">An Architect's View</title>
			<subtitle type="html">Sean Corfield, Software Architect, offers his views on the world of software development.</subtitle>
			<link rel="self" href="http://corfield.org/blog/feeds/rss.cfm/category/clojure" />
			<id>http://corfield.org/blog/feeds/rss.cfm/category/clojure</id>
			<updated>2010-09-03T21:01:17+00:00</updated>
		</source>
	<feedburner:origLink>http://corfield.org/blog/post.cfm/cfmljure-using-clojure-from-cfml</feedburner:origLink></entry>

	<entry>
		<title type="html">Jobim: an actors library for Clojure</title>
		<link href="" />
		<id>http://antoniogarrote.wordpress.com/?p=40</id>
		<updated>2010-09-03T13:05:39+00:00</updated>
		<content type="html">In the latest days I&amp;#8217;ve been working in an actors library for Clojure built on top of RabbitMQ and Zookeeper. I&amp;#8217;ve called this little piece of software Jobim. The source code is available in github. External dependencies Jobim depends on &amp;#8230; &lt;a rel="nofollow" target="_blank" href="http://antoniogarrote.wordpress.com/2010/09/03/jobim-an-actors-library-for-clojure/"&gt;Continue reading &lt;span class="meta-nav"&gt;&amp;#8594;&lt;/span&gt;&lt;/a&gt;&lt;img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=antoniogarrote.wordpress.com&amp;blog=5485705&amp;post=40&amp;subd=antoniogarrote&amp;ref=&amp;feed=1" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/clojure?a=Ro2eosQjYao:ldneR-OV7IM:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/clojure?a=Ro2eosQjYao:ldneR-OV7IM:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content>
		<author>
			<name>opus artificem probat</name>
			<uri>http://pipes.yahoo.com/pipes/pipe.info?_id=13f695b744f07195df9d4121406f4362</uri>
		</author>
		<source>
			<title type="html">opus artificem probat</title>
			<subtitle type="html">Pipes Output</subtitle>
			<link rel="self" href="http://pipes.yahoo.com/pipes/pipe.run?_id=13f695b744f07195df9d4121406f4362&amp;_render=rss" />
			<id>http://pipes.yahoo.com/pipes/pipe.run?_id=13f695b744f07195df9d4121406f4362&amp;_render=rss</id>
			<updated>2010-09-03T21:00:39+00:00</updated>
		</source>
	</entry>

	<entry>
		<title type="html">Towards generic APIs for the open world</title>
		<link href="http://feedproxy.google.com/~r/clojure/~3/oxX2sFUKsQA/towards-generic-apis-for-open-world.html" />
		<id>tag:blogger.com,1999:blog-22587889.post-6180939564075434164</id>
		<updated>2010-09-03T10:47:00+00:00</updated>
		<content type="html">&lt;span class="Apple-style-span"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;In my &lt;a rel="nofollow" target="_blank" href="http://debasishg.blogspot.com/2010/08/random-thoughts-on-clojure-protocols.html"&gt;last post&lt;/a&gt; on how Clojure protocols encourage open abstractions, I did some quick rounds between type classes in Haskell and protocols in Clojure. At the end in the section titled "Not really a type class", I mentioned about the &lt;code&gt;read&lt;/code&gt; function of Haskell's &lt;code&gt;Read&lt;/code&gt; type class. &lt;code&gt;read&lt;/code&gt; takes a &lt;code&gt;String&lt;/code&gt; and returns a type - hence it doesn't dispatch on the function argument, but rather on the return type. Clojure protocols can't do this, I am not aware of any dynamic language that can do this. Check out James Iry's &lt;a rel="nofollow" target="_blank" href="http://debasishg.blogspot.com/2010/08/random-thoughts-on-clojure-protocols.html?showComment=1282928486610#c616188610926898843"&gt;insightful comment&lt;/a&gt; on this subject on the post.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;With type classes &lt;i&gt;all dispatch is static&lt;/i&gt; - the dispatch map is passed as a dictionary of types and inferred by the compiler. What benefit does this bring on to us ? Do we really get anything special when the language supports APIs like the &lt;code&gt;read&lt;/code&gt; method of Haskell's &lt;code&gt;Read&lt;/code&gt; type class ?&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;In this post I try to explore how type classes help design generic APIs that are &lt;i&gt;open&lt;/i&gt; and can work seamlessly with abstractions that you implement much later in timeline than the type class itself. This is in contrast to subtype polymorphism where all subtypes are bound by the contracts that the super type exposes. In this sense subtype polymorphism is &lt;i&gt;closed&lt;/i&gt;.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;This post is inspired in part by the excellent article &lt;a rel="nofollow" target="_blank" href="http://blog.ezyang.com/2010/08/generalizing-apis/"&gt;Generalizing APIs&lt;/a&gt; by Edward Z. Yang. For this post I will use Scala, my current language of choice for most of the things I do today.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;b&gt;My generic API&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;I want to implement a &lt;code&gt;read&lt;/code&gt; API like the one in Haskell encoded in a Scala type class .. Let's make it generic in the type that it returns ..&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;code&gt;&lt;span class="java_comment"&gt;//&amp;nbsp;type&amp;nbsp;class&lt;/span&gt;&lt;/code&gt;&lt;/span&gt;&lt;code&gt;&lt;/code&gt;&lt;/span&gt;&lt;code&gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="java_comment"&gt;//&amp;nbsp;reads&amp;nbsp;a&amp;nbsp;string,&amp;nbsp;returns&amp;nbsp;a&amp;nbsp;T&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="java_keyword"&gt;trait&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_type"&gt;Read&lt;/span&gt;&lt;span class="java_separator"&gt;[&lt;/span&gt;&lt;span class="java_plain"&gt;T&lt;/span&gt;&lt;span class="java_separator"&gt;]&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_separator"&gt;{&lt;/span&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class="java_keyword"&gt;def&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;read&lt;/span&gt;&lt;span class="java_separator"&gt;(&lt;/span&gt;&lt;span class="java_plain"&gt;s&lt;/span&gt;&lt;span class="java_operator"&gt;:&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_type"&gt;String&lt;/span&gt;&lt;span class="java_separator"&gt;)&lt;/span&gt;&lt;span class="java_operator"&gt;:&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;T&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="java_separator"&gt;}&lt;/span&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;code&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;span class="Apple-style-span"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;b&gt;For the open world&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;We can define instances of this type class by instantiating the trait as objects. Type classes are implemented in Scala using implicits. In case you're not familiar with the concept, here's what I &lt;a rel="nofollow" target="_blank" href="http://debasishg.blogspot.com/2010/06/scala-implicits-type-classes-here-i.html"&gt;wrote&lt;/a&gt; about them some time back.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;code&gt;&lt;span class="java_comment"&gt;//&amp;nbsp;instance&amp;nbsp;for&amp;nbsp;Int&lt;/span&gt;&lt;/code&gt;&lt;/span&gt;&lt;code&gt;&lt;/code&gt;&lt;/span&gt;&lt;code&gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="java_keyword"&gt;implicit&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_keyword"&gt;object&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_type"&gt;IntRead&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_keyword"&gt;extends&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_type"&gt;Read&lt;/span&gt;&lt;span class="java_separator"&gt;[&lt;/span&gt;&lt;span class="java_type"&gt;Int&lt;/span&gt;&lt;span class="java_separator"&gt;]&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_separator"&gt;{&lt;/span&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class="java_keyword"&gt;def&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;read&lt;/span&gt;&lt;span class="java_separator"&gt;(&lt;/span&gt;&lt;span class="java_plain"&gt;s&lt;/span&gt;&lt;span class="java_operator"&gt;:&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_type"&gt;String&lt;/span&gt;&lt;span class="java_separator"&gt;)&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_operator"&gt;=&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;s&lt;/span&gt;&lt;span class="java_separator"&gt;.&lt;/span&gt;&lt;span class="java_plain"&gt;toInt&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="java_separator"&gt;}&lt;/span&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="java_comment"&gt;//&amp;nbsp;instance&amp;nbsp;for&amp;nbsp;Float&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="java_keyword"&gt;implicit&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_keyword"&gt;object&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_type"&gt;FloatRead&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_keyword"&gt;extends&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_type"&gt;Read&lt;/span&gt;&lt;span class="java_separator"&gt;[&lt;/span&gt;&lt;span class="java_type"&gt;Float&lt;/span&gt;&lt;span class="java_separator"&gt;]&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_separator"&gt;{&lt;/span&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class="java_keyword"&gt;def&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;read&lt;/span&gt;&lt;span class="java_separator"&gt;(&lt;/span&gt;&lt;span class="java_plain"&gt;s&lt;/span&gt;&lt;span class="java_operator"&gt;:&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_type"&gt;String&lt;/span&gt;&lt;span class="java_separator"&gt;)&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_operator"&gt;=&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;s&lt;/span&gt;&lt;span class="java_separator"&gt;.&lt;/span&gt;&lt;span class="java_plain"&gt;toFloat&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="java_separator"&gt;}&lt;/span&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;code&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;span class="Apple-style-span"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;These are very much like what you would do with type class instances in Haskell. You can even create instances for your own abstractions ..&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;code&gt;&lt;span class="java_keyword"&gt;case&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_keyword"&gt;class&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_type"&gt;Name&lt;/span&gt;&lt;span class="java_separator"&gt;(&lt;/span&gt;&lt;span class="java_plain"&gt;last&lt;/span&gt;&lt;span class="java_operator"&gt;:&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_type"&gt;String&lt;/span&gt;&lt;span class="java_separator"&gt;,&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;first&lt;/span&gt;&lt;span class="java_operator"&gt;:&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_type"&gt;String&lt;/span&gt;&lt;span class="java_separator"&gt;)&lt;/span&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;/code&gt;&lt;/span&gt;&lt;code&gt;&lt;/code&gt;&lt;/span&gt;&lt;code&gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="java_keyword"&gt;object&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_type"&gt;NameDescription&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_separator"&gt;{&lt;/span&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class="java_keyword"&gt;def&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;unapply&lt;/span&gt;&lt;span class="java_separator"&gt;(&lt;/span&gt;&lt;span class="java_plain"&gt;s&lt;/span&gt;&lt;span class="java_operator"&gt;:&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_type"&gt;String&lt;/span&gt;&lt;span class="java_separator"&gt;)&lt;/span&gt;&lt;span class="java_operator"&gt;:&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_type"&gt;Option&lt;/span&gt;&lt;span class="java_separator"&gt;[(&lt;/span&gt;&lt;span class="java_type"&gt;String&lt;/span&gt;&lt;span class="java_separator"&gt;,&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_type"&gt;String&lt;/span&gt;&lt;span class="java_separator"&gt;)]&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_operator"&gt;=&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_separator"&gt;{&lt;/span&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class="java_keyword"&gt;val&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;a&amp;nbsp;&lt;/span&gt;&lt;span class="java_operator"&gt;=&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;s&lt;/span&gt;&lt;span class="java_separator"&gt;.&lt;/span&gt;&lt;span class="java_plain"&gt;split&lt;/span&gt;&lt;span class="java_separator"&gt;(&lt;/span&gt;&lt;span class="java_literal"&gt;"/"&lt;/span&gt;&lt;span class="java_separator"&gt;)&lt;/span&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class="java_type"&gt;Some&lt;/span&gt;&lt;span class="java_separator"&gt;((&lt;/span&gt;&lt;span class="java_plain"&gt;a&lt;/span&gt;&lt;span class="java_separator"&gt;(&lt;/span&gt;&lt;span class="java_literal"&gt;1&lt;/span&gt;&lt;span class="java_separator"&gt;),&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;a&lt;/span&gt;&lt;span class="java_separator"&gt;(&lt;/span&gt;&lt;span class="java_literal"&gt;0&lt;/span&gt;&lt;span class="java_separator"&gt;)))&lt;/span&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class="java_separator"&gt;}&lt;/span&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="java_separator"&gt;}&lt;/span&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="java_comment"&gt;//&amp;nbsp;instance&amp;nbsp;for&amp;nbsp;Name&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="java_keyword"&gt;import&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_type"&gt;NameDescription&lt;/span&gt;&lt;span class="java_separator"&gt;.&lt;/span&gt;&lt;span class="java_plain"&gt;_&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="java_keyword"&gt;implicit&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_keyword"&gt;object&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_type"&gt;NameRead&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_keyword"&gt;extends&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_type"&gt;Read&lt;/span&gt;&lt;span class="java_separator"&gt;[&lt;/span&gt;&lt;span class="java_type"&gt;Name&lt;/span&gt;&lt;span class="java_separator"&gt;]&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_separator"&gt;{&lt;/span&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class="java_keyword"&gt;def&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;read&lt;/span&gt;&lt;span class="java_separator"&gt;(&lt;/span&gt;&lt;span class="java_plain"&gt;s&lt;/span&gt;&lt;span class="java_operator"&gt;:&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_type"&gt;String&lt;/span&gt;&lt;span class="java_separator"&gt;)&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_operator"&gt;=&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;s&amp;nbsp;&lt;/span&gt;&lt;span class="java_keyword"&gt;match&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_separator"&gt;{&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class="java_keyword"&gt;case&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_type"&gt;NameDescription&lt;/span&gt;&lt;span class="java_separator"&gt;(&lt;/span&gt;&lt;span class="java_plain"&gt;l&lt;/span&gt;&lt;span class="java_separator"&gt;,&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;f&lt;/span&gt;&lt;span class="java_separator"&gt;)&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_operator"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_type"&gt;Name&lt;/span&gt;&lt;span class="java_separator"&gt;(&lt;/span&gt;&lt;span class="java_plain"&gt;l&lt;/span&gt;&lt;span class="java_separator"&gt;,&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;f&lt;/span&gt;&lt;span class="java_separator"&gt;)&lt;/span&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class="java_keyword"&gt;case&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;_&amp;nbsp;&lt;/span&gt;&lt;span class="java_operator"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;error&lt;/span&gt;&lt;span class="java_separator"&gt;(&lt;/span&gt;&lt;span class="java_literal"&gt;"invalid"&lt;/span&gt;&lt;span class="java_separator"&gt;)&lt;/span&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class="java_separator"&gt;}&lt;/span&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="java_separator"&gt;}&lt;/span&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;code&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;span class="Apple-style-span"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;So the &lt;code&gt;Read&lt;/code&gt; type class in Scala is generic enough to be instantiated for &lt;i&gt;all&lt;/i&gt; kinds of abstractions. Note that unlike interfaces in Java, the polymorphism is not coupled with inheritance hierarchies. With interface, your abstraction needs to implement the interface statically, which means that the interface has to exist before you design your abstraction. With type classes, the abstractions for &lt;code&gt;Int&lt;/code&gt; and &lt;code&gt;Float&lt;/code&gt; existed well before we define the &lt;code&gt;Read&lt;/code&gt; type class.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;Now if we have a generic function that takes a &lt;code&gt;String&lt;/code&gt;, we can make it return an instance of the type it is generic on.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;code&gt;&lt;span class="java_keyword"&gt;def&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;foo&lt;/span&gt;&lt;span class="java_separator"&gt;[&lt;/span&gt;&lt;span class="java_plain"&gt;T&amp;nbsp;&lt;/span&gt;&lt;span class="java_operator"&gt;:&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_type"&gt;Read&lt;/span&gt;&lt;span class="java_separator"&gt;](&lt;/span&gt;&lt;span class="java_plain"&gt;s&lt;/span&gt;&lt;span class="java_operator"&gt;:&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_type"&gt;String&lt;/span&gt;&lt;span class="java_separator"&gt;)&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_operator"&gt;=&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;implicitly&lt;/span&gt;&lt;span class="java_separator"&gt;[&lt;/span&gt;&lt;span class="java_type"&gt;Read&lt;/span&gt;&lt;span class="java_separator"&gt;[&lt;/span&gt;&lt;span class="java_plain"&gt;T&lt;/span&gt;&lt;span class="java_separator"&gt;]].&lt;/span&gt;&lt;span class="java_plain"&gt;read&lt;/span&gt;&lt;span class="java_separator"&gt;(&lt;/span&gt;&lt;span class="java_plain"&gt;s&lt;/span&gt;&lt;span class="java_separator"&gt;)&lt;/span&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;/code&gt;&lt;/span&gt;&lt;code&gt;&lt;/code&gt;&lt;/span&gt;&lt;code&gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="java_plain"&gt;foo&lt;/span&gt;&lt;span class="java_separator"&gt;[&lt;/span&gt;&lt;span class="java_type"&gt;Int&lt;/span&gt;&lt;span class="java_separator"&gt;](&lt;/span&gt;&lt;span class="java_literal"&gt;"123"&lt;/span&gt;&lt;span class="java_separator"&gt;)&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_comment"&gt;//&amp;nbsp;123&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="java_plain"&gt;foo&lt;/span&gt;&lt;span class="java_separator"&gt;[&lt;/span&gt;&lt;span class="java_type"&gt;Float&lt;/span&gt;&lt;span class="java_separator"&gt;](&lt;/span&gt;&lt;span class="java_literal"&gt;"123.0"&lt;/span&gt;&lt;span class="java_separator"&gt;)&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_comment"&gt;//&amp;nbsp;123.0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="java_plain"&gt;foo&lt;/span&gt;&lt;span class="java_separator"&gt;[&lt;/span&gt;&lt;span class="java_type"&gt;Name&lt;/span&gt;&lt;span class="java_separator"&gt;](&lt;/span&gt;&lt;span class="java_literal"&gt;"debasish/ghosh"&lt;/span&gt;&lt;span class="java_separator"&gt;)&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_comment"&gt;//&amp;nbsp;Name("ghosh",&amp;nbsp;"debasish")&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;code&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;span class="Apple-style-span"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;Ok .. so that was our generic &lt;code&gt;read&lt;/code&gt; API adapting violently to already existing abstractions. In this case it's exactly the Scala variant of how simple type class instances behave in Haskell. The authors of &lt;a rel="nofollow" target="_blank" href="http://www.realworldhaskell.org/blog/"&gt;Real World Haskell&lt;/a&gt; uses the term &lt;i&gt;open world assumption&lt;/i&gt; to describe this feature of the type class system.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;b&gt;Context for selecting the API instance&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;When the function &lt;code&gt;foo&lt;/code&gt; is invoked, the compiler needs to find out the exact instance of the &lt;code&gt;Read&lt;/code&gt; type class from the method dictionary in case of Haskell and from the list of available implicit conversions in case of Scala. For this we specify the context bound of the generic type &lt;code&gt;T&lt;/code&gt; as &lt;code&gt;T : Read&lt;/code&gt;. This is same as the context of the type class that we have in Haskell. &amp;nbsp;It specifies that the method &lt;code&gt;foo&lt;/code&gt; can return any type &lt;code&gt;T&lt;/code&gt; provided the type is an instance of the type class &lt;code&gt;Read&lt;/code&gt;. Apart from using the context bound, in Scala you can also use view bounds to implement context of a type class. The Haskell equivalent is ..&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;code&gt;&lt;span class="java_plain"&gt;foo&amp;nbsp;&lt;/span&gt;&lt;span class="java_operator"&gt;::&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_type"&gt;Read&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;a&amp;nbsp;&lt;/span&gt;&lt;span class="java_operator"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_type"&gt;String&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_operator"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;a&lt;/span&gt;&lt;/code&gt;&lt;/span&gt;&lt;code&gt;&lt;/code&gt;&lt;/span&gt;&lt;code&gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;code&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;span class="Apple-style-span"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;Irrespective of Haskell or Scala, our API becomes hugely expressive through such constraints that the static type system allows us to write. And all these constraints are checked during compile time.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;b&gt;Context in implementing specific instances&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;When defining a generic API, you can also set up a context for specific instances of the type class. Consider our &lt;code&gt;read&lt;/code&gt; method for a &lt;code&gt;List&lt;/code&gt; datatype in Scala. Haskell defines the instance as ..&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;code&gt;&lt;span class="java_keyword"&gt;instance&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_type"&gt;Read&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;a&amp;nbsp;&lt;/span&gt;&lt;span class="java_operator"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_type"&gt;Read&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_separator"&gt;[&lt;/span&gt;&lt;span class="java_plain"&gt;a&lt;/span&gt;&lt;span class="java_separator"&gt;]&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_keyword"&gt;where&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_separator"&gt;..&lt;/span&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;/code&gt;&lt;/span&gt;&lt;code&gt;&lt;/code&gt;&lt;/span&gt;&lt;code&gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;code&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;span class="Apple-style-span"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;Note the &lt;i&gt;context&lt;/i&gt; &lt;code&gt;Read a&lt;/code&gt; following the &lt;code&gt;instance&lt;/code&gt; keyword. This is called the &lt;i&gt;context of the type class instance&lt;/i&gt; which says that we can read a &lt;code&gt;List&lt;/code&gt; of &lt;code&gt;a&lt;/code&gt; only if all individual &lt;code&gt;a&lt;/code&gt;'s also implement the &lt;code&gt;Read&lt;/code&gt; type class.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;We do this in Scala using conditional implicits as ..&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;code&gt;&lt;span class="java_keyword"&gt;implicit&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_keyword"&gt;def&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_type"&gt;ListRead&lt;/span&gt;&lt;span class="java_separator"&gt;[&lt;/span&gt;&lt;span class="java_plain"&gt;A&lt;/span&gt;&lt;span class="java_separator"&gt;](&lt;/span&gt;&lt;span class="java_keyword"&gt;implicit&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;r&lt;/span&gt;&lt;span class="java_operator"&gt;:&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_type"&gt;Read&lt;/span&gt;&lt;span class="java_separator"&gt;[&lt;/span&gt;&lt;span class="java_plain"&gt;A&lt;/span&gt;&lt;span class="java_separator"&gt;])&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_operator"&gt;=&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;/code&gt;&lt;/span&gt;&lt;code&gt;&lt;/code&gt;&lt;/span&gt;&lt;code&gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class="java_keyword"&gt;new&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_type"&gt;Read&lt;/span&gt;&lt;span class="java_separator"&gt;[&lt;/span&gt;&lt;span class="java_type"&gt;List&lt;/span&gt;&lt;span class="java_separator"&gt;[&lt;/span&gt;&lt;span class="java_plain"&gt;A&lt;/span&gt;&lt;span class="java_separator"&gt;]]&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_separator"&gt;{&lt;/span&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class="java_keyword"&gt;def&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;read&lt;/span&gt;&lt;span class="java_separator"&gt;(&lt;/span&gt;&lt;span class="java_plain"&gt;s&lt;/span&gt;&lt;span class="java_operator"&gt;:&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_type"&gt;String&lt;/span&gt;&lt;span class="java_separator"&gt;)&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_operator"&gt;=&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_separator"&gt;{&lt;/span&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class="java_keyword"&gt;val&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;es&amp;nbsp;&lt;/span&gt;&lt;span class="java_operator"&gt;=&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;s&lt;/span&gt;&lt;span class="java_separator"&gt;.&lt;/span&gt;&lt;span class="java_plain"&gt;split&lt;/span&gt;&lt;span class="java_separator"&gt;(&lt;/span&gt;&lt;span class="java_literal"&gt;"&amp;nbsp;"&lt;/span&gt;&lt;span class="java_separator"&gt;).&lt;/span&gt;&lt;span class="java_plain"&gt;toList&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;es&lt;/span&gt;&lt;span class="java_separator"&gt;.&lt;/span&gt;&lt;span class="java_plain"&gt;map&lt;/span&gt;&lt;span class="java_separator"&gt;(&lt;/span&gt;&lt;span class="java_plain"&gt;r&lt;/span&gt;&lt;span class="java_separator"&gt;.&lt;/span&gt;&lt;span class="java_plain"&gt;read&lt;/span&gt;&lt;span class="java_separator"&gt;(&lt;/span&gt;&lt;span class="java_plain"&gt;_&lt;/span&gt;&lt;span class="java_separator"&gt;))&lt;/span&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class="java_separator"&gt;}&lt;/span&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class="java_separator"&gt;}&lt;/span&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;code&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;span class="Apple-style-span"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;The implicit definition itself takes another implicit argument to validate &lt;i&gt;during compile time&lt;/i&gt; that the individual elements of the &lt;code&gt;List&lt;/code&gt; also are instances of the type class. This is similar to what the context does in case of Haskell's type class instantiation.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;code&gt;&lt;span class="java_plain"&gt;foo&lt;/span&gt;&lt;span class="java_separator"&gt;[&lt;/span&gt;&lt;span class="java_type"&gt;List&lt;/span&gt;&lt;span class="java_separator"&gt;[&lt;/span&gt;&lt;span class="java_type"&gt;Int&lt;/span&gt;&lt;span class="java_separator"&gt;]](&lt;/span&gt;&lt;span class="java_literal"&gt;"12&amp;nbsp;234&amp;nbsp;45&amp;nbsp;678"&lt;/span&gt;&lt;span class="java_separator"&gt;)&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_comment"&gt;//&amp;nbsp;List(12,&amp;nbsp;234,&amp;nbsp;45,&amp;nbsp;678)&lt;/span&gt;&lt;/code&gt;&lt;/span&gt;&lt;code&gt;&lt;/code&gt;&lt;/span&gt;&lt;code&gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="java_plain"&gt;foo&lt;/span&gt;&lt;span class="java_separator"&gt;[&lt;/span&gt;&lt;span class="java_type"&gt;List&lt;/span&gt;&lt;span class="java_separator"&gt;[&lt;/span&gt;&lt;span class="java_type"&gt;Float&lt;/span&gt;&lt;span class="java_separator"&gt;]](&lt;/span&gt;&lt;span class="java_literal"&gt;"12.0&amp;nbsp;234.0&amp;nbsp;45.0&amp;nbsp;678.0"&lt;/span&gt;&lt;span class="java_separator"&gt;)&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_comment"&gt;//&amp;nbsp;List(12.0,&amp;nbsp;234.0,&amp;nbsp;45.0,&amp;nbsp;678.0)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="java_plain"&gt;foo&lt;/span&gt;&lt;span class="java_separator"&gt;[&lt;/span&gt;&lt;span class="java_type"&gt;List&lt;/span&gt;&lt;span class="java_separator"&gt;[&lt;/span&gt;&lt;span class="java_type"&gt;Name&lt;/span&gt;&lt;span class="java_separator"&gt;]](&lt;/span&gt;&lt;span class="java_literal"&gt;"debasish/ghosh&amp;nbsp;maulindu/chatterjee&amp;nbsp;nilanjan/das"&lt;/span&gt;&lt;span class="java_separator"&gt;)&lt;/span&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class="java_comment"&gt;//&amp;nbsp;List(Name("ghosh",&amp;nbsp;"debasish"),&amp;nbsp;Name("chatterjee",&amp;nbsp;"maulindu"),&amp;nbsp;Name("das",&amp;nbsp;"nilanjan"))&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;code&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;span class="Apple-style-span"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;As part of common extensions of GHCI, Haskell also provides support for overlapping instances of type classes ..&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;code&gt;&lt;span class="java_keyword"&gt;instance&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_type"&gt;Read&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;a&amp;nbsp;&lt;/span&gt;&lt;span class="java_operator"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_type"&gt;Read&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_separator"&gt;[&lt;/span&gt;&lt;span class="java_plain"&gt;a&lt;/span&gt;&lt;span class="java_separator"&gt;]&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_keyword"&gt;where&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_separator"&gt;..&lt;/span&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;/code&gt;&lt;/span&gt;&lt;code&gt;&lt;/code&gt;&lt;/span&gt;&lt;code&gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="java_keyword"&gt;instance&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_type"&gt;Read&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_separator"&gt;[&lt;/span&gt;&lt;span class="java_type"&gt;Int&lt;/span&gt;&lt;span class="java_separator"&gt;]&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_keyword"&gt;where&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_separator"&gt;..&lt;/span&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;code&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;span class="Apple-style-span"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;In such cases although there are two possible matches for &lt;code&gt;[Int]&lt;/code&gt;, the compiler can make an unambiguous decision and select the most specific instance. With Scala, there is no such ambiguity to be resolved since Scala anyway allows multiple implementations of the same type class and it's up to the user to import the specific one into the module.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;In this post I discussed the power that you get with type class based generic API design. In functional languages like Haskell, type classes are the most potent way to implement extensible APIs for the open world. Of course in object functional languages like Scala, you also have the power of subtyping, which comes good in many circumstances. It will be interesting to come up with a comparative analysis of situations when we prefer one to the other. But that's up for some other day, some other post ..&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/22587889-6180939564075434164?l=debasishg.blogspot.com" alt="" /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/clojure?a=oxX2sFUKsQA:wMrnyxc8xsw:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/clojure?a=oxX2sFUKsQA:wMrnyxc8xsw:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/clojure/~4/oxX2sFUKsQA" height="1" width="1"/&gt;</content>
		<author>
			<name>Debasish Ghosh</name>
			<uri>http://pipes.yahoo.com/pipes/pipe.info?_id=e35d6881f8ced55bed527c7a501fad8d</uri>
		</author>
		<source>
			<title type="html">Debasish Ghosh&amp;amp;#39;s Clojure posts</title>
			<subtitle type="html">Pipes Output</subtitle>
			<link rel="self" href="http://pipes.yahoo.com/pipes/pipe.run?_id=e35d6881f8ced55bed527c7a501fad8d&amp;_render=rss" />
			<id>http://pipes.yahoo.com/pipes/pipe.run?_id=e35d6881f8ced55bed527c7a501fad8d&amp;_render=rss</id>
			<updated>2010-09-03T21:00:23+00:00</updated>
		</source>
	<feedburner:origLink>http://debasishg.blogspot.com/2010/09/towards-generic-apis-for-open-world.html</feedburner:origLink></entry>

	<entry xml:lang="en">
		<title type="html">Today in the Intertweets (Sept 2nd Ed)</title>
		<link href="http://feedproxy.google.com/~r/clojure/~3/gGPNhc8mRb8/" />
		<id>http://disclojure.org/?p=1139</id>
		<updated>2010-09-03T07:57:56+00:00</updated>
		<content type="html">&lt;ul&gt;
&lt;li&gt;Programming Challenge for Newbies in #&lt;a href="http://search.twitter.com/search?q=%23Clojure" rel="nofollow" target="_blank" title="Search Twitter for "&gt;Clojure&lt;/a&gt; and #&lt;a href="http://search.twitter.com/search?q=%23Python" rel="nofollow" target="_blank" title="Search Twitter for "&gt;Python&lt;/a&gt; too? Share your thoughts (&lt;a href="http://rubylearning.com/blog/2010/09/02/programming-challenge-for-newbies-in-clojure-and-python-too/"&gt;here&lt;/a&gt;, via @&lt;a href="http://twitter.com/IndianGuru" rel="nofollow" target="_blank" title="View IndianGuru's Twitter Profile"&gt;IndianGuru&lt;/a&gt;) &amp;#8212; &lt;a href="http://rubylearning.com/"&gt;RubyLearning&lt;/a&gt; has been holding monthly Ruby programming challenges for newbies. They&amp;#8217;re thinking about expanding them to Clojure and Python too.&lt;/li&gt;
&lt;li&gt;John Rose on JVM Summit is all about moving towards a functional paradigm; it seems #&lt;a href="http://search.twitter.com/search?q=%23clojure" rel="nofollow" target="_blank" title="Search Twitter for "&gt;clojure&lt;/a&gt;&amp;#8217;s guiding the way (&lt;a href="http://medianetwork.oracle.com/media/show/15487"&gt;here&lt;/a&gt;, via @&lt;a href="http://twitter.com/pedroteixeira" rel="nofollow" target="_blank" title="View pedroteixeira's Twitter Profile"&gt;pedroteixeira&lt;/a&gt;) &amp;#8212; didn&amp;#8217;t I say those talks were full of gold?!&lt;/li&gt;
&lt;li&gt;cfmljure &amp;#8211; calling #&lt;a href="http://search.twitter.com/search?q=%23clojure" rel="nofollow" target="_blank" title="Search Twitter for "&gt;clojure&lt;/a&gt; from #&lt;a href="http://search.twitter.com/search?q=%23coldfusion" rel="nofollow" target="_blank" title="Search Twitter for "&gt;coldfusion&lt;/a&gt; &amp;#8211; is available to play (&lt;a href="http://github.com/seancorfield/cfmljure"&gt;here&lt;/a&gt;, via @&lt;a href="http://twitter.com/seancofrield" rel="nofollow" target="_blank" title="View seancofrield's Twitter Profile"&gt;seancofrield&lt;/a&gt;) &amp;#8212; &lt;a href="http://www.adobe.com/products/coldfusion/"&gt;ColdFusion&lt;/a&gt; is a veteran of the web scripting languages/frameworks. Now you can finally do cool stuff with it ;)&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/disclojure?a=Vq9H2w8uxM4:BZ8FpvnVNmk:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/disclojure?d=yIl2AUoC8zA" border="0" /&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/disclojure?a=Vq9H2w8uxM4:BZ8FpvnVNmk:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/disclojure?i=Vq9H2w8uxM4:BZ8FpvnVNmk:D7DqB2pKExk" border="0" /&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/disclojure?a=Vq9H2w8uxM4:BZ8FpvnVNmk:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/disclojure?i=Vq9H2w8uxM4:BZ8FpvnVNmk:V_sGLiPBpWU" border="0" /&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/disclojure?a=Vq9H2w8uxM4:BZ8FpvnVNmk:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/disclojure?i=Vq9H2w8uxM4:BZ8FpvnVNmk:gIN9vFwOqvQ" border="0" /&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/disclojure/~4/Vq9H2w8uxM4" height="1" width="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/clojure?a=gGPNhc8mRb8:BZ8FpvnVNmk:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/clojure?a=gGPNhc8mRb8:BZ8FpvnVNmk:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/clojure/~4/gGPNhc8mRb8" height="1" width="1"/&gt;</content>
		<author>
			<name>Toni Batchelli</name>
			<uri>http://disclojure.org</uri>
		</author>
		<source>
			<title type="html">disclojure: all things clojure</title>
			<subtitle type="html">public disclosure of all things Clojure</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/disclojure" />
			<id>http://feeds.feedburner.com/disclojure</id>
			<updated>2010-09-03T08:30:53+00:00</updated>
		</source>
	<feedburner:origLink>http://feedproxy.google.com/~r/disclojure/~3/Vq9H2w8uxM4/</feedburner:origLink></entry>

	<entry xml:lang="en">
		<title type="html">Leiningen (unknown severity): Release leiningen 1.3.0 to clojars</title>
		<link href="http://feedproxy.google.com/~r/clojure/~3/m3xhWjOXjdI/" />
		<id>http://github.com/technomancy/leiningen/issues/#issue/106</id>
		<updated>2010-09-03T00:00:00+00:00</updated>
		<content type="html">Leiningen (unknown severity): Release leiningen 1.3.0 to clojars&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/clojure?a=m3xhWjOXjdI:umqgTze1uOI:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/clojure?a=m3xhWjOXjdI:umqgTze1uOI:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/clojure/~4/m3xhWjOXjdI" height="1" width="1"/&gt;</content>
		<author>
			<name>BugSpy</name>
			<uri>http://bugspy.net</uri>
		</author>
		<source>
			<title type="html">BugSpy.net - Reports By Tag: clojure</title>
			<link rel="self" href="http://bugspy.net/tag/clojure/?format=rss" />
			<id>http://bugspy.net/tag/clojure/?format=rss</id>
			<updated>2010-09-03T21:01:14+00:00</updated>
		</source>
	<feedburner:origLink>http://github.com/technomancy/leiningen/issues/#issue/106</feedburner:origLink></entry>

	<entry xml:lang="en">
		<title type="html">Compojure Demystified with an example – Part 5</title>
		<link href="" />
		<id>https://sivajag.wordpress.com/?p=173</id>
		<updated>2010-09-02T07:19:37+00:00</updated>
		<content type="html">In this part lets write our own middleware. From part4 you will remember, &amp;#8220;Middleware are functions that could be chained together to process a request. Middleware functions can take any number of arguments, but the spec stats that first argument should be a handler and function should return a handler. An example for middleware is [...]&lt;img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=techbehindtech.com&amp;blog=11954221&amp;post=173&amp;subd=sivajag&amp;ref=&amp;feed=1" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/clojure?a=Ro2eosQjYao:NVQ7xAZT92I:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/clojure?a=Ro2eosQjYao:NVQ7xAZT92I:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content>
		<author>
			<name>Siva Jagadeesan</name>
			<uri>http://techbehindtech.com</uri>
		</author>
		<source>
			<title type="html">Tech behind Tech » Clojure</title>
			<subtitle type="html">Raw information. No finesse :)</subtitle>
			<link rel="self" href="http://techbehindtech.com/category/clojure/feed/" />
			<id>http://techbehindtech.com/category/clojure/feed/</id>
			<updated>2010-09-03T21:00:38+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">Today in the Intertweets (Sept 1st Ed)</title>
		<link href="http://feedproxy.google.com/~r/clojure/~3/DdR0V10aA5M/" />
		<id>http://disclojure.org/?p=1137</id>
		<updated>2010-09-02T07:01:32+00:00</updated>
		<content type="html">&lt;ul&gt;
&lt;li&gt;Editing trees in #&lt;a href="http://search.twitter.com/search?q=%23clojure" rel="nofollow" target="_blank" title="Search Twitter for "&gt;clojure&lt;/a&gt; with clojure.zip (&lt;a href="http://www.exampler.com/blog/2010/09/01/editing-trees-in-clojure-with-clojurezip/"&gt;here&lt;/a&gt;, via @&lt;a href="http://twitter.com/marick" rel="nofollow" target="_blank" title="View marick's Twitter Profile"&gt;marick&lt;/a&gt;) &amp;#8212; clojure.zip is a functional traverse and modify (well, create modified copies of) trees. How to use this library is not immediately obvious, and this article explains how to use them.&lt;/li&gt;
&lt;li&gt;The Joy of Clojure: Thinking the Clojure Way &amp;#8211; Book Review (&lt;a href="http://books.dzone.com/reviews/joy-clojure-thinking-clojure-0"&gt;here&lt;/a&gt;, via @&lt;a href="http://twitter.com/ibmkhd" rel="nofollow" target="_blank" title="View ibmkhd's Twitter Profile"&gt;ibmkhd&lt;/a&gt;) &amp;#8212; &amp;#8220;reading &amp;#8220;Joy of Clojure&amp;#8221; might actually require the reader to use a dictionary, as the lexical range used by the authors is broad and might be a barrier&amp;#8221;. I disagree, english is my third language and I didn&amp;#8217;t need a dictionary. I even got some of the jokes! This is a horribly shallow review, actually.&lt;/li&gt;
&lt;li&gt;Did you know about linear search in #&lt;a href="http://search.twitter.com/search?q=%23clojure" rel="nofollow" target="_blank" title="Search Twitter for "&gt;clojure&lt;/a&gt;? (&lt;a href="http://kotka.de/blog/2010/09/Did_you_know_VIII.html"&gt;here&lt;/a&gt;, via @&lt;a href="http://twitter.com/kotarak" rel="nofollow" target="_blank" title="View kotarak's Twitter Profile"&gt;kotarak&lt;/a&gt;) &amp;#8212; Short article explaining how &amp;#8216;contains?&amp;#8217; works (which seems to confuse a lot of people) and  how &amp;#8217;some&amp;#8217; is a very useful higher-level function for finding elements in a sequence.&lt;/li&gt;
&lt;li&gt;&amp;#8220;at the moment we believe #&lt;a href="http://search.twitter.com/search?q=%23fsharp" rel="nofollow" target="_blank" title="Search Twitter for "&gt;fsharp&lt;/a&gt; and #&lt;a href="http://search.twitter.com/search?q=%23clojure" rel="nofollow" target="_blank" title="Search Twitter for "&gt;clojure&lt;/a&gt; to be better suited to most organisations for assessing than #&lt;a href="http://search.twitter.com/search?q=%23scala" rel="nofollow" target="_blank" title="Search Twitter for "&gt;scala&lt;/a&gt;&amp;#8221; (&lt;a href="http://www.thoughtworks.com/sites/www.thoughtworks.com/files/files/thoughtworks-tech-radar-august-2010-US-color.pdf"&gt;here&lt;/a&gt;, via @&lt;a href="http://twitter.com/ptrelford" rel="nofollow" target="_blank" title="View ptrelford's Twitter Profile"&gt;ptrelford&lt;/a&gt;) &amp;#8212; &lt;a href="http://www.thoughtworks.com/radar/"&gt;Technology Radar&lt;/a&gt; is an advisory publication by the IT consultancy &lt;a href="http://www.thoughtworks.com/"&gt;ThoughtWorks&lt;/a&gt; that periodically reviews new technologies and assesses their levels of maturity and desirability for IT customers. Well, in this issue they are &lt;a href="http://www.thoughtworks.com/sites/www.thoughtworks.com/files/files/tw-radar-april-2010.pdf"&gt;continuing&lt;/a&gt; to favor Clojure over Scala&amp;#8230; aaaand now it is time to run for cover ;)&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/disclojure?a=6p9xmVrNl_k:-SutIPJzlUk:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/disclojure?d=yIl2AUoC8zA" border="0" /&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/disclojure?a=6p9xmVrNl_k:-SutIPJzlUk:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/disclojure?i=6p9xmVrNl_k:-SutIPJzlUk:D7DqB2pKExk" border="0" /&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/disclojure?a=6p9xmVrNl_k:-SutIPJzlUk:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/disclojure?i=6p9xmVrNl_k:-SutIPJzlUk:V_sGLiPBpWU" border="0" /&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/disclojure?a=6p9xmVrNl_k:-SutIPJzlUk:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/disclojure?i=6p9xmVrNl_k:-SutIPJzlUk:gIN9vFwOqvQ" border="0" /&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/disclojure/~4/6p9xmVrNl_k" height="1" width="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/clojure?a=DdR0V10aA5M:-SutIPJzlUk:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/clojure?a=DdR0V10aA5M:-SutIPJzlUk:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/clojure/~4/DdR0V10aA5M" height="1" width="1"/&gt;</content>
		<author>
			<name>Toni Batchelli</name>
			<uri>http://disclojure.org</uri>
		</author>
		<source>
			<title type="html">disclojure: all things clojure</title>
			<subtitle type="html">public disclosure of all things Clojure</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/disclojure" />
			<id>http://feeds.feedburner.com/disclojure</id>
			<updated>2010-09-03T08:30:53+00:00</updated>
		</source>
	<feedburner:origLink>http://feedproxy.google.com/~r/disclojure/~3/6p9xmVrNl_k/</feedburner:origLink></entry>

	<entry>
		<title type="html">Clojure: Mocking</title>
		<link href="http://feedproxy.google.com/~r/clojure/~3/fx_31ADnK90/clojure-mocking.html" />
		<id>tag:blogger.com,1999:blog-12467669.post-2486214703634967640</id>
		<updated>2010-09-02T06:54:52+00:00</updated>
		<content type="html">An &lt;a href="http://blog.jayfields.com/2010/08/clojuretest-introduction.html"&gt;introduction to clojure.test&lt;/a&gt; is easy, but it doesn't take long before you feel like you need a mocking framework. As far as I know, you have 3 options.&lt;ol&gt;&lt;li&gt;Take a look at &lt;a href="http://github.com/marick/Midje"&gt;Midje&lt;/a&gt;. I haven't gone down this path, but it looks like the most mature option if you're looking for a sophisticated solution.&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Go simple. Let's take an example where you want to call a function that computes a value and sends a response to a gateway. Your first implementation looks like the code below. (&lt;a href="http://blog.jayfields.com/2010/07/clojure-destructuring.html"&gt;destructuring explained&lt;/a&gt;)&lt;pre&gt;(defn withdraw [&amp;amp; {:keys [balance withdrawal account-number]}]&lt;br /&gt; (gateway/process {:balance (- balance withdrawal)&lt;br /&gt;                   :withdrawal withdrawal&lt;br /&gt;                   :account-number account-number}))&lt;/pre&gt;No, it's not pure. That's not the point. Let's pretend that this impure function is the right design and focus on how we would test it.&lt;br /&gt;&lt;br /&gt;You can change the code a bit and pass in the gateway/process function as an argument. Once you've changed how the code works you can test it by passing identity as the function argument in your tests. The full example is below.&lt;pre&gt;(ns gateway)&lt;br /&gt;&lt;br /&gt;(defn process [m] (println m))&lt;br /&gt;&lt;br /&gt;(ns controller&lt;br /&gt; (:use clojure.test))&lt;br /&gt;&lt;br /&gt;(defn withdraw [f &amp;amp; {:keys [balance withdrawal account-number]}]&lt;br /&gt; (f {:balance (- balance withdrawal)&lt;br /&gt;     :withdrawal withdrawal&lt;br /&gt;     :account-number account-number}))&lt;br /&gt;&lt;br /&gt;(withdraw gateway/process :balance 100 :withdrawal 22 :account-number 4)&lt;br /&gt;;; =&gt; {:balance 78, :withdrawal 22, :account-number 4}&lt;br /&gt;&lt;br /&gt;(deftest withdraw-test&lt;br /&gt; (is (= {:balance 78, :withdrawal 22, :account-number 4}&lt;br /&gt;  (withdraw identity :balance 100 :withdrawal 22 :account-number 4))))&lt;br /&gt;&lt;br /&gt;(run-all-tests #"controller")&lt;/pre&gt;If you run the previous example you will see the println output and the clojure.test output, verifying that our code is working as we expected. This simple solution of passing in your side effect function and using identity in your tests can often obviate any need for a mock.&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Solution 2 works well, but has the limitations that only one side-effecty function can be passed in and it's result must be used as the return value.&lt;br /&gt;&lt;br /&gt;Let's extend our example and say that we want to log a message if the withdrawal would cause insufficient funds. (Our gateway/process and log/write functions will simply println since this is only an example, but in production code their behavior would differ and both would be required)&lt;pre&gt;(ns gateway)&lt;br /&gt;&lt;br /&gt;(defn process [m] (println "gateway: " m))&lt;br /&gt;&lt;br /&gt;(ns log)&lt;br /&gt;&lt;br /&gt;(defn write [m] (println "log: " m))&lt;br /&gt;&lt;br /&gt;(ns controller&lt;br /&gt;  (:use clojure.test))&lt;br /&gt;&lt;br /&gt;(defn withdraw [&amp;amp; {:keys [balance withdrawal account-number]}]&lt;br /&gt;  (let [new-balance (- balance withdrawal)]&lt;br /&gt;    (if (&gt; 0 new-balance)&lt;br /&gt;      (log/write "insufficient funds")&lt;br /&gt;      (gateway/process {:balance new-balance&lt;br /&gt;                        :withdrawal withdrawal&lt;br /&gt;                        :account-number account-number}))))&lt;br /&gt;&lt;br /&gt;(withdraw :balance 100 :withdrawal 22 :account-number 4)&lt;br /&gt;;; =&gt; gateway:  {:balance 78, :withdrawal 22, :account-number 4}&lt;br /&gt;&lt;br /&gt;(withdraw :balance 100 :withdrawal 220 :account-number 4)&lt;br /&gt;;; =&gt; log:  insufficient funds&lt;/pre&gt;Our new withdraw implementation calls two functions that have side effects. We could pass in both functions, but that solution doesn't seem to scale very well as the number of passed functions grows. Also, passing in multiple functions tends to clutter the signature and make it hard to remember what is the valid order for the arguments. Finally, if we need withdraw to always return a map showing the balance and withdrawal amount, there would be no easy solution for verifying the string sent to log/write.&lt;br /&gt;&lt;br /&gt;Given our implementation of withdraw, writing a test that verifies that gateway/process and log/write are called correctly looks like a job for a mock. However, thanks to Clojure's binding function, it's very easy to redefine both of those functions to capture values that can later be tested.&lt;br /&gt;&lt;br /&gt;The following code rebinds both gateway/process and log/write to partial functions that capture whatever is passed to them in an atom that can easily be verified directly in the test.&lt;pre&gt;(ns gateway)&lt;br /&gt;&lt;br /&gt;(defn process [m] (println "gateway: " m))&lt;br /&gt;&lt;br /&gt;(ns log)&lt;br /&gt;&lt;br /&gt;(defn write [m] (println "log: " m))&lt;br /&gt;&lt;br /&gt;(ns controller&lt;br /&gt;  (:use clojure.test))&lt;br /&gt;&lt;br /&gt;(defn withdraw [&amp;amp; {:keys [balance withdrawal account-number]}]&lt;br /&gt;  (let [new-balance (- balance withdrawal)]&lt;br /&gt;    (if (&gt; 0 new-balance)&lt;br /&gt;      (log/write "insufficient funds")&lt;br /&gt;      (gateway/process {:balance new-balance&lt;br /&gt;                        :withdrawal withdrawal&lt;br /&gt;                        :account-number account-number}))))&lt;br /&gt;&lt;br /&gt;(deftest withdraw-test1&lt;br /&gt;  (let [result (atom nil)]&lt;br /&gt;    (binding [gateway/process (partial reset! result)]&lt;br /&gt;      (withdraw :balance 100 :withdrawal 22 :account-number 4)&lt;br /&gt;      (is (= {:balance 78, :withdrawal 22, :account-number 4} @result)))))&lt;br /&gt;&lt;br /&gt;(deftest withdraw-test2&lt;br /&gt;  (let [result (atom nil)]&lt;br /&gt;    (binding [log/write (partial reset! result)]&lt;br /&gt;      (withdraw :balance 100 :withdrawal 220 :account-number 4)&lt;br /&gt;      (is (= "insufficient funds" @result)))))&lt;br /&gt;&lt;br /&gt;(run-all-tests #"controller")&lt;/pre&gt;&lt;/li&gt;&lt;/ol&gt;In general I use option 2 when I can get away with it, and option 3 where necessary. Option 3 adds enough additional code that I'd probably look into Midje quickly if I found myself writing a more than a few tests that way. However, I generally go out of my way to design pure functions, and I don't find myself needing either of these techniques very often.&lt;div class="blogger-post-footer"&gt;&lt;br /&gt;&lt;a href="http://www.jayfields.com"&gt;&amp;copy; Jay Fields - www.jayfields.com&lt;/a&gt;&lt;img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/12467669-2486214703634967640?l=blog.jayfields.com" alt="" /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/clojure?a=fx_31ADnK90:Zv4ZLB19bNc:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/clojure?a=fx_31ADnK90:Zv4ZLB19bNc:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/clojure/~4/fx_31ADnK90" height="1" width="1"/&gt;</content>
		<author>
			<name>Jay Fields</name>
			<email>blogger@jayfields.com</email>
			<uri>http://blog.jayfields.com/search/label/clojure</uri>
		</author>
		<source>
			<title type="html">Jay Fields' Thoughts</title>
			<subtitle type="html">experiences in software development</subtitle>
			<link rel="self" href="http://blog.jayfields.com/feeds/posts/default/-/clojure" />
			<id>tag:blogger.com,1999:blog-12467669</id>
			<updated>2010-09-03T18:01:24+00:00</updated>
		</source>
	<feedburner:origLink>http://blog.jayfields.com/2010/09/clojure-mocking.html</feedburner:origLink></entry>

	<entry>
		<title type="html">Clojure: Mocking</title>
		<link href="http://feedproxy.google.com/~r/clojure/~3/onmQ_1QCGYI/clojure-mocking" />
		<id>http://pipes.yahoo.com/pipes/28361 at http://java.dzone.com</id>
		<updated>2010-09-02T05:40:56+00:00</updated>
		<content type="html">An introduction to clojure.test is easy, but it doesn't take long before you feel like you need a mocking framework. As far as I know, you have 3 options. James Sugrue&lt;img src="http://feeds.feedburner.com/~r/javalobby/frontpage/~4/uuHCvuJFfE4" height="1" width="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/clojure?a=onmQ_1QCGYI:naq-Lh_M964:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/clojure?a=onmQ_1QCGYI:naq-Lh_M964:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/clojure/~4/onmQ_1QCGYI" height="1" width="1"/&gt;</content>
		<author>
			<name>Javalobby</name>
			<uri>http://pipes.yahoo.com/pipes/pipe.info?_id=f8b56ef73099743fdfe6336dd7cd0d5c</uri>
		</author>
		<source>
			<title type="html">Javalobby</title>
			<subtitle type="html">Pipes Output</subtitle>
			<link rel="self" href="http://pipes.yahoo.com/pipes/pipe.run?_id=f8b56ef73099743fdfe6336dd7cd0d5c&amp;_render=rss" />
			<id>http://pipes.yahoo.com/pipes/pipe.run?_id=f8b56ef73099743fdfe6336dd7cd0d5c&amp;_render=rss</id>
			<updated>2010-09-03T21:00:38+00:00</updated>
		</source>
	<feedburner:origLink>http://feeds.dzone.com/~r/javalobby/frontpage/~3/uuHCvuJFfE4/clojure-mocking</feedburner:origLink></entry>

	<entry xml:lang="en">
		<title type="html">Programming Challenge for Newbies in Clojure and Python too?</title>
		<link href="http://feedproxy.google.com/~r/clojure/~3/q_aeGkw37IE/" />
		<id>http://rubylearning.com/blog/?p=4408</id>
		<updated>2010-09-02T02:09:35+00:00</updated>
		<content type="html">&lt;p&gt;&lt;/p&gt;
&lt;div class="topsy_widget_data topsy_theme_brick-red"&gt;&lt;/div&gt;
&lt;div&gt;
&lt;h3&gt;Programming Challenge for Newbies in Clojure and Python too?&lt;/h3&gt;
&lt;p&gt;RubyLearning has been conducting the monthly Ruby Programming Challenge for Newbies for over a year now and so far 12 challenges have been completed. The 13th challenge is in progress. All this was possible due to the extensive support we got from &lt;a href="http://ruby-challenge.rubylearning.org/"&gt;Rubyists&lt;/a&gt; across the world. Also, you all indicated that &lt;a href="http://rubylearning.com/blog/2010/08/09/do-you-want-us-to-continue-with-the-ruby-challenge-for-newbies/"&gt;we continue with these challenges&lt;/a&gt; in the months to come.&lt;/p&gt;
&lt;p&gt;Recently, my colleague &lt;a href="http://blog.dhananjaynene.com/"&gt;Dhananjay Nene&lt;/a&gt; posted a &lt;a href="http://codeblog.dhananjaynene.com/2010/09/code-kata-ruby-programming-challenge-for-newbies-in-python/"&gt;Python based solution&lt;/a&gt; to the 13th Ruby challenge. While discussing the solution it struck me that it would help Clojure and Python Newbies, if we opened up these challenges in these languages too. Dhananjay and some of my Clojure colleagues are interested in evaluating the submitted solutions in Clojure and Python and maybe we could start the challenges from Oct. 2010.&lt;/p&gt;
&lt;p class="update"&gt;Clojure and Python enthusiasts &amp;#8211; interested? What Do you Think? What is Your Opinion? Please share in the comments below.&lt;/p&gt;
&lt;p&gt;&lt;img class="alignleft" src="http://rubylearning.com/images/update.jpg" alt="Update" title="Update" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;3rd Sept.&lt;/b&gt; Thanks for the very encouraging response. Based on the feedback received so far, we have decided the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;We will start the challenges for Clojure, Python and Ruby from &lt;b&gt;1st Oct. 2010&lt;/b&gt;. We will call these &amp;#8220;&lt;b&gt;Programming Challenge for Newbies&lt;/b&gt;&amp;#8221; and host it on this blog till end Dec. 2010. If the response is encouraging, we can host the challenges on different domains.&lt;/li&gt;
&lt;li&gt;We will have separate panels to evaluate the solutions. One each for Clojure, Python and Ruby.&lt;/li&gt;
&lt;li&gt;We will keep separate prizes for the 3 languages (and hopefully would find some sponsors).&lt;/li&gt;
&lt;li&gt;The challenge problem setters (fixed till Dec. 2010) would be told that the problem should be solvable in all languages and specifically Clojure, Python and Ruby. This means that the problem setter should not set a problem that needs to be solved by some specific language feature.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;p&gt;Technorati Tags: &lt;a href="http://technorati.com/tag/Clojure" rel="tag"&gt;Clojure&lt;/a&gt;, &lt;a href="http://technorati.com/tag/Python" rel="tag"&gt; Python&lt;/a&gt;, &lt;a href="http://technorati.com/tag/RPCFN" rel="tag"&gt; RPCFN&lt;/a&gt;, &lt;a href="http://technorati.com/tag/Ruby+Challenge" rel="tag"&gt; Ruby Challenge&lt;/a&gt;, &lt;a href="http://technorati.com/tag/Ruby" rel="tag"&gt; Ruby&lt;/a&gt;, &lt;a href="http://technorati.com/tag/Programming" rel="tag"&gt; Programming&lt;/a&gt;&lt;/p&gt;
Posted by &lt;b&gt;Satish Talim&lt;/b&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/clojure?a=q_aeGkw37IE:C6gu1v5uTWM:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/clojure?a=q_aeGkw37IE:C6gu1v5uTWM:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/clojure/~4/q_aeGkw37IE" height="1" width="1"/&gt;</content>
		<author>
			<name>RubyLearning Blog</name>
			<uri>http://rubylearning.com/blog</uri>
		</author>
		<source>
			<title type="html">RubyLearning Blog » Clojure</title>
			<subtitle type="html">Ruby helps programmers have more fun!</subtitle>
			<link rel="self" href="http://rubylearning.com/blog/tag/clojure/feed/" />
			<id>http://rubylearning.com/blog/tag/clojure/feed/</id>
			<updated>2010-09-03T08:00:30+00:00</updated>
		</source>
	<feedburner:origLink>http://rubylearning.com/blog/2010/09/02/programming-challenge-for-newbies-in-clojure-and-python-too/</feedburner:origLink></entry>

	<entry xml:lang="en">
		<title type="html">Leiningen (unknown severity): Certain dev-dependencies cause NPE during deps task.</title>
		<link href="http://feedproxy.google.com/~r/clojure/~3/PIDLBHWC7bo/" />
		<id>http://github.com/technomancy/leiningen/issues/#issue/105</id>
		<updated>2010-09-02T00:00:00+00:00</updated>
		<content type="html">Leiningen (unknown severity): Certain dev-dependencies cause NPE during deps task.&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/clojure?a=PIDLBHWC7bo:MkNj6Rub5ZM:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/clojure?a=PIDLBHWC7bo:MkNj6Rub5ZM:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/clojure/~4/PIDLBHWC7bo" height="1" width="1"/&gt;</content>
		<author>
			<name>BugSpy</name>
			<uri>http://bugspy.net</uri>
		</author>
		<source>
			<title type="html">BugSpy.net - Reports By Tag: clojure</title>
			<link rel="self" href="http://bugspy.net/tag/clojure/?format=rss" />
			<id>http://bugspy.net/tag/clojure/?format=rss</id>
			<updated>2010-09-03T21:01:14+00:00</updated>
		</source>
	<feedburner:origLink>http://github.com/technomancy/leiningen/issues/#issue/105</feedburner:origLink></entry>

	<entry>
		<title type="html">git cheatsheet and class notes</title>
		<link href="http://feedproxy.google.com/~r/clojure/~3/rYKdIGfUNpg/" />
		<id>http://www.xcombinator.com/?p=274</id>
		<updated>2010-09-01T19:27:48+00:00</updated>
		<content type="html">&lt;p&gt;I recently gave a talk at work about git. I created a cheatsheet based on &lt;a rel="nofollow" target="_blank" href="http://clojure.org/cheatsheet"&gt;Steve Tayon&amp;#8217;s Clojure Cheatsheet&lt;/a&gt;. &lt;/p&gt;
&lt;div id="attachment_276" class="wp-caption center"&gt;&lt;a rel="nofollow" target="_blank" href="http://www.xcombinator.com/wp-content/uploads/2010/09/git-class-cheat-sheet.pdf"&gt;&lt;img src="http://www.xcombinator.com/wp-content/uploads/2010/09/git-cheat-sheet-preview.jpg" alt="Git Cheat Sheet Preview" title="Git Cheat Sheet Preview" width="496" height="347" class="size-full wp-image-276" /&gt;&lt;/a&gt;&lt;p class="wp-caption-text"&gt;Git Cheat Sheet Preview&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;I realize there are a &lt;a rel="nofollow" target="_blank" href="http://zrusin.blogspot.com/2007/09/git-cheat-sheet.html"&gt;number&lt;/a&gt; &lt;a rel="nofollow" target="_blank" href="http://github.com/guides/git-cheat-sheet"&gt;of&lt;/a&gt; &lt;a rel="nofollow" target="_blank" href="http://cheat.errtheblog.com/s/git"&gt;cheatsheets&lt;/a&gt; for git already. However, I wanted a simple, one-page sheet specifically for my attendees. &lt;/p&gt;
&lt;p&gt;You can download it here:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://www.xcombinator.com/wp-content/uploads/2010/09/git-class-cheat-sheet.pdf"&gt;git cheatsheet pdf&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://github.com/jashmenn/talks/raw/master/git/cheat-sheet/git-class-cheat-sheet.tex"&gt;git cheatsheet LaTeX source&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Like it? Hate it? Find a typo? &lt;a rel="nofollow" target="_blank" href="http://www.xcombinator.com/2010/09/01/git-cheat-sheet-and-class-notes/#comments"&gt;Leave your feedback in the comments!&lt;/a&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Here are my raw notes from the talk:&lt;br /&gt;
&lt;code&gt;&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;
;; -*- mode: Markdown; -*-

# How to read:
commands are indented
actions to perform while presenting are marked with @
left to right

# Welcome
see progit.org
what is version control

why use it:

  * backup/restore
  * synchronization sharing
  * track changes
  * ownership
  * branching and merging

who has used subversion 

git
  * you've heard its distributed
  * b/c branching and merging

pace - slow, no slides

leave with practical understanding

# Install &amp;amp; Config

    sudo port install git-core +svn
    git config --global user.name "Nate Murray"
    git config --global user.email "nate@natemurray.com"

# Basic Commands

    cd ~
    mkdir -p projects/demo       # explain only a little
    cd projects/demo
    git init
    git status                   # nothing here
    ls -a                        # talk .git repository vs. working copy
    echo "version 1" &gt; README.txt
    git status                   # untracked file
    git add README.txt
    git status                   # changes to be committed
    git commit -m "added version one of the file"
    git status                   # clean

stop, draw the picture of the local operation phases - e.g. svn vs. git

&gt; Principle 1: (almost) everything is local

so now that you know about the staging area, lets do it again

    echo "new file" &gt; sheep.rb
    git status                   # draw untracked
    git add sheep.rb
    git status                   # draw staged
    git commit -m "added"

    cat README.txt                 # draw unmodified
    echo "version 2" &gt; README.txt
    git status                   # draw modified
    git commit -a -m "updated version" # shorthand for git add
    git status

Tips:

    git config --global alias.st status
    git st

# Git Internals

* Before we can talk about branching you *have* to understand how git (tried to avoid this)
* files and folders

three objects -  @ Draw first commit

  * blob        - raw data
  * tree        - folder (stores blobs and trees)
  * commit      - snapshot of the repo + meta 

You won't need to use `git cat-file` on a daily basis. however, understanding
the concepts we're going to talk about is really important for branching.

    git log # view the log
    git show ----  # first commit, whatever it is

    git cat-file -p  ---- # first commit
    git cat-file -p  ---- # tree
    git cat-file -p  ---- # blob

draw the rest using git `cat-file`

    git log           # show the log again
    git cat-file -p ---- # second commit

draw the picture. point out the parent connection.
note committer / author

    git cat-file -p ---- # tree

note here there are two blobs!

finish drawing out the second commit
* git stores reference to first file.
* snapshot of the *whole project*
* git stores each file once
* filename is in the `tree` 

draw the last commit

     git log
     git cat-file -p ---- # third commit

&gt; Principle #2 : Git commits are snapshots

* A commit in git is a snapshot of the entire project, not just a list of diffs.
* snapshot is based on the SHA hash function. guarantees file integrity

# refs/branches

questions?

@ stop. redraw commits as *linear* . looking only at commits

ready to define a branch
a branch is a pointer to a commi
text file with a sha. thats it. 

start with one branch called `master`

    git branch

bash prompt

    # skip this
    tree .git/refs/
    cat .git/refs/heads/master
    git log
    # compare the SHAs

update diagram by adding a `ref` to our commit. (`master`). 

@ draw circle pointing to commit

create testing branch

# branching

So lets create another branch:

    git branch testing
    git branch

only created, didn't switch. just created a ref pointing to this
commit

@ update diagram

How does git know what branch we are "on"?

special ref called `HEAD` that points to the local branch
since we are still on master HEAD points to master

@ add HEAD

To switch working copy, use the `git checkout`

    git checkout testing
    git branch

HEAD moves from `master` to `testing`

@ update diagram

master and testing point to the same commit, working directory isn't changed

checkout means something different in git than it does in svn.
checkout in git to switch our working directory to a particular commit. 

now make changes:

    cat README.txt
    echo "we are on the testing branch!" &gt; README.txt
    cat README.txt
    git commit -a -m "updated the readme"
    git log

@ update diagram, adding new commit. move the testing ref and the HEAD ref with it

add a "test"

    echo "this is a test" &gt; test.rb
    git add test.rb                    # stage it for our commit
    git commit -m "added a test"       # now commit
    git log

@ update diagram - should have two commits

hotfix - scenario: you need to switch back to master

    git checkout master
    ls

@ move HEAD

so notice two things.
1) switching to this branch was fast - everything is local
2) our file test.rb is absent

and if we

    cat README.txt

it says 'version 2' just like we would expect

    echo "applying fix" &gt;&gt; sheep.rb
    cat sheep.rb
    git commit -a -m "applied important fix"
    git log
    git cat-file -p ---- # last commit

@ draw the new commit, and draw its reference back to the parent. move HEAD and master

now fixed, can push into production
and get back to work in `testing`

    git checkout testing
    cat README.txt
    cat test.rb

This is a general pattern:

&gt; Principle #3: Branching is cheap, use it often

If you are working on a particular feature, create a branch. 

If you're coming from svn, making frequent branches might seem unnatural.
in svn, a branch is global -&gt; namespace issues.
vs. git: private branches
name your branch 'test' and it won't collide with anyone elses

But branching itself isn't that useful unless its easy to merge.

* how many of you have merged a branch in svn?
* how many of you enjoyed it?

merging is one of git's strength and git makes it relatively easy

# merging

    cat sheep.rb

two branches: `master` and `testing` - need to merge

    git checkout master
    git merge testing
    git show HEAD

instead of a 'parent' we have a line that says 'merge'
a merge commit has more than one parent

@ draw the commit object
@ draw lines to the commits

    gitx

sometimes merging doesn't go as planned - conflicts

    git checkout -b breaker

this is shorthand for create and then checkout a new branch based on the
current HEAD

    vi sheep.rb # changing fix
    git commit -a -m "changed the fix"
    git checkout master
    vi sheep.rb # improving fix
    git commit -a -m "improved the fix"

@(update diagram, adding breaker and master refs)

    git merge breaker
    git status

there are many diff viewing tools.
* perforce
* opendiff - from apple

    git mergetool -t opendiff

I don't really like using the visual tools.
Sometimes you need character level editing

    vi sheep.rb
    git add sheep.rb
    git commit -a

talk about merge with conflicts

@ update diagram draw new merge commit

    gitx

Questions?

# Remotes

Everything so far on one machine. 

I work offline (I take the train)
If I break something I can rollback see where I was an hour ago 

want to share our changes.
might seem scary or messy because changes to totally independent lines of the code.
but in practice its not a problem.

svn version numbers are incremental - so two repos would get out of
step
no easy way of merging two separate repostories. 

git blob identifiers are a SHA of the content.
if the same content is created anywhere in the universe you'll still
have the same SHA

git doesn't care about where your commits come from or how you get them

Protocols:
  * ssh
  * git
  * http
  * local file system

sample project on our github

    cd ..
    open http://XXX/nmurray/simple-echo
    git clone git@XXX:nmurray/simple-echo.git
    cd simple-echo
    git log

svn checkout just HEAD
vs. git - whole repo

To be able to collaborate with others you have to manage 'remote repositories'.
When you clone a project, you have a default remote called 'origin'. 

    git remote -v

Remotes are pointers to other repositories that are _usually_ over the network.
'pull' and 'push' changes.

    vi README.mkd
    # make a change
    git commit -a -m "make a change"
    git push

If someone else makes a change:

    git pull origin master

This means pull from `origin` the branch `master` into local branch `master`. You can often to just

    git pull

which means pull from origin whatever branch Im on (i.e. HEAD) into this branch.

Now let's say someone pushes a change and I make a change
I can't push unless I pull first. This is good.

# remote forks

So that is while we are on the same line. What if were on different lines?

@(open up webbrowser again)

Bh also has forked my project. But when we say forked, all the means is he has
created his own development line from some of my commits

    git remote add bh git@XXX:bhenderson/simple-echo.git
    git remote -v

Now you shouldn't be surprised to learn that adding the remote doesn't change
anything. First we have to `fetch` hist changes

    git fetch bh

`fetch` brings his commits into my repo but again, doesnt change my working copy.

fetch brought branches + commits into repo
work with those branches just like any other branch.

    git branch -a

So you see here we have 

* `master`, which is our local master
* we have at the bottom `origin/master` which is the origin where we pulled from branch master
* and then we have `bh/master`, which is bhendersons master branch

These are all regular branches: they are just pointers to commits. We
can even checkout as branch 

    git checkout bh/master

scary message

    git checkout master

So how would we merge bhendersons changes with our own? I'm sure you could guess by now. Simply:

    git merge bh/master # don't press enter!!!

But lets take it up a notch.
say you didn't want to merge bh changes in your master branch.
real world, you might not know if his changes would merge cleanly
don't want to mess up your master branch.  

What we are going to do is
* create a new branch,
* merge bhs branch in THAT branch
* then we're going to merge to master.

It will make more sense when we do it. Lets try:

Okay we first want to create a new branch based on our master

    git checkout -b bh-merge
    git branch -a 

Now lets merge his changes

    cat simple-echo.rb
    git merge bh/master
    cat simple-echo.rb
    git log                  # see bh as the author of the commit

okay everything was clean! *phew* now lets go back to master

    git checkout master
    git merge bh-merge
    git log

and there we go! merged nicely.
now I don't need bhendersons merge branch anymore, so lets delete it

    git branch -d bh-merge
    git branch -a

git is distributed

Instead of one central server, that everyone has to sync to,
* independent lines of work can go on.
* If someone creates something good in their branch, they just tell people about it.
* permission-less 

you can see why it is so good for open-source development

questions about branching?

# Advanced

* tagging
* rebase
* cherry pick
* git bisect
* hooks
* tracking branches
* submodules
* interactive staging
* squashing commits
* git-svn
* setting up your own server
* patches via email
* gitjour
&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Share:&lt;/p&gt;
&lt;p&gt;	&lt;a rel="nofollow" target="_blank" href="http://delicious.com/post?url=http%3A%2F%2Fwww.xcombinator.com%2F2010%2F09%2F01%2Fgit-cheat-sheet-and-class-notes%2F&amp;title=git%20cheatsheet%20and%20class%20notes&amp;notes=I%20recently%20gave%20a%20talk%20at%20work%20about%20git.%20I%20created%20a%20cheat%20sheet%20based%20on%20Steve%20Tayon%27s%20Clojure%20Cheatsheet.%20%0D%0A%0D%0A%0D%0AI%20realize%20there%20are%20a%20number%20of%20cheatsheets%20for%20git%20already.%20However%2C%20I%20wanted%20a%20simple%2C%20one-page%20sheet%20specifically%20for%20my%20attendees.%20%0D%0A%0D%0AYou%20can%20download%20it%20here%3A%0D%0A%0D%0A%09git%20cheatsheet%20pdf%0D%0A%09git%20cheatsheet%20LaTeX%20source%0D%0A%0D%0A%0D%0AYou%20can%20find%20the%20raw%20notes%20of%20my%20talk%20after%20the%20jump.%0D%0A%0D%0A%0D%0A%0D%0A%0D%0A%20%0D%0A" title="del.icio.us"&gt;&lt;img src="http://www.xcombinator.com/wp-content/plugins/sociable/images/delicious.png" title="del.icio.us" alt="del.icio.us" class="sociable-hovers" /&gt;&lt;/a&gt;&lt;br /&gt;
	&lt;a rel="nofollow" target="_blank" href="http://reddit.com/submit?url=http%3A%2F%2Fwww.xcombinator.com%2F2010%2F09%2F01%2Fgit-cheat-sheet-and-class-notes%2F&amp;title=git%20cheatsheet%20and%20class%20notes" title="Reddit"&gt;&lt;img src="http://www.xcombinator.com/wp-content/plugins/sociable/images/reddit.png" title="Reddit" alt="Reddit" class="sociable-hovers" /&gt;&lt;/a&gt;&lt;br /&gt;
	&lt;a rel="nofollow" target="_blank" href="http://technorati.com/faves?add=http%3A%2F%2Fwww.xcombinator.com%2F2010%2F09%2F01%2Fgit-cheat-sheet-and-class-notes%2F" title="Technorati"&gt;&lt;img src="http://www.xcombinator.com/wp-content/plugins/sociable/images/technorati.png" title="Technorati" alt="Technorati" class="sociable-hovers" /&gt;&lt;/a&gt;&lt;br /&gt;
	&lt;a rel="nofollow" target="_blank" href="http://twitter.com/home?status=git%20cheatsheet%20and%20class%20notes%20-%20http%3A%2F%2Fwww.xcombinator.com%2F2010%2F09%2F01%2Fgit-cheat-sheet-and-class-notes%2F" title="Twitter"&gt;&lt;img src="http://www.xcombinator.com/wp-content/plugins/sociable/images/twitter.png" title="Twitter" alt="Twitter" class="sociable-hovers" /&gt;&lt;/a&gt;&lt;br /&gt;
	&lt;a rel="nofollow" target="_blank" href="http://www.facebook.com/share.php?u=http%3A%2F%2Fwww.xcombinator.com%2F2010%2F09%2F01%2Fgit-cheat-sheet-and-class-notes%2F&amp;t=git%20cheatsheet%20and%20class%20notes" title="Facebook"&gt;&lt;img src="http://www.xcombinator.com/wp-content/plugins/sociable/images/facebook.png" title="Facebook" alt="Facebook" class="sociable-hovers" /&gt;&lt;/a&gt;&lt;br /&gt;
	&lt;a rel="nofollow" target="_blank" href="http://www.google.com/bookmarks/mark?op=edit&amp;bkmk=http%3A%2F%2Fwww.xcombinator.com%2F2010%2F09%2F01%2Fgit-cheat-sheet-and-class-notes%2F&amp;title=git%20cheatsheet%20and%20class%20notes&amp;annotation=I%20recently%20gave%20a%20talk%20at%20work%20about%20git.%20I%20created%20a%20cheat%20sheet%20based%20on%20Steve%20Tayon%27s%20Clojure%20Cheatsheet.%20%0D%0A%0D%0A%0D%0AI%20realize%20there%20are%20a%20number%20of%20cheatsheets%20for%20git%20already.%20However%2C%20I%20wanted%20a%20simple%2C%20one-page%20sheet%20specifically%20for%20my%20attendees.%20%0D%0A%0D%0AYou%20can%20download%20it%20here%3A%0D%0A%0D%0A%09git%20cheatsheet%20pdf%0D%0A%09git%20cheatsheet%20LaTeX%20source%0D%0A%0D%0A%0D%0AYou%20can%20find%20the%20raw%20notes%20of%20my%20talk%20after%20the%20jump.%0D%0A%0D%0A%0D%0A%0D%0A%0D%0A%20%0D%0A" title="Google Bookmarks"&gt;&lt;img src="http://www.xcombinator.com/wp-content/plugins/sociable/images/googlebookmark.png" title="Google Bookmarks" alt="Google Bookmarks" class="sociable-hovers" /&gt;&lt;/a&gt;&lt;br /&gt;
	&lt;a rel="nofollow" target="_blank" href="http://news.ycombinator.com/submitlink?u=http%3A%2F%2Fwww.xcombinator.com%2F2010%2F09%2F01%2Fgit-cheat-sheet-and-class-notes%2F&amp;t=git%20cheatsheet%20and%20class%20notes" title="HackerNews"&gt;&lt;img src="http://www.xcombinator.com/wp-content/plugins/sociable/images/hackernews.png" title="HackerNews" alt="HackerNews" class="sociable-hovers" /&gt;&lt;/a&gt;&lt;br /&gt;
	&lt;a rel="nofollow" target="_blank" href="http://www.printfriendly.com/print?url=http%3A%2F%2Fwww.xcombinator.com%2F2010%2F09%2F01%2Fgit-cheat-sheet-and-class-notes%2F&amp;partner=sociable" title="PDF"&gt;&lt;img src="http://www.xcombinator.com/wp-content/plugins/sociable/images/pdf.png" title="PDF" alt="PDF" class="sociable-hovers" /&gt;&lt;/a&gt;&lt;br /&gt;
	&lt;a rel="nofollow" target="_blank" href="http://www.xcombinator.com/feed/" title="RSS"&gt;&lt;img src="http://www.xcombinator.com/wp-content/plugins/sociable/images/rss.png" title="RSS" alt="RSS" class="sociable-hovers" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/clojure?a=rYKdIGfUNpg:IAsSXrU1Zq4:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/clojure?a=rYKdIGfUNpg:IAsSXrU1Zq4:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/clojure/~4/rYKdIGfUNpg" height="1" width="1"/&gt;</content>
		<author>
			<name>X-combinator</name>
			<uri>http://pipes.yahoo.com/pipes/pipe.info?_id=796ee0b7c5d764dcf498b0419d0c2feb</uri>
		</author>
		<source>
			<title type="html">X-Combinator</title>
			<subtitle type="html">Pipes Output</subtitle>
			<link rel="self" href="http://pipes.yahoo.com/pipes/pipe.run?_id=796ee0b7c5d764dcf498b0419d0c2feb&amp;_render=rss" />
			<id>http://pipes.yahoo.com/pipes/pipe.run?_id=796ee0b7c5d764dcf498b0419d0c2feb&amp;_render=rss</id>
			<updated>2010-09-03T21:01:09+00:00</updated>
		</source>
	<feedburner:origLink>http://www.xcombinator.com/2010/09/01/git-cheat-sheet-and-class-notes/</feedburner:origLink></entry>

	<entry>
		<title type="html">Consistent APIs for collections</title>
		<link href="http://feedproxy.google.com/~r/clojure/~3/IrgsHel-W4c/consistent-apis-for-collections.html" />
		<id>tag:blogger.com,1999:blog-7100397.post-2700169983098955943</id>
		<updated>2010-09-01T13:56:00+00:00</updated>
		<content type="html">I have been using Clojure a lot for work this year and the consistent API for anything that is a &lt;b&gt;seq&lt;/b&gt; (lists, vectors, maps, trees, etc.) is probably my favorite language feature. Scala 2.8 &lt;a rel="nofollow" target="_blank" href="http://lampwww.epfl.ch/~odersky/whatsnew/collections-api/collections.html"&gt;collections&lt;/a&gt; offer the same uniform API. For me Clojure and Scala, with a fairly small number of operations to remember across most collections therefore represent a new paradigm for programming compared to some older languages Like Java, Scheme, and Common Lisp that force you to remember too many different operation names. The Ruby Enumerable Module is also provides a nice consistent API over collections. Most Ruby collection classes mixin Enumerable, but the API consistency is not as good as Scala and Clojure. That said, even though Enumerable only requires a small number of methods to be implemented like &lt;b&gt;each&lt;/b&gt;, &lt;b&gt;map&lt;/b&gt;, &lt;b&gt;find&lt;/b&gt;, etc., the ability to combine these methods with blocks is very flexible.&lt;div class="blogger-post-footer"&gt;&lt;img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/7100397-2700169983098955943?l=blog.markwatson.com" alt="" /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/clojure?a=IrgsHel-W4c:3Y8gLXa9tqI:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/clojure?a=IrgsHel-W4c:3Y8gLXa9tqI:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/clojure/~4/IrgsHel-W4c" height="1" width="1"/&gt;</content>
		<author>
			<name>Mark Watson</name>
			<uri>http://pipes.yahoo.com/pipes/pipe.info?_id=a0161f6185ca965613735b6b06f2e3ef</uri>
		</author>
		<source>
			<title type="html">Mark Watson</title>
			<subtitle type="html">Pipes Output</subtitle>
			<link rel="self" href="http://pipes.yahoo.com/pipes/pipe.run?_id=a0161f6185ca965613735b6b06f2e3ef&amp;_render=rss" />
			<id>http://pipes.yahoo.com/pipes/pipe.run?_id=a0161f6185ca965613735b6b06f2e3ef&amp;_render=rss</id>
			<updated>2010-09-03T21:01:28+00:00</updated>
		</source>
	<feedburner:origLink>http://blog.markwatson.com/2010/09/consistent-apis-for-collections.html</feedburner:origLink></entry>

	<entry xml:lang="en">
		<title type="html">“Editing” trees in Clojure with clojure.zip</title>
		<link href="http://feedproxy.google.com/~r/clojure/~3/tCnk09UQF4I/" />
		<id>http://www.exampler.com/blog/2010/09/01/editing-trees-in-clojure-with-clojurezip/</id>
		<updated>2010-09-01T10:46:03+00:00</updated>
		<content type="html">&lt;p&gt;Clojure.zip is a library that lets you move around freely within trees and also create changed copies of them. This is a tutorial I wish I&amp;#8217;d had when I started using it.&lt;/p&gt;
&lt;p&gt;In this tutorial, I&amp;#8217;ll use sequences as trees. You can create your own kind of trees if you want, but I won&amp;#8217;t cover that. &lt;/p&gt;
&lt;p&gt;Here&amp;#8217;s what we&amp;#8217;ll be working with:&lt;/p&gt;
&lt;pre&gt;
user=&gt; (def original [1 '(a b c) 2])
#'user/original
&lt;/pre&gt;
&lt;p&gt;It&amp;#8217;s a tree whose root is a vector with three children: 1, the subtree &lt;code&gt;(a,b,c)&lt;/code&gt; and 2. We need to convert it into some sort of data structure that allows free movement. That&amp;#8217;s done like this:&lt;/p&gt;
&lt;pre&gt;
user=&gt; (require '[clojure.zip :as zip])
nil
user=&gt; (def root-loc (zip/seq-zip (seq original)))
#'user/root-loc
&lt;/pre&gt;
&lt;p&gt;Notice that I used the alias &lt;code&gt;zip&lt;/code&gt;. If you &lt;code&gt;refer&lt;/code&gt; or &lt;code&gt;use&lt;/code&gt; clojure.zip, you&amp;#8217;ll find yourself overwriting useful functions like &lt;code&gt;clojure.core/next&lt;/code&gt;. &lt;/p&gt;
&lt;p&gt;Notice also that I explicitly wrapped the tree in a seq. If you use seq-zip on an unwrapped vector, you&amp;#8217;ll get confusing results.&lt;/p&gt;
&lt;p&gt;At this point, I&amp;#8217;d describe &lt;code&gt;root-loc&lt;/code&gt; as &amp;#8220;the location (or &lt;em&gt;loc&lt;/em&gt;) of the root of the &lt;em&gt;tomorrow tree&lt;/em&gt;.&amp;#8221; I say &amp;#8220;tomorrow tree&amp;#8221; because it&amp;#8217;s not a tree itself, but something that can later be converted into a tree. In reality, &lt;code&gt;root-loc&lt;/code&gt; names both the loc and the tomorrow tree, bundled up together, but I think it most straightforward to leave the tomorrow tree implicit.&lt;/p&gt;
&lt;p&gt;(The actual data structure is called a &amp;#8220;zipper&amp;#8221;, which is a decent analogy for the actual implementation but didn&amp;#8217;t help me understand how to use the library.)&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Moving around inside a tomorrow tree&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;With the loc, we can move around:&lt;/p&gt;
&lt;pre&gt;
user=&gt; original
[1 (a b c) 2]
user=&gt; (zip/node (zip/down root-loc))
1
&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;zip/down&lt;/code&gt; moves to the leftmost child of the current loc and returns that child&amp;#8217;s loc. &lt;code&gt;zip/node&lt;/code&gt; gives you the subtree of the original tree corresponding to its loc argument. It&amp;#8217;s one of the main ways you get parts of a tree&amp;#8212;regular lists, vectors, and the like&amp;#8212;&amp;#8221;out of&amp;#8221; a tomorrow tree.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;-&amp;gt;&lt;/code&gt; macro makes movement in the tomorrow tree much easier to understand:&lt;/p&gt;
&lt;pre&gt;
user=&gt; (-&gt; root-loc zip/down zip/right zip/node)
(a b c)
user=&gt; (-&gt; root-loc zip/down zip/right zip/down zip/right zip/node)
b
&lt;/pre&gt;
&lt;p&gt;Nevertheless, I always wrap anything but the simplest traversals in their own functions. &lt;/p&gt;
&lt;p&gt;Here are some other movement functions for you to try: &lt;code&gt;up&lt;/code&gt;, &lt;code&gt;left&lt;/code&gt;, &lt;code&gt;rightmost&lt;/code&gt;, and &lt;code&gt;leftmost&lt;/code&gt;. Beware of (arguable) inconsistencies in the handling of edge cases. For example, &lt;code&gt;right&lt;/code&gt; and &lt;code&gt;rightmost&lt;/code&gt; behave differently when moving &amp;#8220;off the end&amp;#8221; of a list of siblings:&lt;/p&gt;
&lt;pre&gt;
user=&gt; original
[1 (a b c) 2]
user=&gt; (def last-one (-&gt; root-loc zip/down zip/right zip/right))
#'user/last-one
user=&gt; (zip/node last-one)
2
user=&gt; (-&gt; last-one zip/&lt;b&gt;right&lt;/b&gt;)
nil         ; off into nothingness
user=&gt; (-&gt; last-one zip/&lt;b&gt;rightmost&lt;/b&gt; zip/node)
2           ; stays put
&lt;/pre&gt;
&lt;p&gt;&lt;b&gt;Parts of a tree&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;In addition to &lt;code&gt;zip/node&lt;/code&gt;, there are other functions for recovering parts of the original tree. All work relative to the current loc.&lt;/p&gt;
&lt;pre&gt;
user=&gt; (def b (-&gt; root-loc zip/down zip/right zip/down zip/right))
#'user/b
user=&gt; (zip/node b)
b
user=&gt; (zip/&lt;b&gt;lefts&lt;/b&gt; b)
(a)
user=&gt; (zip/&lt;b&gt;rights&lt;/b&gt; b)
(c)
&lt;/pre&gt;
&lt;p&gt;An interesting one shows all subtrees from the root of the tree down to just above the current loc:&lt;/p&gt;
&lt;pre&gt;
user=&gt; (zip/path b)
[  (1 (a b c) 2)
      (a b c)     ]
&lt;/pre&gt;
&lt;p&gt;&lt;b&gt;Changing the tree&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;A number of functions take a current loc (and associated tomorrow tree) and produce a new loc inside a different tomorrow tree. For example, let&amp;#8217;s delete the &amp;#8216;(a b c) subtree:&lt;/p&gt;
&lt;pre&gt;
user=&gt; (def loc-in-new-tree (zip/remove (zip/up b)))
#'user/loc-in-new-tree
&lt;/pre&gt;
&lt;p&gt;How does the tree represented by this new tomorrow tree differ from the &lt;code&gt;original&lt;/code&gt; tree? We can see that with the &lt;code&gt;root&lt;/code&gt; function, which applies &lt;code&gt;zip/node&lt;/code&gt; to the root of the tomorrow tree:&lt;/p&gt;
&lt;pre&gt;
user=&gt; (zip/root loc-in-new-tree)
(1 2)
user=&gt; original
[1 (a b c) 2]
&lt;/pre&gt;
&lt;p&gt;Where, exactly, is the new location? &lt;/p&gt;
&lt;pre&gt;
user=&gt; (zip/node loc-in-new-tree)
1
&lt;/pre&gt;
&lt;p&gt;The new loc has &amp;#8220;backed up&amp;#8221; from its previous version. (That&amp;#8217;s not an exact enough description, but it&amp;#8217;ll do for a few more paragraphs.) The other editing functions return an &amp;#8220;unchanged&amp;#8221; loc (except in the sense that it&amp;#8217;s pointing into a new tomorrow tree with a changed structure): &lt;code&gt;insert-left&lt;/code&gt;, &lt;code&gt;insert-right&lt;/code&gt;, &lt;code&gt;replace&lt;/code&gt;, &lt;code&gt;edit&lt;/code&gt;, &lt;code&gt;insert-child&lt;/code&gt;, and &lt;code&gt;append-child&lt;/code&gt;. Try them out.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;In which I reveal I&amp;#8217;m slow&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;At first, I easily forgot that these functions create a new tomorrow tree and don&amp;#8217;t really &amp;#8220;replace&amp;#8221; or &amp;#8220;insert&amp;#8221; or &amp;#8220;edit&amp;#8221; parts of the old one. That is:&lt;/p&gt;
&lt;pre&gt;
user=&gt; (zip/root loc-in-new-tree)
(1 2)                ; I see that I've edited the tree.
user=&gt; (zip/root b)
(1 (a b c) 2)        ; Wait - I thought I changed the tree?!
&lt;/pre&gt;
&lt;p&gt;&amp;#8220;Well, duh&amp;#8221;, you might say, &amp;#8220;it&amp;#8217;s a functional language with immutable state, so &lt;em&gt;of course&lt;/em&gt; it doesn&amp;#8217;t change the old tree.&amp;#8221; You&amp;#8217;re absolutely right, but it was surprisingly easy for old habits to sneak up on me. So, two rules:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;
If you ever fail to use the return value of one of these functions, &lt;em&gt;you&amp;#8217;re doing it wrong&lt;/em&gt;.
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
If you ever write code like this:
&lt;/p&gt;
&lt;pre&gt;
(let [stashed-location (zip/whatever ...)]
   ... make "changes" ...
   ... use stashed location ...)
&lt;/pre&gt;
&lt;p&gt;you &lt;em&gt;might&lt;/em&gt; be doing it wrong. Make sure that you&amp;#8217;re not unthinkingly assuming that later changes to &amp;#8220;the&amp;#8221; tree are reflected in your &lt;code&gt;stashed-location&lt;/code&gt;.
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;b&gt;Whole-tree editing&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;Here&amp;#8217;s an example of printing out a whole tree, one node at a time:&lt;/p&gt;
&lt;pre&gt;
(defn print-tree [original]
  (loop [loc (zip/seq-zip (seq original))]
    (if (&lt;b&gt;zip/end?&lt;/b&gt; loc)
      (zip/root loc)
      (recur (&lt;b&gt;zip/next&lt;/b&gt;
                (do (println (zip/node loc))
                    loc))))))
&lt;/pre&gt;
&lt;p&gt;This is an ordinary recursive loop. It visits each location in the tomorrow tree, stopping when &lt;code&gt;zip/end?&lt;/code&gt; is true. &lt;code&gt;zip/next&lt;/code&gt; returns a new current loc that is the next one in the tomorrow tree, where &amp;#8220;next&amp;#8221; means &amp;#8220;in &lt;a href="http://en.wikipedia.org/wiki/Tree_traversal#Depth-first_Traversal"&gt;preorder depth-first&lt;/a&gt; order&amp;#8221;. To see that, here&amp;#8217;s what one run of the function prints:&lt;/p&gt;
&lt;pre&gt;
user=&gt; (print-tree [1 '(a (i ii iii) c) 2])
(1 (a (i ii iii) c) 2)
1
(a (i ii iii) c)
a
(i ii iii)
i
ii
iii
c
2
&lt;/pre&gt;
&lt;p&gt;
To make changes to the tree, add a &lt;code&gt;cond&lt;/code&gt;. The default case should hand the current loc to &lt;code&gt;zip/next&lt;/code&gt;. The other cases should yield a loc pointing into a changed copy of the tomorrow tree:
&lt;/p&gt;
&lt;pre&gt;
  (loop [loc (zip/seq-zip original-tree)]
    (if (zip/end?&gt; loc)
      (zip/root loc)
      (recur (zip/next
          &lt;b&gt;(cond (subtree-to-change? loc)
                (modify-subtree loc)
                &amp;#8230;
                :else loc&lt;/b&gt;)))))
&lt;/pre&gt;
&lt;p&gt;The tricky bit is making sure that &lt;code&gt;modify-subtree&lt;/code&gt; returns a loc &lt;em&gt;just before&lt;/em&gt; the next loc of interest (in a depth-first traversal). (It has to be before so that &lt;code&gt;zip/next&lt;/code&gt; takes you to the interesting loc.) To get to that loc, you can use any of the movement functions (&lt;code&gt;zip/next&lt;/code&gt;, &lt;code&gt;zip/up&lt;/code&gt;, &lt;code&gt;zip/rightmost&lt;/code&gt;, and so on). There&amp;#8217;s also a &lt;code&gt;zip/prev&lt;/code&gt; that returns the loc just before the current one. &lt;/p&gt;
&lt;p&gt;To keep from confusing myself, I write little helper functions, each named by what it does &lt;em&gt;and&lt;/em&gt; what loc it returns. So, for example, I have one function that glories in this name:&lt;/p&gt;
&lt;pre&gt;
(defn &lt;b&gt;wrap-with-expect__at-rightmost-wrapped-location&lt;/b&gt; [loc]
  (assert (start-of-arrow-sequence? loc))
  (let [right-hand (-&gt; loc zip/right zip/right)
        edited-loc (&lt;b&gt;zip/edit&lt;/b&gt; loc
                   (fn [loc] `(expect ~loc =&gt; ~(zip/node right-hand))))]
    (-&gt; edited-loc zip/right zip/right zip/remove zip/remove)))
&lt;/pre&gt;
&lt;p&gt;It takes a form like &lt;code&gt;... (f 1) =&amp;gt; (+ 2 3) :next&lt;/code&gt;, with the current loc being &lt;code&gt;(f 1)&lt;/code&gt;,  and turns it into this:&lt;/p&gt;
&lt;pre&gt;
... (expect (f 1) =&amp;gt; (+ 2 3)) :next
&lt;/pre&gt;
&lt;p&gt;&amp;#8230; with the current loc being at the 3 so that the &lt;code&gt;zip/next&lt;/code&gt; returns a loc at &lt;code&gt;:next&lt;/code&gt;. This positioning works because I use &lt;code&gt;zip/remove&lt;/code&gt;, which returns a loc that&amp;#8217;s &amp;#8220;backed up&amp;#8221; to the previous loc in a depth-first traversal. (That&amp;#8217;s the fix to my earlier imprecision about what &lt;code&gt;zip/remove&lt;/code&gt; returns. It&amp;#8217;s not the previous loc &lt;em&gt;at the same level&lt;/em&gt;, which&amp;#8212;for the sake of a simpler explanation&amp;#8212;I earlier allowed you to assume.)&lt;/p&gt;
&lt;p&gt;By building and testing these little functions first, my main cond-loop is easier to get right. You can see some more examples in my test package, &lt;a href="http://github.com/marick/Midje"&gt;Midje&lt;/a&gt;. You can look at both &lt;a href="http://github.com/marick/Midje/blob/master/test/midje/fact_body_transformation_test.clj"&gt;the tests&lt;/a&gt; and &lt;a href="http://github.com/marick/Midje/blob/master/src/midje/fact_body_transformation.clj"&gt;the code&lt;/a&gt;.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/clojure?a=tCnk09UQF4I:0mS3caagaa0:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/clojure?a=tCnk09UQF4I:0mS3caagaa0:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/clojure/~4/tCnk09UQF4I" height="1" width="1"/&gt;</content>
		<author>
			<name>Exploration Through Example</name>
			<uri>http://www.exampler.com/blog</uri>
		</author>
		<source>
			<title type="html">Exploration Through Example</title>
			<subtitle type="html">Example-driven development, Agile software development, testing, Ruby, and other things of interest to Brian Marick</subtitle>
			<link rel="self" href="http://www.exampler.com/blog/category/clojure/feed/" />
			<id>http://www.exampler.com/blog/category/clojure/feed/</id>
			<updated>2010-09-01T15:01:14+00:00</updated>
		</source>
	<feedburner:origLink>http://www.exampler.com/blog/2010/09/01/editing-trees-in-clojure-with-clojurezip/</feedburner:origLink></entry>

	<entry>
		<title type="html">Clojure: Using Sets and Maps as Functions</title>
		<link href="http://feedproxy.google.com/~r/clojure/~3/pDnVYk7HYFY/clojure-using-sets-and-maps-as.html" />
		<id>tag:blogger.com,1999:blog-12467669.post-7460886934653799963</id>
		<updated>2010-09-01T09:07:15+00:00</updated>
		<content type="html">Clojure sets and maps are functions.&lt;br /&gt;&lt;br /&gt;Since they are functions, you don't need functions to get values out of them. You can use the map or set as the example below shows.&lt;pre&gt;(#{1 2} 1)&lt;br /&gt;&amp;gt; 1&lt;br /&gt;&lt;br /&gt;({:a 2 :b 3} :a)&lt;br /&gt;&amp;gt; 2&lt;br /&gt;&lt;/pre&gt;That's nice, but it's not exactly game changing. However, when you use sets or maps with high order functions you can get a lot of power with a little code.&lt;br /&gt;&lt;br /&gt;For example, the following code removes all of the elements of a vector if the element is also in the set.&lt;pre&gt;(def banned #{"Steve" "Michael"})&lt;br /&gt;(def guest-list ["Brian" "Josh" "Steve"])&lt;br /&gt;&lt;br /&gt;(remove banned guest-list)&lt;br /&gt;&amp;gt; ("Brian" "Josh")&lt;/pre&gt;I'm a big fan of using sets in the way described above, but I don't often find myself using maps in the same way. The following code works, but I rarely use maps as predicates.&lt;pre&gt;(def banned {"Steve" [] "Michael" []})&lt;br /&gt;(def guest-list ["Brian" "Josh" "Steve"])&lt;br /&gt;&lt;br /&gt;(remove banned guest-list)&lt;br /&gt;&amp;gt; ("Brian" "Josh")&lt;/pre&gt;However, yesterday I needed to compare two maps and get the list of ids in the second map where the quantities didn't match the quantities in the first map. I started by using filter and defining a function that checks if the quantities are not equal. The following code shows solving the problem with that approach.&lt;pre&gt;; key/value pairs representing order-id and order-quantity&lt;br /&gt;(def map1 {1 44 2 33})&lt;br /&gt;(def map2 {1 55 2 33})&lt;br /&gt;&lt;br /&gt;(defn not=quantities [[id qty]] (not= (map1 id) qty))&lt;br /&gt;(keys (filter not=quantities map2))&lt;br /&gt;&amp;gt; (1)&lt;br /&gt;&lt;/pre&gt;However, since you can use maps as filter functions you can also solve the problem by merging the maps with &lt;code&gt;not=&lt;/code&gt; and filtering by the result. The following code shows an example of merging and using the result as the predicate.&lt;pre&gt;; key/value pairs representing order-id and order-quantity&lt;br /&gt;(def map1 {1 44 2 33})&lt;br /&gt;(def map2 {1 55 2 33})&lt;br /&gt;&lt;br /&gt;(filter (merge-with not= map1 map2) (keys map2))&lt;br /&gt;&amp;gt; (1)&lt;/pre&gt;I don't often find myself using maps as predicates, but in certain cases it's exactly what I need.&lt;div class="blogger-post-footer"&gt;&lt;br /&gt;&lt;a href="http://www.jayfields.com"&gt;&amp;copy; Jay Fields - www.jayfields.com&lt;/a&gt;&lt;img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/12467669-7460886934653799963?l=blog.jayfields.com" alt="" /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/clojure?a=pDnVYk7HYFY:LemDoFlqNG4:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/clojure?a=pDnVYk7HYFY:LemDoFlqNG4:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/clojure/~4/pDnVYk7HYFY" height="1" width="1"/&gt;</content>
		<author>
			<name>Jay Fields</name>
			<email>blogger@jayfields.com</email>
			<uri>http://blog.jayfields.com/search/label/clojure</uri>
		</author>
		<source>
			<title type="html">Jay Fields' Thoughts</title>
			<subtitle type="html">experiences in software development</subtitle>
			<link rel="self" href="http://blog.jayfields.com/feeds/posts/default/-/clojure" />
			<id>tag:blogger.com,1999:blog-12467669</id>
			<updated>2010-09-03T18:01:24+00:00</updated>
		</source>
	<feedburner:origLink>http://blog.jayfields.com/2010/08/clojure-using-sets-and-maps-as.html</feedburner:origLink></entry>

	<entry xml:lang="en">
		<title type="html">Today in the Intertweets (Aug 31st Ed)</title>
		<link href="http://feedproxy.google.com/~r/clojure/~3/sgdH7_G5zgk/" />
		<id>http://disclojure.org/?p=1134</id>
		<updated>2010-09-01T07:51:28+00:00</updated>
		<content type="html">&lt;ul&gt;
&lt;li&gt;Protocols are faster than Clojure multimethods. Can be as fast as direct func calls in fact and inlined by hotspot (via @&lt;a href="http://twitter.com/chouser" rel="nofollow" target="_blank" title="View chouser's Twitter Profile"&gt;chouser&lt;/a&gt;) &amp;#8212; This is an important fact.&lt;/li&gt;
&lt;li&gt;Clojure or: How I Learned to Stop Worrying and Love the Parentheses (&lt;a href="http://nathanmarz.com/blog/clojure-or-how-i-learned-to-stop-worrying-and-love-the-paren.html"&gt;here&lt;/a&gt;, via @&lt;a href="http://twitter.com/nathanmarz" rel="nofollow" target="_blank" title="View nathanmarz's Twitter Profile"&gt;nathanmarz&lt;/a&gt;) &amp;#8212; This is an article that explains one of the main differences between Lisps and other mainstream languages: the ability to extend the the language &amp;#8211;even create your own mini-languages&amp;#8211; to fit your purposes from within the host language itself and without adding any accidental complexity to the system.. Most other languages add accidental complexity when trying to do so.&lt;/li&gt;
&lt;li&gt;Sweet, a Clojure Ring adapter for Mongrel2 by mikejs (&lt;a href="http://github.com/mikejs/ring/tree/master/ring-mongrel2-adapter/ "&gt;here&lt;/a&gt;, via @&lt;a href="http://twitter.com/zedshaw" rel="nofollow" target="_blank" title="View zedshaw's Twitter Profile"&gt;zedshaw&lt;/a&gt;) &amp;#8212; This allows you to run Ring/Compojure applications inside &lt;a href="http://mongrel2.org/home"&gt;Mongrel2&lt;/a&gt;, a cool new language agnostic web server.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/disclojure?a=Fcc_Z8Xu0N8:MWPe8PsrO6M:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/disclojure?d=yIl2AUoC8zA" border="0" /&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/disclojure?a=Fcc_Z8Xu0N8:MWPe8PsrO6M:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/disclojure?i=Fcc_Z8Xu0N8:MWPe8PsrO6M:D7DqB2pKExk" border="0" /&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/disclojure?a=Fcc_Z8Xu0N8:MWPe8PsrO6M:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/disclojure?i=Fcc_Z8Xu0N8:MWPe8PsrO6M:V_sGLiPBpWU" border="0" /&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/disclojure?a=Fcc_Z8Xu0N8:MWPe8PsrO6M:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/disclojure?i=Fcc_Z8Xu0N8:MWPe8PsrO6M:gIN9vFwOqvQ" border="0" /&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/disclojure/~4/Fcc_Z8Xu0N8" height="1" width="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/clojure?a=sgdH7_G5zgk:MWPe8PsrO6M:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/clojure?a=sgdH7_G5zgk:MWPe8PsrO6M:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/clojure/~4/sgdH7_G5zgk" height="1" width="1"/&gt;</content>
		<author>
			<name>Toni Batchelli</name>
			<uri>http://disclojure.org</uri>
		</author>
		<source>
			<title type="html">disclojure: all things clojure</title>
			<subtitle type="html">public disclosure of all things Clojure</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/disclojure" />
			<id>http://feeds.feedburner.com/disclojure</id>
			<updated>2010-09-03T08:30:53+00:00</updated>
		</source>
	<feedburner:origLink>http://feedproxy.google.com/~r/disclojure/~3/Fcc_Z8Xu0N8/</feedburner:origLink></entry>

	<entry>
		<title type="html">Clojure or: How I Learned to Stop Worrying and Love the Parentheses</title>
		<link href="http://feedproxy.google.com/~r/clojure/~3/8MVHx_7pPI8/clojure-or-how-i-learned-to-stop-worrying-and-love-the-paren.html" />
		<id>621062:7220166:8687857</id>
		<updated>2010-08-31T16:52:44+00:00</updated>
		<content type="html">&lt;p&gt;I'm a longtime Java, Ruby, and Python programmer. Yet Clojure is the first language I've used that I truly enjoy using on a daily basis.&lt;/p&gt; &lt;p&gt;Clojure is a special language. There have been many attempts to articulate the benefits of Lisp-based languages before, but most of these attempts seem to end in futility. Until you use the language, it's hard to understand why functional programming, macros, and immutability are such a big deal.&lt;/p&gt; &lt;p&gt;So I'm going to take a different approach in explaining the virtues of Clojure. I'm going to start off somewhat unusually by talking about &lt;span class="caps"&gt;SQL, &lt;/span&gt;show how querying is done fundamentally differently in Clojure, and transition from there into a broader discussion about domain specific languages, accidental complexity, and how Clojure solves problems that have plagued programmers throughout programming's history.&lt;/p&gt; &lt;h3&gt;The problem with &lt;span class="caps"&gt;SQL&lt;/span&gt;&lt;/h3&gt; &lt;p&gt;&lt;span class="caps"&gt;SQL &lt;/span&gt;is a language for querying relational databases. &lt;span class="caps"&gt;SQL &lt;/span&gt;is one of the most successful technologies ever, but very few technologies can claim to have led to as much unnecessary complexity as &lt;span class="caps"&gt;SQL.&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span class="caps"&gt;SQL &lt;/span&gt;solves the problem of querying a relational database in a concise, expressive manner. In that regard, &lt;span class="caps"&gt;SQL &lt;/span&gt;does a very good job.&lt;/p&gt; &lt;p&gt;The problem with &lt;span class="caps"&gt;SQL &lt;/span&gt;is that it's a custom language. Using &lt;span class="caps"&gt;SQL &lt;/span&gt;from other languages causes a host of other problems - problems that are orthogonal to querying a database. These problems are examples of accidental complexity, complexity in an application caused by the tool used to solve a problem rather than the problem itself.&lt;/p&gt; &lt;p&gt;The prime example of accidental complexity caused by the nature of &lt;span class="caps"&gt;SQL &lt;/span&gt;being a custom language are &lt;span class="caps"&gt;SQL &lt;/span&gt;injection attacks.&lt;/p&gt; &lt;h3&gt;&lt;span class="caps"&gt;SQL &lt;/span&gt;injection has nothing to do with querying databases&lt;/h3&gt; &lt;p&gt;&lt;span class="caps"&gt;SQL &lt;/span&gt;injection results from using one language from within another by doing string manipulation. This has nothing to do with querying databases, it's an integration problem. As we'll see later, it's a problem we can avoid in Clojure.&lt;/p&gt; &lt;p&gt;I know what you're thinking. "There are X, Y, and Z libraries for parameterizing &lt;span class="caps"&gt;SQL &lt;/span&gt;queries and avoiding &lt;span class="caps"&gt;SQL &lt;/span&gt;injection attacks!" This begs the question: then why are &lt;span class="caps"&gt;SQL &lt;/span&gt;injection attacks so pervasive?&lt;/p&gt; &lt;p&gt;The obvious answer is that string manipulation is the most straightforward way to use one language within another. There's something wrong with your tools when the obvious, straightforward way to do something causes major security problems.&lt;/p&gt; &lt;p&gt;There are other problems that arise from using one language within another. The embedded language is second class. The usual techniques programmers use to reduce program complexity, modularization and composition, can't be fully applied to the embedded language.&lt;/p&gt; &lt;p&gt;Similar problems arise when generating &lt;span class="caps"&gt;HTML &lt;/span&gt;- cross site scripting attacks are very pervasive. This is due to the same problems that occur when trying to use one language from within another.&lt;/p&gt; &lt;h3&gt;Clojure lets you create integrated languages&lt;/h3&gt; &lt;p&gt;There are some serious issues that arise when using distinct languages together. Yet the languages are distinct for a reason - they're intended for different problems and operate with completely different mental models.&lt;/p&gt; &lt;p&gt;What if you could fully integrate the query language into your general purpose programming language? What if queries were first class and could be manipulated as such?&lt;/p&gt; &lt;p&gt;Say hello to Clojure (and Lisps in general).&lt;/p&gt; &lt;p&gt;In Clojure, you can extend the language within the language to create domain specific languages. These mini-languages are fully integrated into Clojure and can be manipulated like anything else in Clojure. Most importantly, you get the benefits of a custom language - conciseness and expressiveness - without the accidental complexities.&lt;/p&gt; &lt;p&gt;There's a number of reasons why building mini-languages is possible in Clojure. These include the "code as data" philosophy of the language, macros, closures, and the emphasis on functional programming.&lt;/p&gt; &lt;h3&gt;An example of an integrated query language for Clojure&lt;/h3&gt; &lt;p&gt;I wrote an integrated query language for Clojure called &lt;a rel="nofollow" target="_blank" href="http://github.com/nathanmarz/cascalog"&gt;Cascalog&lt;/a&gt;. Cascalog is a query language for Hadoop clusters, but a very similar library could be built for querying relational databases.&lt;/p&gt; &lt;p&gt;Cascalog forgoes the syntax-heavy design of &lt;span class="caps"&gt;SQL &lt;/span&gt;in favor of the syntax-light design of Datalog. Here are some examples of what Cascalog looks like, compared against the equivalent &lt;span class="caps"&gt;SQL &lt;/span&gt;queries. Remember, Cascalog is a library for Clojure that has the look and feel of an embedded language:&lt;/p&gt;  &lt;p&gt;Teaching Cascalog is not the goal of this article, so don't worry if you don't fully understand the Cascalog queries. I just wanted to show that Cascalog is just as concise and declarative as &lt;span class="caps"&gt;SQL.&lt;/span&gt; To learn more about Cascalog, see the &lt;a rel="nofollow" target="_blank" href="http://nathanmarz.com/blog/introducing-cascalog-a-clojure-based-query-language-for-hado.html"&gt;introductory tutorial&lt;/a&gt;. &lt;/p&gt; &lt;p&gt;The key difference between Cascalog and &lt;span class="caps"&gt;SQL, &lt;/span&gt;of course, is that Cascalog is an embedded language within Clojure. The first class integration between Clojure and Cascalog avoids accidental complexity and lets us use techniques that are otherwise restricted. Queries written with Cascalog, unlike &lt;span class="caps"&gt;SQL, &lt;/span&gt;can be modularized and composed in all sorts of useful and interesting ways.&lt;/p&gt; &lt;p&gt;For example, you can make functions that return subqueries:&lt;/p&gt;  &lt;p&gt;You can parameterize your queries without needing to explicitly say that you're doing so. You just use variables in your query like you were passing them to any other function:&lt;/p&gt;  &lt;p&gt;You can pass a subquery to a function to use in another query:&lt;/p&gt;  &lt;p&gt;You can compose operations together to create new operations. Here's how to define the "average" aggregator in terms of count, sum, and division:&lt;/p&gt;  &lt;p&gt;"average" can then be used like any other operation, as in the following query which determines the average age of people in the dataset:&lt;/p&gt;  &lt;h3&gt;Mold Clojure to your problem&lt;/h3&gt; &lt;p&gt;Linq is an integrated query system for C#. It exists to solve the integration problems I discussed when using a query language from within a general purpose language.&lt;/p&gt; &lt;p&gt;There's one huge difference between Cascalog and Linq: Linq is part of C#. You can't define Linq in terms of regular C#, it needed to be added by the language designers. Cascalog, on the other hand, needs no special support from Clojure. Cascalog is a regular Clojure library.&lt;/p&gt; &lt;p&gt;This means that you can define &lt;span class="caps"&gt;DSL'&lt;/span&gt;s in Clojure yourself but won't get any help from C#. I've created lots of mini-languages, optimized to my problem domains.&lt;/p&gt; &lt;h3&gt;Clojure has a relentless focus on minimizing accidental complexity&lt;/h3&gt; &lt;p&gt;The ability to make embedded languages from within Clojure is just one example of Clojure's relentless focus on minimizing accidental complexity.&lt;/p&gt; &lt;p&gt;Clojure has a very opinionated approach to mutable state, another big source of accidental complexity. Looking back on my Java programming days, I'm amazed at how much of my programming time involved controlling when and how the states of objects were modified.&lt;/p&gt; &lt;p&gt;Clojure prefers immutable data and forces the programmer to be explicit about manipulating state. Clojure makes explicit the difference between a value (an immutable piece of data) and an identity (an entity whose value changes over time).&lt;/p&gt; &lt;p&gt;Concurrency can also be a huge source of accidental complexity. Locks and semaphores are not the right abstraction for a large number of concurrency problems. Clojure has a number of concurrency primitives baked in such as software transactional memory, futures, and promises. These primitives are higher level than locks and more appropriate for many problems (although it's worth saying there are some problems where locks &lt;em&gt;are&lt;/em&gt; appropriate). Clojure's concurrency features are fully integrated with how it handles mutable state.&lt;/p&gt; &lt;p&gt;You should watch &lt;a rel="nofollow" target="_blank" href="http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hickey"&gt;this excellent talk&lt;/a&gt; by Rich Hickey where he talks in depth about Clojure's philosophy on state, value, and identity.&lt;/p&gt; &lt;h3&gt;Conclusion&lt;/h3&gt; &lt;p&gt;A lot of people talk about how wonderfully expressive is Clojure. However, expressiveness is not the goal of Clojure. Clojure aims to minimize accidental complexity, and its expressiveness is a means to that end.&lt;/p&gt; &lt;p&gt;You should follow me on Twitter &lt;a rel="nofollow" target="_blank" href="http://twitter.com/nathanmarz"&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/clojure?a=8MVHx_7pPI8:TZWjAZnc1gw:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/clojure?a=8MVHx_7pPI8:TZWjAZnc1gw:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/clojure/~4/8MVHx_7pPI8" height="1" width="1"/&gt;</content>
		<author>
			<name>Nathan Marz</name>
			<uri>http://pipes.yahoo.com/pipes/pipe.info?_id=180af42010b57c605f7b7475b311ec32</uri>
		</author>
		<source>
			<title type="html">Nathan Marz</title>
			<subtitle type="html">Pipes Output</subtitle>
			<link rel="self" href="http://pipes.yahoo.com/pipes/pipe.run?_id=180af42010b57c605f7b7475b311ec32&amp;_render=rss" />
			<id>http://pipes.yahoo.com/pipes/pipe.run?_id=180af42010b57c605f7b7475b311ec32&amp;_render=rss</id>
			<updated>2010-09-03T21:01:41+00:00</updated>
		</source>
	<feedburner:origLink>http://nathanmarz.com/blog/clojure-or-how-i-learned-to-stop-worrying-and-love-the-paren.html</feedburner:origLink></entry>

	<entry xml:lang="en">
		<title type="html">Today in the Intertweets (Aug 30th Ed)</title>
		<link href="http://feedproxy.google.com/~r/clojure/~3/mWRcRndPd6U/" />
		<id>http://disclojure.org/?p=1131</id>
		<updated>2010-08-31T05:33:28+00:00</updated>
		<content type="html">&lt;ul&gt;
&lt;li&gt;In which the lessons of ZZ Top are applied to the marketplace (&lt;a href="http://technomancy.us/140"&gt;here&lt;/a&gt;, via @&lt;a href="http://twitter.com/planetclojure" rel="nofollow" target="_blank" title="View planetclojure's Twitter Profile"&gt;planetclojure&lt;/a&gt;) &amp;#8212; Tangentially related to Clojure, except that the author of the article built Leningen for us, and along the way he did something bad&amp;#8230; and nationwide. A good read about why a hacker sometimes needs to assert her/his opinion in the code.&lt;/li&gt;
&lt;li&gt;Clojure and SQL (&lt;a href="http://corfield.org/blog/post.cfm/clojure-and-sql"&gt;here&lt;/a&gt;, via @&lt;a href="http://twitter.com/cfbloggers" rel="nofollow" target="_blank" title="View cfbloggers's Twitter Profile"&gt;cfbloggers&lt;/a&gt;) &amp;#8212; Short tutorial on getting some SQL working with Clojure.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/disclojure?a=xTd36fjXTO8:mmY5jRY1KD4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/disclojure?d=yIl2AUoC8zA" border="0" /&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/disclojure?a=xTd36fjXTO8:mmY5jRY1KD4:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/disclojure?i=xTd36fjXTO8:mmY5jRY1KD4:D7DqB2pKExk" border="0" /&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/disclojure?a=xTd36fjXTO8:mmY5jRY1KD4:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/disclojure?i=xTd36fjXTO8:mmY5jRY1KD4:V_sGLiPBpWU" border="0" /&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/disclojure?a=xTd36fjXTO8:mmY5jRY1KD4:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/disclojure?i=xTd36fjXTO8:mmY5jRY1KD4:gIN9vFwOqvQ" border="0" /&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/disclojure/~4/xTd36fjXTO8" height="1" width="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/clojure?a=mWRcRndPd6U:mmY5jRY1KD4:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/clojure?a=mWRcRndPd6U:mmY5jRY1KD4:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/clojure/~4/mWRcRndPd6U" height="1" width="1"/&gt;</content>
		<author>
			<name>Toni Batchelli</name>
			<uri>http://disclojure.org</uri>
		</author>
		<source>
			<title type="html">disclojure: all things clojure</title>
			<subtitle type="html">public disclosure of all things Clojure</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/disclojure" />
			<id>http://feeds.feedburner.com/disclojure</id>
			<updated>2010-09-03T08:30:53+00:00</updated>
		</source>
	<feedburner:origLink>http://feedproxy.google.com/~r/disclojure/~3/xTd36fjXTO8/</feedburner:origLink></entry>

	<entry>
		<title type="html">Clojure: Using Sets and Maps as Functions</title>
		<link href="http://feedproxy.google.com/~r/clojure/~3/4713XfNXwbU/clojure-using-sets-and-maps" />
		<id>http://pipes.yahoo.com/pipes/28231 at http://java.dzone.com</id>
		<updated>2010-08-31T05:20:53+00:00</updated>
		<content type="html">Clojure sets and maps are functions. Since they are functions, you don't need functions to get values out of them. You can use the map or set as the example below shows. James Sugrue&lt;img src="http://feeds.feedburner.com/~r/javalobby/frontpage/~4/lixoKuJt5gA" height="1" width="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/clojure?a=4713XfNXwbU:sEZvZFXBGxA:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/clojure?a=4713XfNXwbU:sEZvZFXBGxA:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/clojure/~4/4713XfNXwbU" height="1" width="1"/&gt;</content>
		<author>
			<name>Javalobby</name>
			<uri>http://pipes.yahoo.com/pipes/pipe.info?_id=f8b56ef73099743fdfe6336dd7cd0d5c</uri>
		</author>
		<source>
			<title type="html">Javalobby</title>
			<subtitle type="html">Pipes Output</subtitle>
			<link rel="self" href="http://pipes.yahoo.com/pipes/pipe.run?_id=f8b56ef73099743fdfe6336dd7cd0d5c&amp;_render=rss" />
			<id>http://pipes.yahoo.com/pipes/pipe.run?_id=f8b56ef73099743fdfe6336dd7cd0d5c&amp;_render=rss</id>
			<updated>2010-09-03T21:00:38+00:00</updated>
		</source>
	<feedburner:origLink>http://feeds.dzone.com/~r/javalobby/frontpage/~3/lixoKuJt5gA/clojure-using-sets-and-maps</feedburner:origLink></entry>

	<entry>
		<title type="html">Clojure and SQL</title>
		<link href="http://feedproxy.google.com/~r/clojure/~3/wnqZP3J8Ee0/clojure-and-sql" />
		<id>http://corfield.org/blog/post.cfm/clojure-and-sql</id>
		<updated>2010-08-31T02:16:20+00:00</updated>
		<content type="html">&lt;p&gt;I spent quite a bit of time playing with Clojure over the weekend (including writing my first plugin and my first hook for Leiningen, Clojure's popular build tool) and I started experimenting with reading data from a database. I tweeted that I was pleased with myself for succeeding and &lt;a href="http://twitter.com/MarcEsher"&gt;Marc Esher&lt;/a&gt; asked "is reading data so hard in clojure that it warrants celebration?" so I figured I'd post my little example, so you could see how easy it is (or isn't, depending on your point of view).&lt;/p&gt;
&lt;pre&gt;
(ns sean.core
  (:use [clojure.contrib.sql :as sql])
  (:gen-class))
&lt;/pre&gt;
&lt;p&gt;This just declares a namespace for my code to live in - the file is sean/core.clj - and says I'm going to be using the library package clojure.contrib.sql under the alias sql. :gen-class says I want the file compiled to a Java class.&lt;/p&gt;
&lt;pre&gt;
(def db {:classname "com.mysql.jdbc.Driver"
         :subprotocol "mysql"
         :subname "//127.0.0.1:3306/mydb"
         :user "dbuser"
         :password "secret"})
&lt;/pre&gt;
&lt;p&gt;This declares the datasource I'm going to use, MySQL, locally, database 'mydb' with the credentials I'm using to login.&lt;/p&gt;
&lt;pre&gt;
(defn print-users
  [] (sql/with-connection db
       (sql/with-query-results res
         ["SELECT * FROM user"]
         (doseq [rec res]
           (println rec)))))
&lt;/pre&gt;
&lt;p&gt;This declares a function print-users taking no arguments [] which reads all users from the 'user' table and prints them out (they are automatically formatted as records with key: value pairs for columns). I'll explain this in more detail below but it really is pretty straightforward.&lt;/p&gt;
&lt;pre&gt;
(defn -main
  [] (print-users))
&lt;/pre&gt;
&lt;p&gt;And that's my 'main' function. Like a regular Java main function. Once this is compiled (I'm using the CounterClockwise Plugin for Eclipse which lets me easily compile Clojure files but you can also use Leiningen - I'll blog examples of both later), I can run it like a regular Java program:&lt;/p&gt;
&lt;pre&gt;
java -cp ./classes/:clojure.jar:clojure-contrib.jar:mysql-connector-java-bin.jar sean.core
&lt;/pre&gt;
&lt;p&gt;So what exactly does it do? The key thing to remember with functional languages is that they often have expressions which are treated as functions that get applied to data in a context. The body of print-users is (sql/with-connection db expression) so it gets a connection for the specified db and then evaluates expression in that context. (sql/with-query-results res [vector] expression) executes the SQL in the vector (subsequent elements of the vector are parameters substituted into the SQL - see below), binds the result to 'res' and then evaluates the expression in that context. (doseq [rec res] expression) takes the sequence 'res' and iterates over each element, binding the element to 'rec' and then evaluating the expression in that context. So, it gets a connection, selects all users and prints each row.&lt;/p&gt;
&lt;p&gt;If you wanted to just get users with a particular status, you'd say something like (sql/with-query-results res [ "SELECT * FROM user WHERE status = ?", search-status ] expression) where search-status was a variable containing the status you were searching on.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/clojure?a=wnqZP3J8Ee0:p3rYBg0r2kA:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/clojure?a=wnqZP3J8Ee0:p3rYBg0r2kA:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/clojure/~4/wnqZP3J8Ee0" height="1" width="1"/&gt;</content>
		<author>
			<name>"An Architect's View"</name>
			<uri>http://corfield.org/blog/</uri>
		</author>
		<source>
			<title type="html">An Architect's View</title>
			<subtitle type="html">Sean Corfield, Software Architect, offers his views on the world of software development.</subtitle>
			<link rel="self" href="http://corfield.org/blog/feeds/rss.cfm/category/clojure" />
			<id>http://corfield.org/blog/feeds/rss.cfm/category/clojure</id>
			<updated>2010-09-03T21:01:17+00:00</updated>
		</source>
	<feedburner:origLink>http://corfield.org/blog/post.cfm/clojure-and-sql</feedburner:origLink></entry>

	<entry xml:lang="en">
		<title type="html">(Community Standards)</title>
		<link href="http://feedproxy.google.com/~r/clojure/~3/6u0M2kJOQwI/" />
		<id>http://blog.fogus.me/?p=2318</id>
		<updated>2010-08-30T22:19:05+00:00</updated>
		<content type="html">As with any Lisp ever created,  Clojure has recently been infected with talk of alternative layout styles of closing (and in some cases, open) parentheses...&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/clojure?a=6u0M2kJOQwI:JBkAI8zPLsU:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/clojure?a=6u0M2kJOQwI:JBkAI8zPLsU:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/clojure/~4/6u0M2kJOQwI" height="1" width="1"/&gt;</content>
		<author>
			<name>fogus</name>
			<uri>http://blog.fogus.me</uri>
		</author>
		<source>
			<title type="html">Send More Paramedics » clojure</title>
			<subtitle type="html">λ λ λ</subtitle>
			<link rel="self" href="http://blog.fogus.me/tag/clojure/feed/atom/" />
			<id>http://blog.fogus.me/feed/atom/</id>
			<updated>2010-09-03T20:30:18+00:00</updated>
		</source>
	<feedburner:origLink>http://blog.fogus.me/2010/08/30/community-standards/</feedburner:origLink></entry>

	<entry xml:lang="en">
		<title type="html">Akamai Technologies, Engineering Manager, Clojure, Cambridge, MA</title>
		<link href="" />
		<id>http://lispjobs.wordpress.com/?p=542</id>
		<updated>2010-08-30T20:20:00+00:00</updated>
		<content type="html">Hi Will, Mike McLaughlin writes: [Akamai Technologies] has just opened a new Engineering Manager role in Cambridge, MA for our mobile team. The position will help lead a team of engineers working with Clojure. We really want to hire someone that will help act as an advocate and evangelist for the Clojure work we are [...]&lt;img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=lispjobs.wordpress.com&amp;blog=504450&amp;post=542&amp;subd=lispjobs&amp;ref=&amp;feed=1" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/clojure?a=Ro2eosQjYao:9rP1ct4KTL8:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/clojure?a=Ro2eosQjYao:9rP1ct4KTL8:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content>
		<author>
			<name>Clojure Jobs</name>
			<uri>http://lispjobs.wordpress.com</uri>
		</author>
		<source>
			<title type="html">Lispjobs » clojure</title>
			<subtitle type="html">A gift to Lisp hackers from Will Fitzgerald</subtitle>
			<link rel="self" href="http://lispjobs.wordpress.com/category/clojure/feed/" />
			<id>http://lispjobs.wordpress.com/category/clojure/feed/</id>
			<updated>2010-09-03T21:01:41+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en-US">
		<title type="html">in which the lessons of ZZ Top are applied to the marketplace</title>
		<link href="http://feedproxy.google.com/~r/clojure/~3/ETnFoIcdGak/140" />
		<id>tag:technomancy.us,2007:in%20which%20the%20lessons%20of%20ZZ%20Top%20are%20applied%20to%20the%20marketplace</id>
		<updated>2010-08-30T18:23:38+00:00</updated>
		<content type="html">&lt;p&gt;I've been thinking a lot about ZZ Top recently. This isn't
  something I generally do as a rule, but it was prompted by
  re-reading &lt;a href="http://gilesbowkett.blogspot.com/2007/10/im-bad-im-nationwide-job-security-vs.html"&gt;a
  blog post&lt;/a&gt; by the inimitable Giles Bowkett ostensibly about the
  song &lt;a href="http://www.youtube.com/watch?v=SxHyHk3h2IU"&gt;I'm Bad;
  I'm Nationwide&lt;/a&gt;. Go ahead and cue that up in the background
  while you read this post; it's vaguely relevant.&lt;/p&gt;

&lt;img src="http://technomancy.us/i/zz-top.jpg" alt="zz top" /&gt;

&lt;p&gt;"Bad" in this sense of course is the good kind of bad, like the
  Michael Jackson song. It seems to be mostly about attitude. Giles
  makes the point that generally being bad is not correlated with
  being nationwide.&lt;/p&gt;

&lt;blockquote&gt;"I'm Bad, I'm Nationwide" is a ZZ Top song. Hopefully
  you can figure out what it's about, but just in case, the singer's
  point is that he is bad, and he is nationwide. [...]&lt;/blockquote&gt;

&lt;blockquote&gt;It's good to be bad. It's good to be nationwide. It's
  even better to be worldwide. How can we apply the lessons of ZZ
  Top in the workplace?&lt;/blockquote&gt;

&lt;blockquote&gt;Obviously if you walk into your boss' office, jump on
  his or her desk, pull down your pants, and perform toilet
  functions all over the place, that would be bad. But it would not
  be nationwide, and it would not encourage becoming nationwide. In
  fact, it would not really be bad, it would just be stupid. But
  this silly example highlights a deeper paradox: that which is bad
  is usually local, and that which is nationwide is usually
  good.&lt;/blockquote&gt;

&lt;p&gt;Giles goes on to talk about how the bad/nationwide balancing act
  applies to a career in software development, which is interesting,
  but I've been thinking about it in terms of projects instead. Take
  the familiar realm of editors. There are a few of them that are
  nationwide just by virtue of having survived and built up a
  following over the course of several decades. And they're also
  often bad when flame wars erupt over them, as is fairly
  common.&lt;/p&gt;

&lt;p&gt;So Emacs and vi have somehow achieved the intersection of bad and
  nationwide, which as Giles posits is tricky to pull off. Simply
  being bad doesn't work in the long-term, and while quiet
  competence sometimes does, it's worth noting that in many cases
  attention helps a project improve in concrete
  ways&amp;mdash;especially projects whose users are developers. This
  is pretty key for things like languages, libraries, and build tools.&lt;/p&gt;

&lt;p&gt;The problem I'm faced with here is that being bad is also often
  correlated with being inflammatory. The easiest way to get attention in
  the software world is to pick a fight. You see this &lt;i&gt;all the
  time&lt;/i&gt; on sites like Reddit; when people smell blood they
  upvote, which is why stuff like
  &lt;a href="http://dosync.posterous.com/clojure-nodejs-and-why-messaging-can-be-lame"&gt;Aleph
  vs Node.js: the smackdown&lt;/a&gt; makes it to the front page despite
  being a superficial comparison.&lt;/p&gt;

&lt;p&gt;The thing you have to remember about picking fights with another
  project or language just for the sake of it is that often the
  attention fallout is more evenly distributed than is
  intended. When someone goes out of their way to pick a fight, they
  &lt;a href="http://www.jroller.com/obie/entry/top_10_reasons_why_java"&gt;usually
  aren't much good at hiding the fact that they've got an investment
  in one side&lt;/a&gt;. Impartial readers can usually pick up on this
  pretty easily, and they're likely to spot holes in the argument
  or write it off it as a piece of cheerleading. In cases of
  particularly unfair partisanship, they may even begin to
  sympathize with the target under attack.&lt;/p&gt;

&lt;p&gt;The closest I've come to this sort of bad/nationwide
  is &lt;a href="http://twitter.com/technomancy/status/10994115673"&gt;this
  post I made on Twitter a few months back&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;Q: What's the difference between Ant and Maven? A: The
  creator of Ant has apologized.&lt;/blockquote&gt;

&lt;p&gt;This turned out to be just the right mix of nasty and clever
  to really take off; hundreds and hundreds of people passed it on, and
  over the next few days searches for my name came up with just
  pages and pages of this over and over again. At the time of this
  writing it's still on the second page of results in a search for
  my name.&lt;/p&gt;

&lt;p&gt;I've got to admit, as the author
  of &lt;a href="http://github.com/technomancy/leiningen"&gt;a build
  system that competes with Maven&lt;/a&gt;, this felt kind of good. The
  problem is it's totally a cheap shot&amp;mdash;everyone involved with
  build tools ends up in a position of needing to apologize to their
  users given enough time. James Duncan Davidson has expressed his
  regrets over the use of XML in ant, Dave Thomas is less than proud
  of how RDoc has turned out, and I'm pretty sure the only reason
  the guy responsible for the tabs/spaces distinction in Makefiles
  hasn't apologized is that he fled to Tijuana for facial
  reconstructive surgery. Anyway, Leiningen will eventually be in
  the same position if it's not already.&lt;/p&gt;

&lt;img src="http://technomancy.us/i/why-range.gif" alt="why sample" align="right" /&gt;

&lt;p&gt;So we're still left with this question of whether you can be bad
  and nationwide without also being a jerk. I think it's doable, but
  you just don't see it much because picking fights is so much
  easier. One example that comes readily to mind
  is &lt;a href="http://en.wikipedia.org/wiki/Why_the_lucky_stiff"&gt;_why
  the lucky stiff&lt;/a&gt;. He qualified not just by his off-kilter visual style
  but by his aversion to what he scoffed at as "best practices".&lt;/p&gt;

&lt;blockquote&gt;Perhaps this is why I have trouble swallowing unit
  testing or extreme programming or other best practices as the
  law. I guess there’s a place for these tricks (the work place,)
  but they do not speak to the pure form of hacking for hacking’s
  sake, which I so ardently defend! Unit testing, in particular, is
  designed to reel in spontaneous hacking. It is like framing a
  picture before it has been painted. Hacking, at heart, will
  continue to be something of spontaneous order, something of
  anarchy, and the landscape of hacking is something which comes
  from human action but is not of human design.&lt;/blockquote&gt;
&lt;p&gt;&lt;a href="http://web.archive.org/web/20080512050317/hackety.org/2007/12/24/thisHackWasNotProperlyPlanned.html"&gt;&amp;#8213;
    This Hack was not Properly Planned&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This may not sound particularly controversial, but in the context
  of the test-driven-fanatic Ruby community it was a pretty weighty
  heresy. But he was all about exploring the fringe, and some
  excellent ideas came of it. It caught peoples' eyes and drew them
  in, so much so that when he disappeared, the communities
  surrounding his projects picked up the orphaned bits and carried
  them forward.&lt;/p&gt;

&lt;img src="http://technomancy.us/i/zz-top2.jpg" alt="gibbons" align="left" /&gt;

&lt;p&gt;Bad... and &lt;i&gt;nationwide&lt;/i&gt;.&lt;/p&gt;

&lt;p&gt;This is way more productive than us-vs-them fights that normally
  accompany attempts to be bad and nationwide. So what does this
  mean for you and me? Most people can't draw like _why, but
  injecting your own particular brand of crazy into your projects
  may be a slick hack you can pull to sidestep the negativity.&lt;/p&gt;

&lt;p&gt;Here's an example: the &lt;tt&gt;new&lt;/tt&gt; task in Leiningen spits out a
  blank Clojure project skeleton. At the time I saw a few too many
  "foojure"-type names popping up for new projects, and when I saw
  one called "Couverjure" I said enough is enough. Now
  the &lt;tt&gt;new&lt;/tt&gt; task will refuse to generate projects named after
  *jure puns. Arbitrary? You bet. Ridiculous? Perhaps. But harmless
  and easy to work around. And don't forget controversial:&lt;/p&gt;

&lt;a href="http://github.com/technomancy/leiningen/commit/39732d5b649dedb70b14e88fe561dfc9ddb31611"&gt;&lt;img src="http://technomancy.us/i/enough.png" alt="no more jure names" /&gt;&lt;/a&gt;

&lt;p&gt;The point is: don't take yourself too seriously. Hack the good
  hack and leave an easter egg or two around for the
  adventurous. Then you too can be bad... and &lt;i&gt;nationwide&lt;/i&gt;.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/clojure?a=ETnFoIcdGak:Pj28DujrfKE:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/clojure?a=ETnFoIcdGak:Pj28DujrfKE:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/clojure/~4/ETnFoIcdGak" height="1" width="1"/&gt;</content>
		<author>
			<name>Phil Hagelberg</name>
			<uri>http://technomancy.us/</uri>
		</author>
		<source>
			<title type="html">Technomancy</title>
			<link rel="self" href="http://technomancy.us/feed/atom.xml" />
			<id>tag:technomancy.us,2007:blog/</id>
			<updated>2010-08-31T21:00:42+00:00</updated>
		</source>
	<feedburner:origLink>http://technomancy.us/140</feedburner:origLink></entry>

	<entry xml:lang="en">
		<title type="html">This weekend in the Intertweets (Aug 29th Ed)</title>
		<link href="http://feedproxy.google.com/~r/clojure/~3/wmH7IoNXSHc/" />
		<id>http://disclojure.org/?p=1127</id>
		<updated>2010-08-30T07:40:35+00:00</updated>
		<content type="html">&lt;ul&gt;
&lt;li&gt;stumbling towards the clojure api (a code example using de maybe monad and null safe operator .?.) (&lt;a href="http://twoguysarguing.wordpress.com/2010/08/26/stumbling-towards-the-clojure-api/"&gt;here&lt;/a&gt;, via @&lt;a href="http://twitter.com/jneira" rel="nofollow" target="_blank" title="View jneira's Twitter Profile"&gt;jneira&lt;/a&gt;) &amp;#8212; The many ways to deal with functions that can return a null value.&lt;/li&gt;
&lt;li&gt;I put together a small example of how to use the #&lt;a href="http://search.twitter.com/search?q=%23websocket" rel="nofollow" target="_blank" title="Search Twitter for "&gt;websocket&lt;/a&gt; support in #&lt;a href="http://search.twitter.com/search?q=%23aleph" rel="nofollow" target="_blank" title="Search Twitter for "&gt;aleph&lt;/a&gt; using #&lt;a href="http://search.twitter.com/search?q=%23clojure" rel="nofollow" target="_blank" title="Search Twitter for "&gt;clojure&lt;/a&gt; (&lt;a href="http://www.spyfoos.com/index.php/2010/08/27/a-simple-chat-app-using-aleph-websockets-and-clojure/"&gt;here&lt;/a&gt;, via @&lt;a href="http://twitter.com/maclausen" rel="nofollow" target="_blank" title="View maclausen's Twitter Profile"&gt;maclausen&lt;/a&gt;) &amp;#8212; Don&amp;#8217;t you worry, you won&amp;#8217;t be reading much code as the code in this example is very succinct.&lt;/li&gt;
&lt;li&gt;Random thoughts on Clojure Protocols (&lt;a href="http://debasishg.blogspot.com/2010/08/random-thoughts-on-clojure-protocols.html"&gt;here&lt;/a&gt;, via @&lt;a href="http://twitter.com/debasishg" rel="nofollow" target="_blank" title="View debasishg's Twitter Profile"&gt;debasishg&lt;/a&gt;) &amp;#8212; This is a very informative article about what protocols in clojure are and are not, the latter part (what protocols are not) being most informative for all of you programming polyglots.&lt;/li&gt;
&lt;li&gt;Porting #&lt;a href="http://search.twitter.com/search?q=%23clojure" rel="nofollow" target="_blank" title="Search Twitter for "&gt;clojure&lt;/a&gt; ants concurrency demo to #&lt;a href="http://search.twitter.com/search?q=%23haskell" rel="nofollow" target="_blank" title="Search Twitter for "&gt;haskell&lt;/a&gt; (&lt;a href="http://www.fatvat.co.uk/2010/08/ants-and-haskell.html"&gt;here&lt;/a&gt;, via @&lt;a href="http://twitter.com/wmacgyver" rel="nofollow" target="_blank" title="View wmacgyver's Twitter Profile"&gt;wmacgyver&lt;/a&gt;) &amp;#8212; Here is a follow-up post, &amp;#8220;&lt;a href="http://www.fatvat.co.uk/2010/08/speeding-up-ants-program.html"&gt;Speeding up the Ants program&lt;/a&gt;&amp;#8221; which contains some interesting profiling info.&lt;/li&gt;
&lt;li&gt;lein-hadoop is now available on clojars.org. Contributions welcome! (&lt;a href="http://github.com/ndimiduk/lein-hadoop"&gt;here&lt;/a&gt;, via @&lt;a href="http://twitter.com/xefyr" rel="nofollow" target="_blank" title="View xefyr's Twitter Profile"&gt;xefyr&lt;/a&gt;) &amp;#8212; A leiningen plugin that lets you create hadoop-compatible jar files.&lt;/li&gt;
&lt;li&gt;The only real problem I have with Clojure is that after learning it, you never want to program in another language again (via @&lt;a href="http://twitter.com/mauritsrijk" rel="nofollow" target="_blank" title="View mauritsrijk's Twitter Profile"&gt;mauritsrijk&lt;/a&gt;) &amp;#8212; I know, it happens&amp;#8230;&lt;/li&gt;
&lt;li&gt;Beware Choosing the Most Complex Tool for the Job (&lt;a href="http://stuartsierra.com/2010/08/28/beware-choosing-the-most-complex-tool-for-the-job"&gt;here&lt;/a&gt;, via @&lt;a href="http://twitter.com/stuartsierra" rel="nofollow" target="_blank" title="View stuartsierra's Twitter Profile"&gt;stuartsierra&lt;/a&gt;) &amp;#8212; A word of caution for those too eager to use the new 1.2 features (protocols, records) that could make your programs more complex and less flexible.&lt;/li&gt;
&lt;li&gt;static &amp;#8211; static blog generator in #&lt;a href="http://search.twitter.com/search?q=%23clojure" rel="nofollow" target="_blank" title="Search Twitter for "&gt;clojure&lt;/a&gt; (&lt;a href="http://nakkaya.com/2010/08/29/so-long-compojure-and-thanks-for-all-the-fish/"&gt;here&lt;/a&gt;, vi a@maclausen) &amp;#8212; Nurullah Akkaya moved his blog away from Compojure and into the static world by using only &lt;a href="http://github.com/weavejester/hiccup"&gt;hiccup&lt;/a&gt;. The code is &lt;a href="http://github.com/nakkaya/static"&gt;here&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/disclojure?a=RqYH45Dchc0:kGoHa3mBoec:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/disclojure?d=yIl2AUoC8zA" border="0" /&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/disclojure?a=RqYH45Dchc0:kGoHa3mBoec:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/disclojure?i=RqYH45Dchc0:kGoHa3mBoec:D7DqB2pKExk" border="0" /&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/disclojure?a=RqYH45Dchc0:kGoHa3mBoec:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/disclojure?i=RqYH45Dchc0:kGoHa3mBoec:V_sGLiPBpWU" border="0" /&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/disclojure?a=RqYH45Dchc0:kGoHa3mBoec:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/disclojure?i=RqYH45Dchc0:kGoHa3mBoec:gIN9vFwOqvQ" border="0" /&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/disclojure/~4/RqYH45Dchc0" height="1" width="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/clojure?a=wmH7IoNXSHc:kGoHa3mBoec:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/clojure?a=wmH7IoNXSHc:kGoHa3mBoec:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/clojure/~4/wmH7IoNXSHc" height="1" width="1"/&gt;</content>
		<author>
			<name>Toni Batchelli</name>
			<uri>http://disclojure.org</uri>
		</author>
		<source>
			<title type="html">disclojure: all things clojure</title>
			<subtitle type="html">public disclosure of all things Clojure</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/disclojure" />
			<id>http://feeds.feedburner.com/disclojure</id>
			<updated>2010-09-03T08:30:53+00:00</updated>
		</source>
	<feedburner:origLink>http://feedproxy.google.com/~r/disclojure/~3/RqYH45Dchc0/</feedburner:origLink></entry>

	<entry>
		<title type="html">Clojure Plugin For Grails</title>
		<link href="http://feedproxy.google.com/~r/clojure/~3/3YwiaCHA480/grails_clojure_plugin" />
		<id>http://pipes.yahoo.com/pipes/27853 at http://java.dzone.com</id>
		<updated>2010-08-30T04:00:48+00:00</updated>
		<content type="html">According to a post from XML co-creator Tim Bray from awhile back, Clojure is considered "the new hotness among people who think the JVM is an interesting platform" for other languages to build on, for people who think that "there's still life in that ol' Lisp beast," and for "people who worry about concurrency and state in the context of the multicore future." In...&lt;img src="http://feeds.feedburner.com/~r/javalobby/frontpage/~4/He8fgGJBMhk" height="1" width="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/clojure?a=3YwiaCHA480:ZuDecZSyNaY:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/clojure?a=3YwiaCHA480:ZuDecZSyNaY:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/clojure/~4/3YwiaCHA480" height="1" width="1"/&gt;</content>
		<author>
			<name>Javalobby</name>
			<uri>http://pipes.yahoo.com/pipes/pipe.info?_id=f8b56ef73099743fdfe6336dd7cd0d5c</uri>
		</author>
		<source>
			<title type="html">Javalobby</title>
			<subtitle type="html">Pipes Output</subtitle>
			<link rel="self" href="http://pipes.yahoo.com/pipes/pipe.run?_id=f8b56ef73099743fdfe6336dd7cd0d5c&amp;_render=rss" />
			<id>http://pipes.yahoo.com/pipes/pipe.run?_id=f8b56ef73099743fdfe6336dd7cd0d5c&amp;_render=rss</id>
			<updated>2010-09-03T21:00:38+00:00</updated>
		</source>
	<feedburner:origLink>http://feeds.dzone.com/~r/javalobby/frontpage/~3/He8fgGJBMhk/grails_clojure_plugin</feedburner:origLink></entry>

	<entry xml:lang="en">
		<title type="html">Leiningen (unknown severity): Compatability with cake</title>
		<link href="http://feedproxy.google.com/~r/clojure/~3/UcIMBFLc0N4/" />
		<id>http://github.com/technomancy/leiningen/issues/#issue/102</id>
		<updated>2010-08-30T00:00:00+00:00</updated>
		<content type="html">Leiningen (unknown severity): Compatability with cake&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/clojure?a=UcIMBFLc0N4:B2eXsY4ZoKU:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/clojure?a=UcIMBFLc0N4:B2eXsY4ZoKU:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/clojure/~4/UcIMBFLc0N4" height="1" width="1"/&gt;</content>
		<author>
			<name>BugSpy</name>
			<uri>http://bugspy.net</uri>
		</author>
		<source>
			<title type="html">BugSpy.net - Reports By Tag: clojure</title>
			<link rel="self" href="http://bugspy.net/tag/clojure/?format=rss" />
			<id>http://bugspy.net/tag/clojure/?format=rss</id>
			<updated>2010-09-03T21:01:14+00:00</updated>
		</source>
	<feedburner:origLink>http://github.com/technomancy/leiningen/issues/#issue/102</feedburner:origLink></entry>

	<entry>
		<title type="html">Using cljr for Clojure development</title>
		<link href="http://feedproxy.google.com/~r/clojure/~3/je0gkewYLTY/using-cljr-for-clojure-development.html" />
		<id>tag:blogger.com,1999:blog-7100397.post-4407437540057680123</id>
		<updated>2010-08-29T18:19:00+00:00</updated>
		<content type="html">At work I now use the Clojure setup that everyone else uses, emacs+swank-clojure, with our custom repositories. For my own Clojure hacking (my own projects) I have just about settled on using cljr for convenience and agility. For me, the big win is being able to access Clojure libraries, Java libraries, and JAR files containing data sets I use often for NLP work from any directory. I don't need a heavy weight project, like for example, using Leiningen with all dependencies locally loaded. cljr uses Leiningen to manage the packages in the single ~/.cljr repository. When you startup cljr, everything in ~/.cljr is on your JVM classpath: this may seem a little heavy, but it is very convenient.&lt;br /&gt;&lt;br /&gt;As an example, this morning I noticed an old Twitter direct message from the author of Nozzle library asking me if I had a chance to try it. Instead of setting up a separate Leiningen project directory, I just did a &lt;b&gt;cljr install com.ashafa/nozzle 0.2.1&lt;/b&gt;, went to my catch-all directory where I keep short snippets of Clojure code, and entered Tunde's test program for Nozzle:&lt;pre&gt;;; assumes: cljr install com.ashafa/nozzle 0.2.1&lt;br /&gt;&lt;br /&gt;(use 'com.ashafa.nozzle)&lt;br /&gt;&lt;br /&gt;(def username (System/getenv "TWITTER_ACCOUNT"))&lt;br /&gt;(def passwd (System/getenv "TWITTER_PASSWD"))&lt;br /&gt;&lt;br /&gt;(defn my-callback &lt;br /&gt; [message] &lt;br /&gt; (println message))&lt;br /&gt;&lt;br /&gt;(def noz (create-nozzle "filter" username passwd my-callback {:track "twitter"}))&lt;/pre&gt;and running it is as simple as:&lt;pre&gt;cljr run nozzle-twitter-test.clj&lt;/pre&gt;or, using swank and Emacs:&lt;pre&gt;cljr swank&lt;/pre&gt;and in Emacs do &lt;b&gt;M-x slime-connect&lt;/b&gt; and in the repl: &lt;b&gt;(load "nozzle-twitter-test")&lt;/b&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/7100397-4407437540057680123?l=blog.markwatson.com" alt="" /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/clojure?a=je0gkewYLTY:V7rLwMXV8Zw:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/clojure?a=je0gkewYLTY:V7rLwMXV8Zw:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/clojure/~4/je0gkewYLTY" height="1" width="1"/&gt;</content>
		<author>
			<name>Mark Watson</name>
			<uri>http://pipes.yahoo.com/pipes/pipe.info?_id=a0161f6185ca965613735b6b06f2e3ef</uri>
		</author>
		<source>
			<title type="html">Mark Watson</title>
			<subtitle type="html">Pipes Output</subtitle>
			<link rel="self" href="http://pipes.yahoo.com/pipes/pipe.run?_id=a0161f6185ca965613735b6b06f2e3ef&amp;_render=rss" />
			<id>http://pipes.yahoo.com/pipes/pipe.run?_id=a0161f6185ca965613735b6b06f2e3ef&amp;_render=rss</id>
			<updated>2010-09-03T21:01:28+00:00</updated>
		</source>
	<feedburner:origLink>http://blog.markwatson.com/2010/08/using-cljr-for-clojure-development.html</feedburner:origLink></entry>

	<entry>
		<title type="html">My light weight Clojure wrapper for the PowerLoom knowledge representation and reasoning system</title>
		<link href="http://feedproxy.google.com/~r/clojure/~3/Z7ZF965SGnY/my-light-weight-clojure-wrapper-for.html" />
		<id>tag:blogger.com,1999:blog-7100397.post-3794869637074081384</id>
		<updated>2010-08-29T18:13:00+00:00</updated>
		<content type="html">A ZIP file with everything you need to try it is on &lt;a rel="nofollow" target="_blank" href="http://markwatson.com/opensource/"&gt;my open source&lt;/a&gt; web page.&lt;br /&gt;&lt;br /&gt;&lt;a rel="nofollow" target="_blank" href="http://www.isi.edu/isd/LOOM/PowerLoom/"&gt;PowerLoom&lt;/a&gt; has been in development for many years and is available in Common Lisp, C++, and Java editions. I wrapped the Java edition for this project.&lt;br /&gt;&lt;br /&gt;This is just a first cut at a wrapper because assertions and queries must be encoded as strings.&lt;div class="blogger-post-footer"&gt;&lt;img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/7100397-3794869637074081384?l=blog.markwatson.com" alt="" /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/clojure?a=Z7ZF965SGnY:M1eO59p5TSk:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/clojure?a=Z7ZF965SGnY:M1eO59p5TSk:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/clojure/~4/Z7ZF965SGnY" height="1" width="1"/&gt;</content>
		<author>
			<name>Mark Watson</name>
			<uri>http://pipes.yahoo.com/pipes/pipe.info?_id=a0161f6185ca965613735b6b06f2e3ef</uri>
		</author>
		<source>
			<title type="html">Mark Watson</title>
			<subtitle type="html">Pipes Output</subtitle>
			<link rel="self" href="http://pipes.yahoo.com/pipes/pipe.run?_id=a0161f6185ca965613735b6b06f2e3ef&amp;_render=rss" />
			<id>http://pipes.yahoo.com/pipes/pipe.run?_id=a0161f6185ca965613735b6b06f2e3ef&amp;_render=rss</id>
			<updated>2010-09-03T21:01:28+00:00</updated>
		</source>
	<feedburner:origLink>http://blog.markwatson.com/2010/08/my-light-weight-clojure-wrapper-for.html</feedburner:origLink></entry>

	<entry>
		<title type="html">I am merging my other three blogs into this (my main) blog</title>
		<link href="http://feedproxy.google.com/~r/clojure/~3/67hp_lPmJDc/i-am-merging-my-other-three-blogs-into.html" />
		<id>tag:blogger.com,1999:blog-7100397.post-8568455808637594488</id>
		<updated>2010-08-29T17:38:00+00:00</updated>
		<content type="html">I had what I thought was a good idea in the last year: split out special interests into:&lt;ul&gt;&lt;li&gt;This blog - general technology, and Java&lt;/li&gt;&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://www.clojurepla.net/"&gt;Clojurepla.net - my work and play with Clojure&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://www.rubyplanet.net/"&gt;RubyPlanet.net - everything I do with Ruby&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://aiblog.markwatson.com/"&gt;My artificial Intelligence blog&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;I am going to leave my other three blogs intact, as-is, but I am going to start doing two things: all of my non-book writing will go into this single blog and I am going to copy a few of my recent articles in the other three blogs to this one. Havng four distinct blogs has been a nuisance.&lt;div class="blogger-post-footer"&gt;&lt;img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/7100397-8568455808637594488?l=blog.markwatson.com" alt="" /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/clojure?a=67hp_lPmJDc:aF4llVTQXUc:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/clojure?a=67hp_lPmJDc:aF4llVTQXUc:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/clojure/~4/67hp_lPmJDc" height="1" width="1"/&gt;</content>
		<author>
			<name>Mark Watson</name>
			<uri>http://pipes.yahoo.com/pipes/pipe.info?_id=a0161f6185ca965613735b6b06f2e3ef</uri>
		</author>
		<source>
			<title type="html">Mark Watson</title>
			<subtitle type="html">Pipes Output</subtitle>
			<link rel="self" href="http://pipes.yahoo.com/pipes/pipe.run?_id=a0161f6185ca965613735b6b06f2e3ef&amp;_render=rss" />
			<id>http://pipes.yahoo.com/pipes/pipe.run?_id=a0161f6185ca965613735b6b06f2e3ef&amp;_render=rss</id>
			<updated>2010-09-03T21:01:28+00:00</updated>
		</source>
	<feedburner:origLink>http://blog.markwatson.com/2010/08/i-am-merging-my-other-three-blogs-into.html</feedburner:origLink></entry>

	<entry xml:lang="en">
		<title type="html">Beware Choosing the Most Complex Tool for the Job</title>
		<link href="http://feedproxy.google.com/~r/clojure/~3/HfxawEqcfIk/beware-choosing-the-most-complex-tool-for-the-job" />
		<id>http://stuartsierra.com/?p=490</id>
		<updated>2010-08-28T21:48:23+00:00</updated>
		<content type="html">&lt;p&gt;I once saw a TV show about competing groups of archeologists trying to demonstrate how the ancient Egyptians raised stone obelisks weighing hundreds of tons.&lt;/p&gt;
&lt;p&gt;One group of archeologists built a &lt;a href="http://www.pbs.org/wgbh/nova/lostempires/obelisk/raises09.html"&gt;complex apparatus&lt;/a&gt; involving a wooden frame and lots of rope. It looked impressive, but it didn&amp;#8217;t work.&lt;/p&gt;
&lt;p&gt;The other team built a &lt;a href="http://www.pbs.org/wgbh/nova/lostempires/obelisk/raises13.html"&gt;sand pit&lt;/a&gt;, dragged the obelisk to the top, and gradually removed sand from below the obelisk until it reached its final position. Simple, unglamorous, and it worked on the first try. (See the whole &lt;a href="http://www.pbs.org/wgbh/nova/lostempires/obelisk/raises.html"&gt;series of photos&lt;/a&gt;.)&lt;/p&gt;
&lt;p&gt;The leader of the wooden-frame group &lt;a href="http://www.pbs.org/wgbh/nova/lostempires/obelisk/raises10.html"&gt;admitted&lt;/a&gt; they were mistaken in basing their design on the most complex ancient technology they could find, sailing ships. Instead, he said, &amp;#8220;We should have asked, &amp;#8216;What is the simplest way they could have done it?&amp;#8217;&amp;#8221;&lt;/p&gt;
&lt;p&gt;***&lt;/p&gt;
&lt;p&gt;From the ancient Egyptians, jump forward about four thousand years to me, sitting at my computer, writing a new testing framework for Clojure.  I was excited about the new Clojure features &lt;em&gt;datatypes&lt;/em&gt; and &lt;em&gt;protocols&lt;/em&gt;. I based my whole framework around them. It was a beast. Lots of weird edge cases and complex interactions that were hard to reason about and even harder to debug. Datatypes and protocols may be a powerful tool, but that doesn&amp;#8217;t always make them the right tool.&lt;/p&gt;
&lt;p&gt;After my fourth or fifth rewrite of Lazytest, I started asking myself, &amp;#8220;What is the simplest way I could do this?&amp;#8221;&lt;/p&gt;
&lt;p&gt;The answer was staring me in the face. Clojure is a functional language (mostly). What&amp;#8217;s the simplest way to do anything? Functions!&lt;/p&gt;
&lt;p&gt;All of a sudden, complexity started to fall away. My protocols, most of which only had a single method anyway, became ordinary functions. My typed data structures became ordinary maps. The code shrank by many lines, and it was vastly easier to understand. Even better, I discovered new possibilities in the simpler design.&lt;/p&gt;
&lt;p&gt;Functions are a fantastic abstraction because they can be composed.  In the new Lazytest, everything is a function: test cases, test suites, and contexts. The RSpec-like &lt;code&gt;describe&lt;/code&gt; macros are still there, but they&amp;#8217;re simpler. They do what macros are supposed to do: provide a convenient syntactic layer over functional definitions, not define a completely new language.&lt;/p&gt;
&lt;p&gt;I haven&amp;#8217;t completely finished the new API &amp;#8212; fixtures, now renamed back to &amp;#8220;contexts,&amp;#8221; are not supported yet.  But I&amp;#8217;m much happier with this version than with the old one.  I actually feel like this is something I&amp;#8217;d be willing to release soon.  So &lt;a href="http://github.com/stuartsierra/lazytest"&gt;give it a spin&lt;/a&gt; and tell me what you think.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/StuartSierra/~4/ub4yjhGLFf8" height="1" width="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/clojure?a=HfxawEqcfIk:jJ2F_E0SP_w:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/clojure?a=HfxawEqcfIk:jJ2F_E0SP_w:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/clojure/~4/HfxawEqcfIk" height="1" width="1"/&gt;</content>
		<author>
			<name>Stuart Sierra</name>
			<uri>http://stuartsierra.com</uri>
		</author>
		<source>
			<title type="html">Digital Digressions by Stuart Sierra</title>
			<subtitle type="html">From programming to everything else</subtitle>
			<link rel="self" href="http://feeds2.feedburner.com/StuartSierra" />
			<id>http://feeds2.feedburner.com/StuartSierra</id>
			<updated>2010-08-28T22:01:30+00:00</updated>
		</source>
	<feedburner:origLink>http://feedproxy.google.com/~r/StuartSierra/~3/ub4yjhGLFf8/beware-choosing-the-most-complex-tool-for-the-job</feedburner:origLink></entry>

	<entry>
		<title type="html">Random thoughts on Clojure Protocols</title>
		<link href="http://feedproxy.google.com/~r/clojure/~3/M_Vylnbhtxk/random-thoughts-on-clojure-protocols.html" />
		<id>tag:blogger.com,1999:blog-22587889.post-771609389628045845</id>
		<updated>2010-08-27T22:15:00+00:00</updated>
		<content type="html">Great languages are those that offer orthogonality in design. Stated simply it means that the language core offers a minimal set of non-overlapping ways to compose abstractions. In an earlier article &lt;a rel="nofollow" target="_blank" href="http://debasishg.blogspot.com/2010/01/case-for-orthogonality-in-design.html"&gt;A Case for Orthogonality in Design&lt;/a&gt; I discussed some features from languages like Haskell, C++ and Scala that help you compose higher order abstractions from smaller ones using techniques offered by those languages.&lt;br /&gt;&lt;br /&gt;In this post I discuss the new feature in Clojure that just made its way in the recently released 1.2. I am not going into what Protocols are - there are quite a &lt;a rel="nofollow" target="_blank" href="http://kirindave.tumblr.com/post/658770511/monkey-patching-gorilla-engineering-protocols-in"&gt;few&lt;/a&gt; &lt;a rel="nofollow" target="_blank" href="http://freegeek.in/blog/2010/05/clojure-protocols-datatypes-a-sneak-peek/"&gt;nice&lt;/a&gt; articles that introduce &lt;a rel="nofollow" target="_blank" href="http://www.assembla.com/wiki/show/clojure/Protocols"&gt;Clojure Protocols&lt;/a&gt; and the associated &lt;code&gt;defrecord&lt;/code&gt; and &lt;code&gt;deftype&lt;/code&gt; forms. This post will be some random rants about how protocols encourage non intrusive extension of abstractions without muddling inheritance into polymorphism. I also discuss some of my realizations about what protocols aren't, which I felt was equally important along with understanding what they are.&lt;br /&gt;&lt;br /&gt;Let's start with the familiar &lt;code&gt;Show&lt;/code&gt; type class of Haskell ..&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;span class="java_operator"&gt;&amp;gt;&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_operator"&gt;:&lt;/span&gt;&lt;span class="java_plain"&gt;t&amp;nbsp;show&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&lt;span class="java_plain"&gt;show&amp;nbsp;&lt;/span&gt;&lt;span class="java_operator"&gt;::&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_separator"&gt;(&lt;/span&gt;&lt;span class="java_type"&gt;Show&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;a&lt;/span&gt;&lt;span class="java_separator"&gt;)&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_operator"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;a&amp;nbsp;&lt;/span&gt;&lt;span class="java_operator"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_type"&gt;String&lt;/span&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;Takes a type and renders a string for it. You get &lt;code&gt;show&lt;/code&gt; for your class if you have implemented it as an instance of the &lt;code&gt;Show&lt;/code&gt; type class. The &lt;code&gt;Show&lt;/code&gt; type class extends your abstraction transparently through an additional behavior set. We can do the same thing using protocols in Clojure ..&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;span class="java_separator"&gt;(&lt;/span&gt;&lt;span class="java_keyword"&gt;defprotocol&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;SHOW&amp;nbsp;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class="java_separator"&gt;(&lt;/span&gt;&lt;span class="java_plain"&gt;show&amp;nbsp;&lt;/span&gt;&lt;span class="java_separator"&gt;[&lt;/span&gt;&lt;span class="java_plain"&gt;val&lt;/span&gt;&lt;span class="java_separator"&gt;]))&lt;/span&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;The protocol definition just &lt;i&gt;declares&lt;/i&gt; the contract without any &lt;i&gt;concrete implementation&lt;/i&gt; in it. Under the covers it generates a Java interface which you can use in your Java code as well. &lt;i&gt;But a protocol is not an interface&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Adding behaviors non-invasively ..&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;I can extend an existing type with the behaviors of this protocol. And for this I need not have the source code for the type. This is one of the benefits that &lt;a rel="nofollow" target="_blank" href="http://www.haskell.org/haskellwiki/Ad-hoc_polymorphism"&gt;ad hoc polymorphism&lt;/a&gt; of type classes offers - type classes (and Clojure protocols) are &lt;i&gt;open&lt;/i&gt;. Note how this is in contrast to the compile time coupling of Java interface and inheritance.&lt;br /&gt;&lt;br /&gt;Extending &lt;code&gt;java.lang.Integer&lt;/code&gt; with &lt;code&gt;SHOW&lt;/code&gt; ..&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;span class="java_separator"&gt;(&lt;/span&gt;&lt;span class="java_keyword"&gt;extend-type&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_type"&gt;Integer&lt;/span&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&amp;nbsp;SHOW&lt;/span&gt;&lt;br /&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class="java_separator"&gt;(&lt;/span&gt;&lt;span class="java_plain"&gt;show&amp;nbsp;&lt;/span&gt;&lt;span class="java_separator"&gt;[&lt;/span&gt;&lt;span class="java_plain"&gt;i&lt;/span&gt;&lt;span class="java_separator"&gt;]&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_separator"&gt;(.&lt;/span&gt;&lt;span class="java_plain"&gt;toString&amp;nbsp;i&lt;/span&gt;&lt;span class="java_separator"&gt;)))&lt;/span&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;We can extend an interface also. And get access to the added behavior from *any* of its implementations .. Here's extending &lt;code&gt;clojure.lang.IPersistentVector&lt;/code&gt; ..&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;span class="java_separator"&gt;(&lt;/span&gt;&lt;span class="java_keyword"&gt;extend-type&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;clojure&lt;/span&gt;&lt;span class="java_separator"&gt;.&lt;/span&gt;&lt;span class="java_plain"&gt;lang&lt;/span&gt;&lt;span class="java_separator"&gt;.&lt;/span&gt;&lt;span class="java_type"&gt;IPersistentVector&lt;/span&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&amp;nbsp;SHOW&lt;/span&gt;&lt;br /&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class="java_separator"&gt;(&lt;/span&gt;&lt;span class="java_plain"&gt;show&amp;nbsp;&lt;/span&gt;&lt;span class="java_separator"&gt;[&lt;/span&gt;&lt;span class="java_plain"&gt;v&lt;/span&gt;&lt;span class="java_separator"&gt;]&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_separator"&gt;(.&lt;/span&gt;&lt;span class="java_plain"&gt;toString&amp;nbsp;v&lt;/span&gt;&lt;span class="java_separator"&gt;)))&lt;/span&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="java_separator"&gt;(&lt;/span&gt;&lt;span class="java_plain"&gt;show&amp;nbsp;&lt;/span&gt;&lt;span class="java_separator"&gt;[&lt;/span&gt;&lt;span class="java_literal"&gt;12&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_literal"&gt;1&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_literal"&gt;4&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_literal"&gt;15&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_literal"&gt;2&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_literal"&gt;4&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_literal"&gt;67&lt;/span&gt;&lt;span class="java_separator"&gt;])&lt;/span&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="java_operator"&gt;&amp;gt;&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_literal"&gt;"[12&amp;nbsp;1&amp;nbsp;4&amp;nbsp;15&amp;nbsp;2&amp;nbsp;4&amp;nbsp;67]"&lt;/span&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;And of course I can extend my own abstractions with the new behavior ..&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;span class="java_separator"&gt;(&lt;/span&gt;&lt;span class="java_keyword"&gt;defrecord&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_type"&gt;Name&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_separator"&gt;[&lt;/span&gt;&lt;span class="java_plain"&gt;last&amp;nbsp;first&lt;/span&gt;&lt;span class="java_separator"&gt;])&lt;/span&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="java_separator"&gt;(&lt;/span&gt;&lt;span class="java_keyword"&gt;defn&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;name&lt;/span&gt;&lt;span class="java_operator"&gt;-&lt;/span&gt;&lt;span class="java_plain"&gt;desc&amp;nbsp;&lt;/span&gt;&lt;span class="java_separator"&gt;[&lt;/span&gt;&lt;span class="java_plain"&gt;name&lt;/span&gt;&lt;span class="java_separator"&gt;]&lt;/span&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class="java_separator"&gt;(&lt;/span&gt;&lt;span class="java_plain"&gt;str&amp;nbsp;&lt;/span&gt;&lt;span class="java_separator"&gt;(&lt;/span&gt;&lt;span class="java_operator"&gt;:&lt;/span&gt;&lt;span class="java_plain"&gt;last&amp;nbsp;name&lt;/span&gt;&lt;span class="java_separator"&gt;)&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_literal"&gt;"&amp;nbsp;"&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_separator"&gt;(&lt;/span&gt;&lt;span class="java_operator"&gt;:&lt;/span&gt;&lt;span class="java_plain"&gt;first&amp;nbsp;name&lt;/span&gt;&lt;span class="java_separator"&gt;)))&lt;/span&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="java_separator"&gt;(&lt;/span&gt;&lt;span class="java_plain"&gt;name&lt;/span&gt;&lt;span class="java_operator"&gt;-&lt;/span&gt;&lt;span class="java_plain"&gt;desc&amp;nbsp;&lt;/span&gt;&lt;span class="java_separator"&gt;(&lt;/span&gt;&lt;span class="java_type"&gt;Name&lt;/span&gt;&lt;span class="java_separator"&gt;.&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_literal"&gt;"ghosh"&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_literal"&gt;"debasish"&lt;/span&gt;&lt;span class="java_separator"&gt;))&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_separator"&gt;;;&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_literal"&gt;"ghosh&amp;nbsp;debasish"&lt;/span&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="java_separator"&gt;(&lt;/span&gt;&lt;span class="java_keyword"&gt;extend-type&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_type"&gt;Name&lt;/span&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&amp;nbsp;SHOW&lt;/span&gt;&lt;br /&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class="java_separator"&gt;(&lt;/span&gt;&lt;span class="java_plain"&gt;show&amp;nbsp;&lt;/span&gt;&lt;span class="java_separator"&gt;[&lt;/span&gt;&lt;span class="java_plain"&gt;n&lt;/span&gt;&lt;span class="java_separator"&gt;]&lt;/span&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class="java_separator"&gt;(&lt;/span&gt;&lt;span class="java_plain"&gt;name&lt;/span&gt;&lt;span class="java_operator"&gt;-&lt;/span&gt;&lt;span class="java_plain"&gt;desc&amp;nbsp;n&lt;/span&gt;&lt;span class="java_separator"&gt;)))&lt;/span&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="java_separator"&gt;(&lt;/span&gt;&lt;span class="java_plain"&gt;show&amp;nbsp;&lt;/span&gt;&lt;span class="java_separator"&gt;(&lt;/span&gt;&lt;span class="java_type"&gt;Name&lt;/span&gt;&lt;span class="java_separator"&gt;.&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_literal"&gt;"ghosh"&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_literal"&gt;"debasish"&lt;/span&gt;&lt;span class="java_separator"&gt;))&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_separator"&gt;;;&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_literal"&gt;"ghosh&amp;nbsp;debasish"&lt;/span&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&lt;b&gt;No Inheritance&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Protocols help you wire abstractions that are in no way related to each other. And it does this non-invasively. An object conforms to a protocol only if it implements the contract. As I mentioned before, there's no notion of hierarchy or inheritance related to this form of polymorphism.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;No object bloat, no monkey patching&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;And there's no object bloat going on here. You can invoke &lt;code&gt;show&lt;/code&gt; on any abstraction for which you implement the protocol, but &lt;code&gt;show&lt;/code&gt; is never added as a method on that object. As an example try the following after implementing &lt;code&gt;SHOW&lt;/code&gt; for &lt;code&gt;Integer&lt;/code&gt; ..&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;span class="java_separator"&gt;(&lt;/span&gt;&lt;span class="java_plain"&gt;filter&amp;nbsp;#&lt;/span&gt;&lt;span class="java_separator"&gt;(&lt;/span&gt;&lt;span class="java_operator"&gt;=&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_literal"&gt;"show"&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_separator"&gt;(.&lt;/span&gt;&lt;span class="java_plain"&gt;getName&amp;nbsp;&lt;/span&gt;&lt;span class="java_operator"&gt;%&lt;/span&gt;&lt;span class="java_separator"&gt;))&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_separator"&gt;(.&lt;/span&gt;&lt;span class="java_plain"&gt;getMethods&amp;nbsp;&lt;/span&gt;&lt;span class="java_type"&gt;Integer&lt;/span&gt;&lt;span class="java_separator"&gt;))&lt;/span&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;will return an empty list. Hence there is no scope of *accidentally* overriding some one else's monkey patch on some shared class.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Not really a type class&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Clojure protocols dispatch on the first argument of the methods. This limits its ability from getting the full power that Haskell / Scala type classes offer. Consider the counterpart of &lt;code&gt;Show&lt;/code&gt; in Haskell, which is the Read type class ..&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;span class="java_operator"&gt;&amp;gt;&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_operator"&gt;:&lt;/span&gt;&lt;span class="java_plain"&gt;t&amp;nbsp;read&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&lt;span class="java_plain"&gt;read&amp;nbsp;&lt;/span&gt;&lt;span class="java_operator"&gt;::&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_separator"&gt;(&lt;/span&gt;&lt;span class="java_type"&gt;Read&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;a&lt;/span&gt;&lt;span class="java_separator"&gt;)&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_operator"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_type"&gt;String&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_operator"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;a&lt;/span&gt;&lt;br /&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;If your abstraction implements &lt;code&gt;Read&lt;/code&gt;, then the exact instance of the method invoked will depend on the return type. e.g.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;span class="java_operator"&gt;&amp;gt;&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_separator"&gt;[&lt;/span&gt;&lt;span class="java_literal"&gt;1&lt;/span&gt;&lt;span class="java_separator"&gt;,&lt;/span&gt;&lt;span class="java_literal"&gt;2&lt;/span&gt;&lt;span class="java_separator"&gt;,&lt;/span&gt;&lt;span class="java_literal"&gt;3&lt;/span&gt;&lt;span class="java_separator"&gt;]&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_operator"&gt;++&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;read&amp;nbsp;&lt;/span&gt;&lt;span class="java_literal"&gt;"[4,5,6]"&lt;/span&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&lt;span class="java_operator"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="java_plain"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="java_separator"&gt;[&lt;/span&gt;&lt;span class="java_literal"&gt;1&lt;/span&gt;&lt;span class="java_separator"&gt;,&lt;/span&gt;&lt;span class="java_literal"&gt;2&lt;/span&gt;&lt;span class="java_separator"&gt;,&lt;/span&gt;&lt;span class="java_literal"&gt;3&lt;/span&gt;&lt;span class="java_separator"&gt;,&lt;/span&gt;&lt;span class="java_literal"&gt;4&lt;/span&gt;&lt;span class="java_separator"&gt;,&lt;/span&gt;&lt;span class="java_literal"&gt;5&lt;/span&gt;&lt;span class="java_separator"&gt;,&lt;/span&gt;&lt;span class="java_literal"&gt;6&lt;/span&gt;&lt;span class="java_separator"&gt;]&lt;/span&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="java_plain"&gt;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;The specific instance of &lt;code&gt;read&lt;/code&gt; that returns a list of integers is automatically invoked here. Haskell maintains the dispatch match as part of its global dictionary.&lt;br /&gt;&lt;br /&gt;We cannot do this in Clojure protocols, since it's unable to dispatch based on the return type. Protocols dispatch only on the first argument of the function.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/22587889-771609389628045845?l=debasishg.blogspot.com" alt="" /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/clojure?a=M_Vylnbhtxk:Cjyq80TYTMM:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/clojure?a=M_Vylnbhtxk:Cjyq80TYTMM:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/clojure/~4/M_Vylnbhtxk" height="1" width="1"/&gt;</content>
		<author>
			<name>Debasish Ghosh</name>
			<uri>http://pipes.yahoo.com/pipes/pipe.info?_id=e35d6881f8ced55bed527c7a501fad8d</uri>
		</author>
		<source>
			<title type="html">Debasish Ghosh&amp;amp;#39;s Clojure posts</title>
			<subtitle type="html">Pipes Output</subtitle>
			<link rel="self" href="http://pipes.yahoo.com/pipes/pipe.run?_id=e35d6881f8ced55bed527c7a501fad8d&amp;_render=rss" />
			<id>http://pipes.yahoo.com/pipes/pipe.run?_id=e35d6881f8ced55bed527c7a501fad8d&amp;_render=rss</id>
			<updated>2010-09-03T21:00:23+00:00</updated>
		</source>
	<feedburner:origLink>http://debasishg.blogspot.com/2010/08/random-thoughts-on-clojure-protocols.html</feedburner:origLink></entry>

	<entry>
		<title type="html">Ants and Haskell</title>
		<link href="http://feedproxy.google.com/~r/clojure/~3/AAYuhp_VrvM/ants-and-haskell.html" />
		<id>tag:blogger.com,1999:blog-5743983044224833668.post-6532671699357395376</id>
		<updated>2010-08-27T16:12:00+00:00</updated>
		<content type="html">&lt;a rel="nofollow" target="_blank" href="http://en.wikipedia.org/wiki/Software_transactional_memory"&gt;Software Transactional Memory&lt;/a&gt; ( STM ) is a concurrency control mechanism designed to simplify programming for shared memory computers. &lt;a rel="nofollow" target="_blank" href="http://www.amazon.com/Beautiful-Code-Leading-Programmers-Practice/dp/0596510047?ie=UTF8&amp;tag=fatvat-20&amp;link_code=btl&amp;camp=213689&amp;creative=392969"&gt;Beautiful Code&lt;/a&gt;&lt;img alt="" border="0" height="1" src="http://www.assoc-amazon.com/e/ir?t=fatvat-20&amp;l=btl&amp;camp=213689&amp;creative=392969&amp;o=1&amp;a=0596510047" width="1" /&gt; contains a great introduction to the concepts of STM in the Haskell language &lt;br /&gt;
&lt;br /&gt;
In most languages, &lt;a rel="nofollow" target="_blank" href="http://en.wikipedia.org/wiki/Lock_(computer_science)"&gt;locks&lt;/a&gt; and &lt;a rel="nofollow" target="_blank" href="http://en.wikipedia.org/wiki/Monitor_(synchronization)"&gt;condition variables&lt;/a&gt; are the main mechanisms for controlling access, but these are notoriously hard to get right. &lt;a rel="nofollow" target="_blank" href="http://www.amazon.com/Java-Concurrency-Practice-Brian-Goetz/dp/0321349601?ie=UTF8&amp;tag=fatvat-20&amp;link_code=btl&amp;camp=213689&amp;creative=392969"&gt;Java Concurrency in Practice&lt;/a&gt;&lt;img alt="" border="0" height="1" src="http://www.assoc-amazon.com/e/ir?t=fatvat-20&amp;l=btl&amp;camp=213689&amp;creative=392969&amp;o=1&amp;a=0321349601" width="1" /&gt; is a good read to understand just how many ways there are to shoot yourself in the foot (too few locks, too many locks, wrong locks, race conditions, wrong order, error conditions, deadlock, livelock, live stock, brain explosion). STM simplifies shared memory programming by providing database like semantics for changing memory. Reads/Writes to shared memory happen within a transaction - each memory access appears to happens in isolation from the others and appears atomically to observers. If a transaction conflict with another, then one of the transactions is retried. An implementation typically records the memory accesses somehow and then can decide whether there was a conflict. Languages that restrict mutability (like &lt;a rel="nofollow" target="_blank" href="http://www.clojure.org/"&gt;Clojure&lt;/a&gt; and &lt;a rel="nofollow" target="_blank" href="http://www.haskell.org/"&gt;Haskell&lt;/a&gt;) have a significantly simpler implementation than imperative languages such as C/C++.&lt;br /&gt;
&lt;br /&gt;
Composability is another advantage for STM. For example, take &lt;a rel="nofollow" target="_blank" href="http://download.oracle.com/javase/6/docs/api/java/util/Hashtable.html"&gt;java.util.Hashtable&lt;/a&gt; - what if you want to do an insert/delete as a single atomic operation and only make the contents visible to other threads once finished? As the original design didn't do this, you're on your own. In contrast STM composes well.&lt;br /&gt;
&lt;br /&gt;
Both &lt;a rel="nofollow" target="_blank" href="http://www.clojure.org/"&gt;Clojure&lt;/a&gt; and &lt;a rel="nofollow" target="_blank" href="http://www.haskell.org/"&gt;Haskell&lt;/a&gt; feature support for STM. The canonical example in Clojure is &lt;a rel="nofollow" target="_blank" href="http://clojure.googlegroups.com/web/ants.clj"&gt;Ants.clj&lt;/a&gt; that demonstrates STM via a simple simulation of foraging ants (see also &lt;a rel="nofollow" target="_blank" href="http://www.fatvat.co.uk/2009/07/flocking-about-with-clojure.html"&gt;Flocking about with Clojure&lt;/a&gt;). As a learning exercise I thought it'd be neat to try to convert this over to Haskell!&lt;br /&gt;
&lt;br /&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;a rel="nofollow" target="_blank" href="http://4.bp.blogspot.com/_XfmDdL0570Q/THgyegTPEsI/AAAAAAAAAEQ/XzkMjpawWAA/s1600/ants.png"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_XfmDdL0570Q/THgyegTPEsI/AAAAAAAAAEQ/XzkMjpawWAA/s320/ants.png" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption"&gt;Ants in Haskell&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;
To model the ants world, I use the following data structures. Transactional variables (TVars) are used to hold a reference to a mutable variable. For the Ants simulation, I use a &lt;a rel="nofollow" target="_blank" href="http://hackage.haskell.org/packages/archive/vector/0.6.0.2/doc/html/Data-Vector.html"&gt;Vector&lt;/a&gt; of TCell's to represent the ants world.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt; 
&lt;br /&gt;
TVars can only be modified within the &lt;a rel="nofollow" target="_blank" href="http://hackage.haskell.org/packages/archive/stm/2.1.1.2/doc/html/Control-Monad-STM.html"&gt;STM context&lt;/a&gt;. The key thing is that the &lt;b&gt;only&lt;/b&gt; way to mutate transactional variables is from within the STM monad. To fiddle with the variables within TVar you can use &lt;code&gt;newTVar&lt;/code&gt;, readTVar and &lt;code&gt;writeTVar&lt;/code&gt;. Oddly there didn't seem to be a primitive operation to update a TVar based on its current value. &lt;code&gt;updateTVar&lt;/code&gt; updates the TVar by applying a function to the value inside.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt; 
&lt;br /&gt;
&lt;a rel="nofollow" target="_blank" href="http://hackage.haskell.org/packages/archive/stm/2.1.1.2/doc/html/Control-Monad-STM.html#v%3Acheck"&gt;&lt;code&gt;check&lt;/code&gt;&lt;/a&gt; verifies that a condition is true and if it isn't true then the transaction is retried. The key point is that the transaction is only retried when there's a reason to do so (e.g. memory read/write) so you aren't just heating the CPU whilst the condition is being validated. As an example, when we move an ant forward, we want to check that there is not an ant in the way. If there is an ant in the way, we'll wait till the coast is clear before moving.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt; 
&lt;br /&gt;
At some point you have to run your STM actions. &lt;code&gt;atomically&lt;/code&gt; runs the STM transactions from the IO monad (e.g. the top-level) and returns the result. A very important point is that you want your actions to be in the STM monad as much as possible. If all of your functions are run within the IO monad then you lose the composability aspect. The pattern to use is make everything use the STM monad and glue together randomly and you won't have a threading problem (you still have other problems though, it's not magic).&lt;br /&gt;
&lt;br /&gt;
The Clojure code used &lt;a rel="nofollow" target="_blank" href="http://clojure.org/agents"&gt;agents&lt;/a&gt; to represent each ant. I'm not sure what the most idiomatic translation to Haskell is, but I spawned a thread for each ant using &lt;a rel="nofollow" target="_blank" href="http://haskell.org/ghc/docs/6.12.2/html/libraries/base-4.2.0.1/Control-Concurrent.html"&gt;Control.Concurrent&lt;/a&gt; and &lt;code&gt;forkIO&lt;/code&gt;. Haskell threads are incredibly light-weight so spawning even thousands of them is not a problem. Each ant thread simply evaluates the behaviour, moves, sleeps and repeats. &lt;br /&gt;
&lt;br /&gt;
The rest of the code is more or less a direction translation from the Clojure. It's pretty verbose so I won't bother posting it here, but the full code is on &lt;a rel="nofollow" target="_blank" href="http://github.com/fffej/haskellprojects/tree/master/ants/"&gt;my github page&lt;/a&gt;. You should be able to compile it with &lt;code&gt;ghc -lglut --make -main-is AntsVis AntsVis.hs&lt;/code&gt;. Any hints on how to make it suck less appreciated!&lt;br /&gt;
&lt;br /&gt;
Performance seems very good with the default compiler options, I'm able to run with 100+ ant agents all running concurrently. &amp;nbsp;The programming is very simple and once I'd found out and added the appropriate check logic into &lt;code&gt;move&lt;/code&gt; everything worked properly.&lt;br /&gt;
&lt;br /&gt;
Hurrah for simple concurrent programming!&lt;br /&gt;
&lt;br /&gt;
(update 30/8/2010 - after finding out the performance sucked after a while with a few more ants than I'd tested with I looked at &lt;a rel="nofollow" target="_blank" href="http://www.fatvat.co.uk/2010/08/speeding-up-ants-program.html"&gt;speeding up the Ants program&lt;/a&gt;).&lt;div class="blogger-post-footer"&gt;&lt;img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/5743983044224833668-6532671699357395376?l=www.fatvat.co.uk" alt="" /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a rel="nofollow" target="_blank" href="http://feedads.g.doubleclick.net/~a/SYTa-alngX0537RSFL9py2dpUOI/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/SYTa-alngX0537RSFL9py2dpUOI/0/di" border="0" ismap="ismap" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;a rel="nofollow" target="_blank" href="http://feedads.g.doubleclick.net/~a/SYTa-alngX0537RSFL9py2dpUOI/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/SYTa-alngX0537RSFL9py2dpUOI/1/di" border="0" ismap="ismap" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/fatvat/~4/9mXcgwnsS1s" height="1" width="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/clojure?a=AAYuhp_VrvM:oDNrAApy0Gg:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/clojure?a=AAYuhp_VrvM:oDNrAApy0Gg:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/clojure/~4/AAYuhp_VrvM" height="1" width="1"/&gt;</content>
		<author>
			<name>Jeff Foster</name>
			<uri>http://pipes.yahoo.com/pipes/pipe.info?_id=893ce799a0335da4ca871dc7c3ddb5c3</uri>
		</author>
		<source>
			<title type="html">Jeff Foster</title>
			<subtitle type="html">Pipes Output</subtitle>
			<link rel="self" href="http://pipes.yahoo.com/pipes/pipe.run?_id=893ce799a0335da4ca871dc7c3ddb5c3&amp;_render=rss" />
			<id>http://pipes.yahoo.com/pipes/pipe.run?_id=893ce799a0335da4ca871dc7c3ddb5c3&amp;_render=rss</id>
			<updated>2010-09-03T21:02:06+00:00</updated>
		</source>
	<feedburner:origLink>http://feedproxy.google.com/~r/fatvat/~3/9mXcgwnsS1s/ants-and-haskell.html</feedburner:origLink></entry>

	<entry>
		<title type="html">ClojureCLR</title>
		<link href="http://feedproxy.google.com/~r/clojure/~3/hihyo8aMQnY/clojureclr.html" />
		<id>tag:blogger.com,1999:blog-2977517373399006737.post-4983147121063600022</id>
		<updated>2010-08-27T10:06:45+00:00</updated>
		<content type="html">&lt;h3&gt;Installation (Getting to the REPL)&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;First off, you need Visual Studio. I’m doing this with 2008, but I’m pretty sure it would also work on 2010 and the relevant Express versions. I have doubts as to how well it would work with 2005 and am clearly not going to test it.&lt;br /&gt;&lt;br /&gt;Download ClojureCLR 1.1.0 from the &lt;a href="http://github.com/richhickey/clojure-clr/zipball/1.1.0"&gt;github page&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Follow the instructions &lt;a href="http://wiki.github.com/richhickey/clojure-clr/installing-clojureclr"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;If you have trouble with that, use these instructions. They worked for me:&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;Download ClojureCLR and unzip it somewhere&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Download the Dynamic Language Runtime: http://dlr.codeplex.com/&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Copy the unzipped folder into your Clojure parent directory if you want the Clojure solution to work out of the box. Rename it DLR_Main. Just to make this step clear, if your Clojure solution file is C:\dev\gukjoon-clojure\Clojure\ClojureCLR.sln, then you need to have DLR in C:\Dev\DLR_Main. The subfolders for that should be C:\Dev\DLR_Main\src and C:\Dev\DLR_Main\Samples.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Open the Clojure solution in the Clojure folder.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;For now, unload Clojure.Test from the solution.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;I had trouble with the post-build in Clojure.Main so I just took that out. If you do this, you will also have to copy the “clojure” folder from Clojure.Source into the output directory (“bin/Debug”) of Clojure.Main.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Run Clojure!&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Making a package to build external solutions&lt;/h3&gt;&lt;br /&gt;Installation is kind of a bitch with ClojureCLR, especially compared to Java Clojure. To help smooth over acceptance, I created a Clojure package that had all the Clojure binaries in it and two batch scripts that would use nant to build from target solutions and start a REPL with the target solutions loaded.&lt;br /&gt;&lt;br /&gt;First copy your bin/Debug directory into a folder somewhere. Then, get &lt;a href="http://nant.sourceforge.net/"&gt;nant&lt;/a&gt; and put that in the same directory.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://gist.github.com/523588"&gt;Bootstrap.build&lt;/a&gt;&lt;br /&gt;You’ll have to customize this nant build file for your solutions. You set a base directory for your solution (project.dir) and then can set up targets for each solution you have. I’m not very good with Nant so if you have recommendations for improving this buildfile, definitely let me know.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://gist.github.com/523589"&gt;BuildClojure.bat&lt;/a&gt;&lt;br /&gt;BuildClojure.bat runs the nant build file. It takes in an argument that it passes along to the nant build as the target. So depending on how you set up the nant build file, you could build specific solutions or all of them.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;RunClojure.bat&lt;/b&gt;&lt;br /&gt;RunClojure.bat is kind of worthless. It’s just one line: .\Clojure.Main.exe .\Startup.clj. I mostly have it because the Windows command prompt is a usability nightmare. I would much rather click to run Clojure.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://gist.github.com/523583"&gt;Startup.clj&lt;/a&gt;&lt;br /&gt;RunClojure.bat starts clojure with a startup script that loads all the assemblies you need. .NET classloading doesn’t work quite as well as Java so here I am loading the assemblies manually. You will want to change “Adc.*.dll” to something else, unless you also happen to work at AOL Advertising.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Generics&lt;/h3&gt;&lt;br /&gt;A big problem I came across was the lack of generics support in vanilla ClojureCLR. You actually need to pass in parameter types in .NET for generic types and methods and our legacy code was littered with generic types and methods. I didn’t really even need to create generics, just use them.&lt;br /&gt;&lt;br /&gt;It’s fairly easy to hack your way around this using reflection. However, I would advise against doing it the way I did:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://gist.github.com/523581"&gt;Clojure/CljCompiler/GenGeneric.cs&lt;/a&gt;&lt;br /&gt;&lt;a href="http://gist.github.com/523582"&gt;Clojure/CljCompiler/GenGenericMethod.cs&lt;/a&gt;&lt;br /&gt;&lt;a href="http://gist.github.com/523579"&gt;core-clr.clj additions&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I created two new classes to do the actual reflection, when you can totally do the whole thing in Clojure with interop. You probably should also put your clojure code in a separate file from the other core-clr functions. This is left as an exercise to the reader.&lt;br /&gt;&lt;br /&gt;If you choose to use this code, just add it into your solution in the appropriate places and recompile Clojure.Main and Clojure.Source (make sure to copy over clore-clr.clj.dll from the clojure directory in the Clojure.Source build.) gen-generic takes in a generic type, a vector of types and then arguments to the constructor. It will return an instance of the type. gen-generic-method takes in your callsite (either a type or an object,) the method as a String, a vector of types and arguments to the method.&lt;br /&gt;&lt;br /&gt;Since you still need to pass in a generic type  to the gen-generic function, you will have to use Type/getType to get the generic type from its string representation. In .NET the number of type parameters is reflected by a ` and then the number. For example, a list would be “System.Collections.Generic.List`1” and a dictionary would be “System.Collections.Generic.Dictionary`2.”&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;How I used it:&lt;/h3&gt;&lt;br /&gt;The problem I found with debugging any sort of object oriented code is that your control tends to be limited to an external interface. While the Visual Studio debugger is very helpful in narrowing down where your code is broken, the stubby fingers that C# (and Java, too) force on you make pinpointing irregular behavior harder than it needs to be. I believe that as a developer, no component of your system should be a black box if you don’t want it to be.&lt;br /&gt;&lt;br /&gt;My debugging usually works this way:&lt;br /&gt;1) Duplicate the bug in my dev environment, as described by QA&lt;br /&gt;2) Walk through the callstack to pinpoint the exact point where irregular behavior occurs&lt;br /&gt;3) Consistently duplicate this irregular behavior&lt;br /&gt;4) Figure out how to fix it.&lt;br /&gt;&lt;br /&gt;Any seasoned developer will tell you that 1-3 are far more difficult and time consuming than 4. Fixing shit is easy. Figuring out what to fix is hard. Furthermore, straight up exceptions tend to be easy to pinpoint using the Visual Studio debugger. The hard bugs to fix are ones that cause bad behavior without any overt exceptions.&lt;br /&gt;&lt;br /&gt;ClojureCLR is a tool for helping with 2-3 (sorry, you’re still shit out of luck for non-deterministic bugs that are impossible to duplicate) in finding “soft” bugs. You want to stand up individual components, test these components with inputs and see if you get the expected outputs. It’s far easier to do this on the fly in Clojure than writing a seperate program, compiling it and doing it.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Anyways, long story short: don’t use ClojureCLR unless you have to, but it is useful if you have to deal with .NET.&lt;div class="blogger-post-footer"&gt;&lt;img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/2977517373399006737-4983147121063600022?l=www.jierenchen.com" alt="" /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/clojure?a=hihyo8aMQnY:d_eAStql4ew:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/clojure?a=hihyo8aMQnY:d_eAStql4ew:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/clojure/~4/hihyo8aMQnY" height="1" width="1"/&gt;</content>
		<author>
			<name>Jieren Chen</name>
			<email>noreply@blogger.com</email>
			<uri>http://www.jierenchen.com/search/label/clojure</uri>
		</author>
		<source>
			<title type="html">No, the OTHER J. Chen.</title>
			<subtitle type="html">Code, music, math, and other stuff that daddy like.</subtitle>
			<link rel="self" href="http://www.jierenchen.com/feeds/posts/default/-/clojure" />
			<id>tag:blogger.com,1999:blog-2977517373399006737</id>
			<updated>2010-09-03T11:02:00+00:00</updated>
		</source>
	<feedburner:origLink>http://www.jierenchen.com/2010/08/clojureclr.html</feedburner:origLink></entry>

	<entry>
		<title type="html">Clojure JIT</title>
		<link href="http://feedproxy.google.com/~r/clojure/~3/v0hXLSjXKAA/clojure-jit.html" />
		<id>tag:blogger.com,1999:blog-2977517373399006737.post-3843702156011783344</id>
		<updated>2010-08-27T10:06:26+00:00</updated>
		<content type="html">Finally got off my ass and put my JIT gen-class implementation &lt;a href="http://www.jierenchen.com/feeds/posts/default/-/&lt;br /&gt;http://github.com/gukjoon/clojure-jit"&gt;&lt;br /&gt;http://github.com/gukjoon/clojure-jit"&gt;&lt;br /&gt;http://github.com/gukjoon/clojure-jit"&gt;&lt;br /&gt;http://github.com/gukjoon/clojure-jit"&gt;on github&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I need to fix things up a bit, but I'm having trouble getting the JIT compiled classes to play well with Hadoop, which was the whole point of writing this library anyways. So I'm going to solve that problem first.&lt;br /&gt;&lt;br /&gt;Anyways, enjoy!&lt;div class="blogger-post-footer"&gt;&lt;img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/2977517373399006737-3843702156011783344?l=www.jierenchen.com" alt="" /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/clojure?a=v0hXLSjXKAA:SViKE0rDrHw:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/clojure?a=v0hXLSjXKAA:SViKE0rDrHw:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/clojure/~4/v0hXLSjXKAA" height="1" width="1"/&gt;</content>
		<author>
			<name>Jieren Chen</name>
			<email>noreply@blogger.com</email>
			<uri>http://www.jierenchen.com/search/label/clojure</uri>
		</author>
		<source>
			<title type="html">No, the OTHER J. Chen.</title>
			<subtitle type="html">Code, music, math, and other stuff that daddy like.</subtitle>
			<link rel="self" href="http://www.jierenchen.com/feeds/posts/default/-/clojure" />
			<id>tag:blogger.com,1999:blog-2977517373399006737</id>
			<updated>2010-09-03T11:02:00+00:00</updated>
		</source>
	<feedburner:origLink>http://www.jierenchen.com/2010/08/clojure-jit.html</feedburner:origLink></entry>

	<entry xml:lang="en">
		<title type="html">A simple chat app using Aleph, Websockets and Clojure</title>
		<link href="http://feedproxy.google.com/~r/clojure/~3/2JpEclHeEms/" />
		<id>http://www.spyfoos.com/?p=116</id>
		<updated>2010-08-27T09:26:23+00:00</updated>
		<content type="html">&lt;p&gt;I implemented a small example shoving how to use the websocket support in &lt;a href="http://github.com/ztellman/aleph" target="_blank"&gt;Aleph&lt;/a&gt;, the asynchronous webframework for &lt;a href="http://clojure.org/" target="_blank"&gt;Clojure&lt;/a&gt; built on &lt;a href="http://www.jboss.org/netty" target="_blank"&gt;Netty&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;UPDATE: The example is tested with Chrome and Firefox on Ubuntu. It should work in all modern browsers as it rely on &lt;a href="http://github.com/gimite/web-socket-js/" target="_blank"&gt;web-socket-js&lt;/a&gt; for websocket emulation in browsers that do not have native support. Please note the updated Usage instructions. The socket-policy-server necessary for Flash websocket emulation has to listen on port 843 (at least that is the first place Flash asks for the policy file) the server has to be run using sudo.&lt;/p&gt;
&lt;p&gt;If you are interested the example is at hosted on &lt;a href="http://github.com/maacl/aleph-ws-test" target="_blank"&gt;github&lt;/a&gt;, along with usage instructions.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/clojure?a=2JpEclHeEms:DiU7GtECcak:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/clojure?a=2JpEclHeEms:DiU7GtECcak:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/clojure/~4/2JpEclHeEms" height="1" width="1"/&gt;</content>
		<author>
			<name>Martin Clausen</name>
			<uri>http://www.spyfoos.com</uri>
		</author>
		<source>
			<title type="html">Spyfoos' Speculations » clojure</title>
			<link rel="self" href="http://www.spyfoos.com/index.php/tag/clojure/feed/" />
			<id>http://www.spyfoos.com/index.php/tag/clojure/feed/</id>
			<updated>2010-08-31T15:30:14+00:00</updated>
		</source>
	<feedburner:origLink>http://www.spyfoos.com/index.php/2010/08/27/a-simple-chat-app-using-aleph-websockets-and-clojure/</feedburner:origLink></entry>

	<entry xml:lang="en">
		<title type="html">Today in the Intertweets (Aug 26th Ed)</title>
		<link href="http://feedproxy.google.com/~r/clojure/~3/7xBGQ8rHSGQ/" />
		<id>http://disclojure.org/?p=1123</id>
		<updated>2010-08-27T07:21:36+00:00</updated>
		<content type="html">&lt;ul&gt;
&lt;li&gt;How we Deploy our Clojure App (&lt;a href="http://asymmetrical-view.com/2010/08/26/how-were-deploying-our-clojure-applications.html"&gt;here&lt;/a&gt;, via @&lt;a href="http://twitter.com/kyleburton" rel="nofollow" target="_blank" title="View kyleburton's Twitter Profile"&gt;kyleburton&lt;/a&gt;) &amp;#8212; Automatically deploy a clojure webapp using &lt;a href="http://wiki.opscode.com/display/chef/Home"&gt;Chef&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Reusable method implementations for deftypes (&lt;a href="http://onclojure.com/2010/08/26/reusable-method-implementations-for-deftypes/"&gt;here&lt;/a&gt;, via @&lt;a href="http://twitter.com/planetclojure" rel="nofollow" target="_blank" title="View planetclojure's Twitter Profile"&gt;planetclojure&lt;/a&gt;) &amp;#8212; The new types in clojure 1.2 are very powerful, both in terms of their flexibility and their performance. Deftype allows you to create lean java classes from clojure. Records are deftypes extended to become first-class clojure citizens (e.g. map support, metadata support, etc&amp;#8230;) Currently there is no support for reusing method implementations in deftypes (i.e. reuse map support from records.) This article introduces the library &lt;a href="http://code.google.com/p/clj-methods-a-la-carte/"&gt;methods-a-la-carte&lt;/a&gt; that allows you to do just that.&lt;/li&gt;
&lt;li&gt;Get @&lt;a href="http://twitter.com/chrishouser" rel="nofollow" target="_blank" title="View chrishouser's Twitter Profile"&gt;chrishouser&lt;/a&gt;&amp;#8217;s top-selling &amp;#8220;The Joy of Clojure&amp;#8221; for 40% off using code s140 (until Sept 1) (&lt;a href="http://joyofclojure.com/buy"&gt;here&lt;/a&gt;, via @&lt;a href="http://twitter.com/fogus" rel="nofollow" target="_blank" title="View fogus's Twitter Profile"&gt;fogus&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Used my lunch break to update the Trammel docs with the new syntax (&lt;a href="http://fogus.me/fun/trammel/"&gt;here&lt;/a&gt;, via @&lt;a href="http://twitter.com/fogus" rel="nofollow" target="_blank" title="View fogus's Twitter Profile"&gt;fogus&lt;/a&gt;) &amp;#8212; &lt;a href="http://github.com/fogus/trammel"&gt;Trammel&lt;/a&gt; is a contracts programming library for Clojure that is WIP. Lately the syntax has changed quite a bit and this article introduces this new syntax.&lt;/li&gt;
&lt;li&gt;Follow-up to yesterday&amp;#8217;s post with some examples on using #&lt;a href="http://search.twitter.com/search?q=%23zeromq" rel="nofollow" target="_blank" title="Search Twitter for "&gt;zeromq&lt;/a&gt; to connect #&lt;a href="http://search.twitter.com/search?q=%23clojure" rel="nofollow" target="_blank" title="Search Twitter for "&gt;clojure&lt;/a&gt; to #&lt;a href="http://search.twitter.com/search?q=%23ruby" rel="nofollow" target="_blank" title="Search Twitter for "&gt;ruby&lt;/a&gt;! (&lt;a href="http://blog.trydionel.com/2010/08/26/using-0mq-for-clojure-and-ruby-interop/"&gt;here&lt;/a&gt;, via @&lt;a href="http://twitter.com/trydionel" rel="nofollow" target="_blank" title="View trydionel's Twitter Profile"&gt;trydionel&lt;/a&gt;) &amp;#8212; This is a follow-up to this article showing &lt;a href="http://blog.trydionel.com/2010/08/25/setting-up-0mq-for-clojure-on-osx/"&gt;how to connect to zeromq from Clojure&lt;/a&gt;, and it shows how to get Clojure and Ruby talking.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/disclojure?a=4DROuFILf8U:iRvhWg8wNVM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/disclojure?d=yIl2AUoC8zA" border="0" /&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/disclojure?a=4DROuFILf8U:iRvhWg8wNVM:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/disclojure?i=4DROuFILf8U:iRvhWg8wNVM:D7DqB2pKExk" border="0" /&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/disclojure?a=4DROuFILf8U:iRvhWg8wNVM:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/disclojure?i=4DROuFILf8U:iRvhWg8wNVM:V_sGLiPBpWU" border="0" /&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/disclojure?a=4DROuFILf8U:iRvhWg8wNVM:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/disclojure?i=4DROuFILf8U:iRvhWg8wNVM:gIN9vFwOqvQ" border="0" /&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/disclojure/~4/4DROuFILf8U" height="1" width="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/clojure?a=7xBGQ8rHSGQ:iRvhWg8wNVM:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/clojure?a=7xBGQ8rHSGQ:iRvhWg8wNVM:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/clojure/~4/7xBGQ8rHSGQ" height="1" width="1"/&gt;</content>
		<author>
			<name>Toni Batchelli</name>
			<uri>http://disclojure.org</uri>
		</author>
		<source>
			<title type="html">disclojure: all things clojure</title>
			<subtitle type="html">public disclosure of all things Clojure</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/disclojure" />
			<id>http://feeds.feedburner.com/disclojure</id>
			<updated>2010-09-03T08:30:53+00:00</updated>
		</source>
	<feedburner:origLink>http://feedproxy.google.com/~r/disclojure/~3/4DROuFILf8U/</feedburner:origLink></entry>

	<entry xml:lang="en">
		<title type="html">Using 0MQ for Clojure and Ruby Interop</title>
		<link href="http://feedproxy.google.com/~r/clojure/~3/p55vAvckmCQ/" />
		<id>http://blog.trydionel.com/?p=230</id>
		<updated>2010-08-27T00:32:13+00:00</updated>
		<content type="html">&lt;p&gt;Now that you have &lt;a href="http://blog.trydionel.com/2010/08/25/setting-up-0mq-for-clojure-on-osx/"&gt;ZeroMQ working with Clojure&lt;/a&gt;, some introductory examples are in order.  The demonstrations below show how simple it is to bridge the gap between programming languages by using ZeroMQ, focusing on connecting Clojure and Ruby.&lt;/p&gt;
&lt;h2&gt;Pub/Sub Pattern&lt;/h2&gt;
&lt;p&gt;Our first example is the &lt;a href="http://en.wikipedia.org/wiki/Publish/subscribe"&gt;pub/sub pattern&lt;/a&gt;.  Our code will broadcast messages from Ruby which our Clojure process can subscribe to.  One interesting capability of 0MQ is that we can subscribe to &amp;#8220;channels&amp;#8221; &amp;mdash; that is, we&amp;#8217;ll only receive messages which start with a given query.&lt;sup class="footnote"&gt;&lt;a href="http://blog.trydionel.com/tag/clojure/feed/#fn-230-1" id="fnref-230-1"&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;pre class="brush: ruby;"&gt;
#!/usr/bin/env ruby -wKU
# pub.rb
require 'rubygems'
require 'zmq'

zmq = ZMQ::Context.new
socket = zmq.socket(ZMQ::PUB)
socket.bind &amp;quot;tcp://127.0.0.1:5555&amp;quot;

# A REPL of sorts.  Messages entered here
# will get sent to our Clojure process.
while true
  '&amp;gt; '.display

  input = gets
  break unless input

  input.each do |msg|
    socket.send(msg)
  end
end

exit 0
&lt;/pre&gt;
&lt;pre class="brush: clojure;"&gt;
; src/my-project/sub.clj
(ns my-project.sub
  (:use [org.zeromq.clojure :as zmq]))

(defn- string-to-bytes [s] (.getBytes s))
(defn- bytes-to-string [b] (String. b))
(defn- on-thread [f]
  (doto (Thread. #^Runnable f)
    (.start)))

(defn launch-subscriber [query]
  (on-thread
   #((let [ctx (zmq/make-context 1)
	   socket (zmq/make-socket ctx zmq/+sub+)]
       (zmq/connect socket &amp;quot;tcp://127.0.0.1:5555&amp;quot;)
       ; Note the dot-syntax! clojure-zmq is a bit behind
       ; on the Java API, so you have to fall back to straight
       ; Java interop to subscribe to a pub &amp;quot;channel&amp;quot;.
       (.subscribe socket (string-to-bytes query))
       (while true
	 (println (bytes-to-string (zmq/recv socket))))))))

; Subscribing to the &amp;quot;foo&amp;quot; channel.  We'll only see messages prefixed with foo.
(launch-subscriber &amp;quot;foo&amp;quot;)
&lt;/pre&gt;
&lt;p&gt;After launching the Clojure process, hop into the shell:&lt;sup class="footnote"&gt;&lt;a href="http://blog.trydionel.com/tag/clojure/feed/#fn-230-2" id="fnref-230-2"&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;pre class="brush: bash;"&gt;
$ ruby pub.rb
&amp;gt; Hello There
# No entry in the Clojure output
&amp;gt; foo Hello There
# prints &amp;quot;foo Hello There&amp;quot; in the Clojure output
&lt;/pre&gt;
&lt;h2&gt;Request/Response Pattern&lt;/h2&gt;
&lt;p&gt;The request/response technique allows us to delegate work from our master program to a worker process.  In this particular example, we&amp;#8217;re sending lists of values from our Ruby process to our Clojure process, which adds them and sends back the result.&lt;/p&gt;
&lt;pre class="brush: ruby;"&gt;
#!/usr/bin/env ruby -wKU
# req.rb

require 'rubygems'
require 'zmq'

zmq = ZMQ::Context.new
socket = zmq.socket(ZMQ::REQ)
socket.bind &amp;quot;tcp://127.0.0.1:5556&amp;quot;

while true
  '&amp;gt; '.display

  input = gets
  break unless input

  input.each do |msg|
    socket.send(msg)
  end
  puts socket.recv
end

exit 0
&lt;/pre&gt;
&lt;pre class="brush: clojure;"&gt;
; src/my-project/rep.clj
(ns my-project.rep
  (:use [org.zeromq.clojure :as zmq])
  (:use [clojure.contrib str-utils]))

(defn- string-to-bytes [s] (.getBytes s))
(defn- bytes-to-string [b] (String. b))
(defn- on-thread [f]
  (doto (Thread. #^Runnable f)
    (.start)))

(defn handler [request]
  (let [request (bytes-to-string request)
	values (map
		#(Integer/parseInt %)
		(re-seq #&amp;quot;\d+&amp;quot; request))
	output (str (apply + values))]
    (println (apply
	      str
	      (str-join &amp;quot; + &amp;quot; values)
	      &amp;quot; = &amp;quot;
	      output))
    output))

(defn make-adder []
  (on-thread
   #((let [ctx (zmq/make-context 1)
	   socket (zmq/make-socket ctx zmq/+rep+)]
       (zmq/connect socket &amp;quot;tcp://127.0.0.1:5556&amp;quot;)
       (while true
	 (let [request (zmq/recv socket)
	       result (handler request)]
	   (zmq/send- socket (string-to-bytes result))))))))

(make-adder)
&lt;/pre&gt;
&lt;p&gt;Fire up the Clojure process, and hop back into the shell:&lt;/p&gt;
&lt;pre class="brush: bash;"&gt;
$ ruby req.rb
&amp;gt; 2 2
4
# The Clojure process will print &amp;quot;2 + 2 = 4&amp;quot;
&amp;gt; 8 8
16
# The Clojure process will print &amp;quot;8 + 8 = 16&amp;quot;
&lt;/pre&gt;
&lt;p&gt;You can find more ZeroMQ patterns on the &lt;a href="http://www.zeromq.org/docs:cookbook"&gt;official cookbook page&lt;/a&gt;.&lt;/p&gt;
&lt;div class="footnotes"&gt;
&lt;div class="footnotedivider"&gt;&lt;/div&gt;
&lt;ol&gt;
&lt;li id="fn-230-1"&gt;This could be useful for using 0MQ for method dispatch, e.g. this socket will accept &amp;#8220;add&amp;#8221; messages and sum the terms in a message, whereas another socket will accept &amp;#8220;log&amp;#8221; messages and log the message to file. &lt;span class="footnotereverse"&gt;&lt;a href="http://blog.trydionel.com/tag/clojure/feed/#fnref-230-1"&gt;&amp;#8617;&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li id="fn-230-2"&gt;If you launched the process through lein and swank-clojure, your output will appear in the console which started &lt;code&gt;lein swank&lt;/code&gt;. &lt;span class="footnotereverse"&gt;&lt;a href="http://blog.trydionel.com/tag/clojure/feed/#fnref-230-2"&gt;&amp;#8617;&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/clojure?a=p55vAvckmCQ:0yec4WKeEs0:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/clojure?a=p55vAvckmCQ:0yec4WKeEs0:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/clojure/~4/p55vAvckmCQ" height="1" width="1"/&gt;</content>
		<author>
			<name>Jeff Tucker</name>
			<uri>http://blog.trydionel.com</uri>
		</author>
		<source>
			<title type="html">spiral_code » clojure</title>
			<link rel="self" href="http://blog.trydionel.com/tag/clojure/feed/" />
			<id>http://blog.trydionel.com/tag/clojure/feed/</id>
			<updated>2010-08-28T02:31:27+00:00</updated>
		</source>
	<feedburner:origLink>http://blog.trydionel.com/2010/08/26/using-0mq-for-clojure-and-ruby-interop/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=using-0mq-for-clojure-and-ruby-interop</feedburner:origLink></entry>

	<entry xml:lang="en">
		<title type="html">Leiningen (unknown severity): lein doesn't fail gracefully without an Internet connection</title>
		<link href="http://feedproxy.google.com/~r/clojure/~3/ctpxZneBTPc/" />
		<id>http://github.com/technomancy/leiningen/issues/#issue/100</id>
		<updated>2010-08-27T00:00:00+00:00</updated>
		<content type="html">Leiningen (unknown severity): lein doesn't fail gracefully without an Internet connection&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/clojure?a=ctpxZneBTPc:wANc9sSJKgM:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/clojure?a=ctpxZneBTPc:wANc9sSJKgM:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/clojure/~4/ctpxZneBTPc" height="1" width="1"/&gt;</content>
		<author>
			<name>BugSpy</name>
			<uri>http://bugspy.net</uri>
		</author>
		<source>
			<title type="html">BugSpy.net - Reports By Tag: clojure</title>
			<link rel="self" href="http://bugspy.net/tag/clojure/?format=rss" />
			<id>http://bugspy.net/tag/clojure/?format=rss</id>
			<updated>2010-09-03T21:01:14+00:00</updated>
		</source>
	<feedburner:origLink>http://github.com/technomancy/leiningen/issues/#issue/100</feedburner:origLink></entry>

	<entry xml:lang="en">
		<title type="html">Leiningen (unknown severity): lein doesn't have an offline mode</title>
		<link href="http://feedproxy.google.com/~r/clojure/~3/uZFfnGXIUu4/" />
		<id>http://github.com/technomancy/leiningen/issues/#issue/101</id>
		<updated>2010-08-27T00:00:00+00:00</updated>
		<content type="html">Leiningen (unknown severity): lein doesn't have an offline mode&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/clojure?a=uZFfnGXIUu4:JoZMpA_qSIE:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/clojure?a=uZFfnGXIUu4:JoZMpA_qSIE:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/clojure/~4/uZFfnGXIUu4" height="1" width="1"/&gt;</content>
		<author>
			<name>BugSpy</name>
			<uri>http://bugspy.net</uri>
		</author>
		<source>
			<title type="html">BugSpy.net - Reports By Tag: clojure</title>
			<link rel="self" href="http://bugspy.net/tag/clojure/?format=rss" />
			<id>http://bugspy.net/tag/clojure/?format=rss</id>
			<updated>2010-09-03T21:01:14+00:00</updated>
		</source>
	<feedburner:origLink>http://github.com/technomancy/leiningen/issues/#issue/101</feedburner:origLink></entry>

	<entry>
		<title type="html">Clojure EMACS swank slime maven maven-clojure-plugin</title>
		<link href="http://feedproxy.google.com/~r/clojure/~3/dFyxP9lU3jQ/clojure-emacs-swank-slime-maven-maven.html" />
		<id>tag:blogger.com,1999:blog-7056990295646173627.post-4090112944109615469</id>
		<updated>2010-08-26T20:09:16+00:00</updated>
		<content type="html">&lt;span class="Apple-style-span"&gt;I've just had to set this up on a fresh install of ubuntu and it's all got very easy.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;Install maven:&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;b&gt;$sudo apt-get install maven2&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;Then create a &lt;b&gt;pom.x&lt;/b&gt;&lt;/span&gt;&lt;span class="Apple-style-span"&gt;&lt;b&gt;ml&lt;/b&gt; file to tell maven which repositories to use. There's an example below:&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;b&gt;$mvn clojure:swank&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;Will start a swank server with clojure and clojure-contrib 1.2 on the classpath.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;That's it from the clojure side.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;For emacs,&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;b&gt;$sudo apt-get install emacs&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;Then install the emacs lisp package archive (see&amp;nbsp;&lt;/span&gt;http://tromey.com/elpa/)&lt;br /&gt;&lt;br /&gt;by evaluating this code (cut and paste it into the scratch buffer, put the cursor in the middle, and use &lt;b&gt;M-C-x&lt;/b&gt;):&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;--emacs lisp to install elpa---------------&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="Apple-style-span"&gt;(let ((buffer (url-retrieve-synchronously&lt;br /&gt;        "http://tromey.com/elpa/package-install.el")))&lt;br /&gt;  (save-excursion&lt;br /&gt;    (set-buffer buffer)&lt;br /&gt;    (goto-char (point-min))&lt;br /&gt;    (re-search-forward "^$" nil 'move)&lt;br /&gt;    (eval-region (point) (point-max))&lt;br /&gt;    (kill-buffer (current-buffer))))&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;span class="Apple-style-span"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;---end of emacs lisp to install elpa-------------&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;Now use &lt;b&gt;M-x package-list-packages&lt;/b&gt; to bring up the list of packages, and use &lt;b&gt;i&lt;/b&gt; and then &lt;b&gt;x&lt;/b&gt;&amp;nbsp;to mark and then install&amp;nbsp;&lt;/span&gt;slime, slime-repl, and clojure-mode.&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;Then connect emacs to the already running clojure image with M-x slime-connect&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;That should be it. You should now be at a running clojure 1.2 repl inside emacs.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;-------------------------------------------------------------------------------------------------------------------------------&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;Here's an example of a pom.xml file that pulls in clojure and clojure-contrib 1.2 . Just cut and paste it.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;div&gt;As well as the essentials, I've also added the maven versions plugin, which helps with keeping everything cutting edge, and jline so that command line repls work better (mvn clojure:repl)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I like to have my startup repls conditioned a little, so if you have a startup script that you always want to run, add this snippet&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;configuration&amp;gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;replScript&amp;gt;startup.clj&amp;lt;/replScript&amp;gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;/configuration&amp;gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;to the clojuire-maven-plugin section so that when maven starts a repl, the code in startup.clj is loaded as the first action.&lt;br /&gt;&lt;br /&gt;-pom.xml----------------------------------------------------------------------------------------------------------------&lt;/div&gt;&lt;/div&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;!--      .xml_body {        color: #000000;        background-color: #ffffff;      }      .function-name {        /* font-lock-function-name-face */        color: #0000ff;      }      a {        color: inherit;        background-color: inherit;        font: inherit;        text-decoration: inherit;      }      a:hover {        text-decoration: underline;      }    --&gt;        &lt;br /&gt;&lt;pre class="xml_body"&gt;&amp;lt;&lt;span class="function-name"&gt;project&lt;/span&gt;&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;&lt;span class="function-name"&gt;modelVersion&lt;/span&gt;&amp;gt;4.0.0&amp;lt;/&lt;span class="function-name"&gt;modelVersion&lt;/span&gt;&amp;gt;&lt;br /&gt;  &amp;lt;&lt;span class="function-name"&gt;groupId&lt;/span&gt;&amp;gt;com.example&amp;lt;/&lt;span class="function-name"&gt;groupId&lt;/span&gt;&amp;gt;&lt;br /&gt;  &amp;lt;&lt;span class="function-name"&gt;artifactId&lt;/span&gt;&amp;gt;hello-maven-clojure-swank&amp;lt;/&lt;span class="function-name"&gt;artifactId&lt;/span&gt;&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;&lt;span class="function-name"&gt;version&lt;/span&gt;&amp;gt;1.0-SNAPSHOT&amp;lt;/&lt;span class="function-name"&gt;version&lt;/span&gt;&amp;gt;&lt;br /&gt;  &amp;lt;&lt;span class="function-name"&gt;name&lt;/span&gt;&amp;gt;hello-maven&amp;lt;/&lt;span class="function-name"&gt;name&lt;/span&gt;&amp;gt;&lt;br /&gt;  &amp;lt;&lt;span class="function-name"&gt;description&lt;/span&gt;&amp;gt;maven, clojure, emacs: together at last&amp;lt;/&lt;span class="function-name"&gt;description&lt;/span&gt;&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;&lt;span class="function-name"&gt;repositories&lt;/span&gt;&amp;gt;&lt;br /&gt;    &amp;lt;&lt;span class="function-name"&gt;repository&lt;/span&gt;&amp;gt;&lt;br /&gt;      &amp;lt;&lt;span class="function-name"&gt;id&lt;/span&gt;&amp;gt;clojars&amp;lt;/&lt;span class="function-name"&gt;id&lt;/span&gt;&amp;gt;&lt;br /&gt;      &amp;lt;&lt;span class="function-name"&gt;url&lt;/span&gt;&amp;gt;http://clojars.org/repo/&amp;lt;/&lt;span class="function-name"&gt;url&lt;/span&gt;&amp;gt;&lt;br /&gt;    &amp;lt;/&lt;span class="function-name"&gt;repository&lt;/span&gt;&amp;gt;&lt;br /&gt;    &amp;lt;&lt;span class="function-name"&gt;repository&lt;/span&gt;&amp;gt;&lt;br /&gt;      &amp;lt;&lt;span class="function-name"&gt;id&lt;/span&gt;&amp;gt;clojure&amp;lt;/&lt;span class="function-name"&gt;id&lt;/span&gt;&amp;gt;&lt;br /&gt;      &amp;lt;&lt;span class="function-name"&gt;url&lt;/span&gt;&amp;gt;http://build.clojure.org/releases&amp;lt;/&lt;span class="function-name"&gt;url&lt;/span&gt;&amp;gt;&lt;br /&gt;    &amp;lt;/&lt;span class="function-name"&gt;repository&lt;/span&gt;&amp;gt;&lt;br /&gt;    &amp;lt;&lt;span class="function-name"&gt;repository&lt;/span&gt;&amp;gt;&lt;br /&gt;      &amp;lt;&lt;span class="function-name"&gt;id&lt;/span&gt;&amp;gt;central&amp;lt;/&lt;span class="function-name"&gt;id&lt;/span&gt;&amp;gt;&lt;br /&gt;      &amp;lt;&lt;span class="function-name"&gt;url&lt;/span&gt;&amp;gt;http://repo1.maven.org/maven2&amp;lt;/&lt;span class="function-name"&gt;url&lt;/span&gt;&amp;gt;&lt;br /&gt;    &amp;lt;/&lt;span class="function-name"&gt;repository&lt;/span&gt;&amp;gt;&lt;br /&gt;  &amp;lt;/&lt;span class="function-name"&gt;repositories&lt;/span&gt;&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;&lt;span class="function-name"&gt;dependencies&lt;/span&gt;&amp;gt;&lt;br /&gt;    &amp;lt;&lt;span class="function-name"&gt;dependency&lt;/span&gt;&amp;gt;&lt;br /&gt;      &amp;lt;&lt;span class="function-name"&gt;groupId&lt;/span&gt;&amp;gt;org.clojure&amp;lt;/&lt;span class="function-name"&gt;groupId&lt;/span&gt;&amp;gt;&lt;br /&gt;      &amp;lt;&lt;span class="function-name"&gt;artifactId&lt;/span&gt;&amp;gt;clojure&amp;lt;/&lt;span class="function-name"&gt;artifactId&lt;/span&gt;&amp;gt;&lt;br /&gt;      &amp;lt;&lt;span class="function-name"&gt;version&lt;/span&gt;&amp;gt;1.2.0&amp;lt;/&lt;span class="function-name"&gt;version&lt;/span&gt;&amp;gt;&lt;br /&gt;    &amp;lt;/&lt;span class="function-name"&gt;dependency&lt;/span&gt;&amp;gt;&lt;br /&gt;    &amp;lt;&lt;span class="function-name"&gt;dependency&lt;/span&gt;&amp;gt;&lt;br /&gt;      &amp;lt;&lt;span class="function-name"&gt;groupId&lt;/span&gt;&amp;gt;org.clojure&amp;lt;/&lt;span class="function-name"&gt;groupId&lt;/span&gt;&amp;gt;&lt;br /&gt;      &amp;lt;&lt;span class="function-name"&gt;artifactId&lt;/span&gt;&amp;gt;clojure-contrib&amp;lt;/&lt;span class="function-name"&gt;artifactId&lt;/span&gt;&amp;gt;&lt;br /&gt;      &amp;lt;&lt;span class="function-name"&gt;version&lt;/span&gt;&amp;gt;1.2.0&amp;lt;/&lt;span class="function-name"&gt;version&lt;/span&gt;&amp;gt;&lt;br /&gt;    &amp;lt;/&lt;span class="function-name"&gt;dependency&lt;/span&gt;&amp;gt;&lt;br /&gt;    &amp;lt;&lt;span class="function-name"&gt;dependency&lt;/span&gt;&amp;gt;&lt;br /&gt;      &amp;lt;&lt;span class="function-name"&gt;groupId&lt;/span&gt;&amp;gt;jline&amp;lt;/&lt;span class="function-name"&gt;groupId&lt;/span&gt;&amp;gt;&lt;br /&gt;      &amp;lt;&lt;span class="function-name"&gt;artifactId&lt;/span&gt;&amp;gt;jline&amp;lt;/&lt;span class="function-name"&gt;artifactId&lt;/span&gt;&amp;gt;&lt;br /&gt;      &amp;lt;&lt;span class="function-name"&gt;version&lt;/span&gt;&amp;gt;0.9.94&amp;lt;/&lt;span class="function-name"&gt;version&lt;/span&gt;&amp;gt;&lt;br /&gt;    &amp;lt;/&lt;span class="function-name"&gt;dependency&lt;/span&gt;&amp;gt;&lt;br /&gt;    &amp;lt;&lt;span class="function-name"&gt;dependency&lt;/span&gt;&amp;gt;&lt;br /&gt;      &amp;lt;&lt;span class="function-name"&gt;groupId&lt;/span&gt;&amp;gt;swank-clojure&amp;lt;/&lt;span class="function-name"&gt;groupId&lt;/span&gt;&amp;gt;&lt;br /&gt;      &amp;lt;&lt;span class="function-name"&gt;artifactId&lt;/span&gt;&amp;gt;swank-clojure&amp;lt;/&lt;span class="function-name"&gt;artifactId&lt;/span&gt;&amp;gt;&lt;br /&gt;      &amp;lt;&lt;span class="function-name"&gt;version&lt;/span&gt;&amp;gt;1.2.1&amp;lt;/&lt;span class="function-name"&gt;version&lt;/span&gt;&amp;gt;&lt;br /&gt;    &amp;lt;/&lt;span class="function-name"&gt;dependency&lt;/span&gt;&amp;gt;&lt;br /&gt;  &amp;lt;/&lt;span class="function-name"&gt;dependencies&lt;/span&gt;&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;&lt;span class="function-name"&gt;build&lt;/span&gt;&amp;gt;&lt;br /&gt;    &amp;lt;&lt;span class="function-name"&gt;plugins&lt;/span&gt;&amp;gt;&lt;br /&gt;      &amp;lt;&lt;span class="function-name"&gt;plugin&lt;/span&gt;&amp;gt;&lt;br /&gt;         &amp;lt;&lt;span class="function-name"&gt;groupId&lt;/span&gt;&amp;gt;com.theoryinpractise&amp;lt;/&lt;span class="function-name"&gt;groupId&lt;/span&gt;&amp;gt;&lt;br /&gt;            &amp;lt;&lt;span class="function-name"&gt;artifactId&lt;/span&gt;&amp;gt;clojure-maven-plugin&amp;lt;/&lt;span class="function-name"&gt;artifactId&lt;/span&gt;&amp;gt;&lt;br /&gt;         &amp;lt;&lt;span class="function-name"&gt;version&lt;/span&gt;&amp;gt;1.3.3&amp;lt;/&lt;span class="function-name"&gt;version&lt;/span&gt;&amp;gt;&lt;br /&gt;      &amp;lt;/&lt;span class="function-name"&gt;plugin&lt;/span&gt;&amp;gt;&lt;br /&gt;      &amp;lt;&lt;span class="function-name"&gt;plugin&lt;/span&gt;&amp;gt;&lt;br /&gt;        &amp;lt;&lt;span class="function-name"&gt;groupId&lt;/span&gt;&amp;gt;org.codehaus.mojo&amp;lt;/&lt;span class="function-name"&gt;groupId&lt;/span&gt;&amp;gt;&lt;br /&gt;          &amp;lt;&lt;span class="function-name"&gt;artifactId&lt;/span&gt;&amp;gt;versions-maven-plugin&amp;lt;/&lt;span class="function-name"&gt;artifactId&lt;/span&gt;&amp;gt;&lt;br /&gt;        &amp;lt;&lt;span class="function-name"&gt;version&lt;/span&gt;&amp;gt;1.2&amp;lt;/&lt;span class="function-name"&gt;version&lt;/span&gt;&amp;gt;&lt;br /&gt;      &amp;lt;/&lt;span class="function-name"&gt;plugin&lt;/span&gt;&amp;gt;&lt;br /&gt;    &amp;lt;/&lt;span class="function-name"&gt;plugins&lt;/span&gt;&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;/&lt;span class="function-name"&gt;build&lt;/span&gt;&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/&lt;span class="function-name"&gt;project&lt;/span&gt;&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre class="xml_body"&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre class="xml_body"&gt;--------end of pom.xml&lt;/pre&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/7056990295646173627-4090112944109615469?l=learnclojure.blogspot.com" alt="" /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/clojure?a=dFyxP9lU3jQ:I47wrigfjO0:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/clojure?a=dFyxP9lU3jQ:I47wrigfjO0:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/clojure/~4/dFyxP9lU3jQ" height="1" width="1"/&gt;</content>
		<author>
			<name>John Lawrence Aspden</name>
			<email>noreply@blogger.com</email>
			<uri>http://learnclojure.blogspot.com/</uri>
		</author>
		<source>
			<title type="html">Learning Clojure</title>
			<link rel="self" href="http://learnclojure.blogspot.com/feeds/posts/default" />
			<id>tag:blogger.com,1999:blog-7056990295646173627</id>
			<updated>2010-08-30T06:00:17+00:00</updated>
		</source>
	<feedburner:origLink>http://learnclojure.blogspot.com/2010/08/clojure-emacs-swank-slime-maven-maven.html</feedburner:origLink></entry>

	<entry xml:lang="en">
		<title type="html">Reusable method implementations for deftypes</title>
		<link href="http://feedproxy.google.com/~r/clojure/~3/dTUQq03WjoI/" />
		<id>http://onclojure.com/?p=141</id>
		<updated>2010-08-26T14:55:51+00:00</updated>
		<content type="html">&lt;p&gt;One of the big new features in the recently released Clojure 1.2 is the possibility of defining new types having data field and implementing methods conforming to interfaces. Clojure provides two levels of user-defined types: the basic &lt;code&gt;deftype&lt;/code&gt;, for defining everything from scratch, and &lt;code&gt;defrecord&lt;/code&gt;, which adds method implementations for a couple of interfaces (some from Java, some from Clojure) that make the new type act like a Clojure map object.&lt;/p&gt;
&lt;p&gt;But what if you want something in between? For example, to make your type a good Clojure citizen, you want it to accept metadata (a feature provided by &lt;code&gt;defrecord&lt;/code&gt;), but you don&amp;#8217;t want all the map stuff. Or perhaps you want a map-like interface for the fields of your type, but without the possibility to extend the map with new keys. Clojure doesn&amp;#8217;t help you out of the box; your only choice is to re-implement the required interfaces yourself, or borrow the code from Clojure&amp;#8217;s &lt;code&gt;defrecord&lt;/code&gt;, if you are up to deciphering how it works. There is no way to &lt;em&gt;reuse&lt;/em&gt; method implementations.&lt;/p&gt;
&lt;p&gt;This also becomes a problem if you want to reuse your own method implementations. You&amp;#8217;d need to write your methods outside of any &lt;code&gt;deftype&lt;/code&gt;, possibly in a way that allows parametrization, and then insert the code into a &lt;code&gt;deftype&lt;/code&gt; form. You might be tempted to use macros for this, but that won&amp;#8217;t work: macros are expanded as part of the evaluation of forms, but inside a &lt;code&gt;deftype&lt;/code&gt; form, almost nothing gets evaluated. The only place where macros can be put to use inside a &lt;code&gt;deftype&lt;/code&gt; is inside the code of the individual methods.&lt;/p&gt;
&lt;p&gt;The library &lt;a href="http://code.google.com/p/clj-methods-a-la-carte/"&gt;methods-a-la-carte&lt;/a&gt; (also available at &lt;a href="http://clojars.org/methods-a-la-carte"&gt;clojars&lt;/a&gt;) comes to your rescue. It defines a templating system, similar in spirit to syntax-quote but with some important differences, that lets you define parametrized templates for methods and sets of methods. It also defines an enhanded version of &lt;code&gt;deftype&lt;/code&gt;, called &lt;code&gt;deftype+&lt;/code&gt;, which expands such templates inside its body. Finally, it comes with a small collection of predefined method implementations, corresponding to the features of defrecord but available individually.&lt;/p&gt;
&lt;p&gt;First, a simple example of a type that reuses just the metadata protocol implementation:&lt;/p&gt;
&lt;pre&gt;
(ns example
  (:use [methods-a-la-carte.core &lt;img src="http://s.wordpress.com/wp-includes/images/smilies/icon_surprised.gif" alt=":o" class="wp-smiley" /&gt; nly (deftype+)])
  (:use [methods-a-la-carte.implementations &lt;img src="http://s.wordpress.com/wp-includes/images/smilies/icon_surprised.gif" alt=":o" class="wp-smiley" /&gt; nly (metadata keyword-lookup)]))

(deftype+ foo
  [field1 field2 __meta]
  ~@(metadata __meta))

(def a-foo (with-meta (new foo 1 2) {:a :b}))
(prn (meta a-foo))
&lt;/pre&gt;
&lt;p&gt;This type has two plain fields (named rather unimaginatively &lt;code&gt;field1&lt;/code&gt; and &lt;code&gt;field2&lt;/code&gt;), and a special field &lt;code&gt;__meta&lt;/code&gt; for storing the metadata. This happens to be the name that Clojure&amp;#8217;s &lt;code&gt;defrecord&lt;/code&gt; uses for the metadata field, but this is unimportant. What &lt;em&gt;is&lt;/em&gt; important is that the name begins with a double underscore, as deftype handles such fields specially: they are omitted from the constructor argument list (to the best of my knowledge this is an undocumented feature of deftype).  Whatever name you choose, you have to give the same name as a parameter to the &lt;code&gt;metadata&lt;/code&gt; template.&lt;/p&gt;
&lt;p&gt;Let&amp;#8217;s add another feature to our type: keyword lookup:&lt;/p&gt;
&lt;pre&gt;
(deftype+ foo
  [field1 field2 __meta]
  ~@(metadata __meta)
  ~@(keyword-lookup field1 field2))

(def a-foo (new foo 1 2))
(prn (:field1 a-foo))
(prn (:field2 a-foo))
&lt;/pre&gt;
&lt;p&gt;The parameters to the template keyword-lookup are the field names for which you want keyword lookup. It can be any subset of the type&amp;#8217;s fields.&lt;/p&gt;
&lt;p&gt;By now you might be curious to know how the templates are defined, for example in order to define your own. Here&amp;#8217;s the metadata template, the simplest one in the collection:&lt;/p&gt;
&lt;pre&gt;
(defimpl metadata [fld]
  clojure.lang.IObj
  (meta [this#]
    ~fld)
  (withMeta [this# m#]
    (new ~this-type ~@(replace {'~fld 'm#} '~this-fields))))
&lt;/pre&gt;
&lt;p&gt;This template has one parameter, &lt;code&gt;fld&lt;/code&gt;, naming the field that stores the metadata. Everything after the parameter list is the content of the template, with a tilde standing for expressions that are replaced by their values, just as with syntax-quote templates. Another similarity with syntax-quote is that symbols ending with # are replaced by freshly generated unique symbols.&lt;/p&gt;
&lt;p&gt;There are two major differences between the new templating mechanism and the well-known syntax-quote:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Symbols are not namespace-resolved. This is important because, contrary to the use of templates in macro definition, namespace resolution is not appropriate for most of the symbols in a method template (method names, method arguments, interface and protocol names).&lt;/li&gt;
&lt;li&gt;Symbols are not looked up in the lexical environment (there is none), but first in a dynamic environment and then in the namespace of the template definition.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The dynamic environment is initialized by &lt;code&gt;deftype+&lt;/code&gt; with the following values:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;this-type&lt;/code&gt;: the symbol naming the type being defined&lt;/li&gt;
&lt;li&gt;&lt;code&gt;this-fields&lt;/code&gt;: the vector of field names supplied to &lt;code&gt;deftype+&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The above method template used both these values in its code for &lt;code&gt;withMeta&lt;/code&gt;. Here is what the first example (type foo with just the metadata implementation) expands to:&lt;/p&gt;
&lt;pre&gt;
(deftype
  foo
  [field1 field2 __meta]
  clojure.lang.IObj
  (meta [this#2515] __meta)
  (withMeta [this#2515 m#2516] (new foo field1 field2 m#2516)))
&lt;/pre&gt;
&lt;p&gt;As with all templating mechanism, including syntax-quote, the interplay of evaluation rules, substitution rules, and quoting requires some experience before it becomes to seem natural. Be prepared for some head-scratching as you write your first templates. Simply using them should be much easier, and probably sufficient for most users. Feedback welcome!&lt;/p&gt;
&lt;br /&gt;  &lt;a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/onclojure.wordpress.com/141/"&gt;&lt;img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/onclojure.wordpress.com/141/" /&gt;&lt;/a&gt; &lt;a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/onclojure.wordpress.com/141/"&gt;&lt;img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/onclojure.wordpress.com/141/" /&gt;&lt;/a&gt; &lt;a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/onclojure.wordpress.com/141/"&gt;&lt;img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/onclojure.wordpress.com/141/" /&gt;&lt;/a&gt; &lt;a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/onclojure.wordpress.com/141/"&gt;&lt;img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/onclojure.wordpress.com/141/" /&gt;&lt;/a&gt; &lt;a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/onclojure.wordpress.com/141/"&gt;&lt;img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/onclojure.wordpress.com/141/" /&gt;&lt;/a&gt; &lt;a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/onclojure.wordpress.com/141/"&gt;&lt;img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/onclojure.wordpress.com/141/" /&gt;&lt;/a&gt; &lt;a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/onclojure.wordpress.com/141/"&gt;&lt;img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/onclojure.wordpress.com/141/" /&gt;&lt;/a&gt; &lt;img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=onclojure.com&amp;blog=5872423&amp;post=141&amp;subd=onclojure&amp;ref=&amp;feed=1" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/clojure?a=dTUQq03WjoI:6FL3zrMyqPo:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/clojure?a=dTUQq03WjoI:6FL3zrMyqPo:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/clojure/~4/dTUQq03WjoI" height="1" width="1"/&gt;</content>
		<author>
			<name>khinsen</name>
			<uri>http://onclojure.com</uri>
		</author>
		<source>
			<title type="html">On Clojure</title>
			<subtitle type="html">A blog about everything Clojure</subtitle>
			<link rel="self" href="http://onclojure.com/feed/atom/" />
			<id>http://onclojure.com/feed/atom/</id>
			<updated>2010-08-26T15:00:08+00:00</updated>
		</source>
	<feedburner:origLink>http://onclojure.com/2010/08/26/reusable-method-implementations-for-deftypes/</feedburner:origLink></entry>

	<entry>
		<title type="html">stumbling towards the clojure api</title>
		<link href="" />
		<id>http://twoguysarguing.wordpress.com/?p=815</id>
		<updated>2010-08-26T13:39:34+00:00</updated>
		<content type="html">Here are two examples of code I&amp;#8217;ve written and re-written lately: My first example came about from dealing with DOM Document elements and Nodes, specifically getting a named attribute from a given Node: ;; bad, throws a NullPointerException if any of the Java methods return nil (defn get-attribute1 [elt attr] (.. elt getAttributes (getNamedItem attr) [...]&lt;img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=twoguysarguing.wordpress.com&amp;blog=6764274&amp;post=815&amp;subd=twoguysarguing&amp;ref=&amp;feed=1" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/clojure?a=Ro2eosQjYao:bH1sTqoEcQA:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/clojure?a=Ro2eosQjYao:bH1sTqoEcQA:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content>
		<author>
			<name>Two Guys Arguing</name>
			<uri>http://pipes.yahoo.com/pipes/pipe.info?_id=5fde276fa708d340f625fb5a72feab94</uri>
		</author>
		<source>
			<title type="html">Two Guys Arguing</title>
			<subtitle type="html">Pipes Output</subtitle>
			<link rel="self" href="http://pipes.yahoo.com/pipes/pipe.run?_id=5fde276fa708d340f625fb5a72feab94&amp;_render=rss" />
			<id>http://pipes.yahoo.com/pipes/pipe.run?_id=5fde276fa708d340f625fb5a72feab94&amp;_render=rss</id>
			<updated>2010-09-03T21:02:05+00:00</updated>
		</source>
	</entry>

	<entry>
		<title type="html">Sparse Matrices: infer, Clojure and the jvm</title>
		<link href="http://feedproxy.google.com/~r/clojure/~3/CytfgFH8BOs/sparse-matrices-infer-clojure-and-the-jvm.html" />
		<id>512307:5918186:8681695</id>
		<updated>2010-08-26T11:18:03+00:00</updated>
		<content type="html">&lt;p&gt;When we started &lt;a rel="nofollow" id="ihyv" title="infer" target="_blank" href="http://github.com/bradford/infer"&gt;Infer&lt;/a&gt;, and ran the first set of &lt;a rel="nofollow" id="ar03" title="matrix benchmarks"&gt;linear algebra benchmarks&lt;/a&gt;, we talked about the advantage of &lt;a rel="nofollow" id="x1kf" title="ujmp" target="_blank" href="http://www.ujmp.org/"&gt;UJMP&lt;/a&gt; in bringing other matrix packages onto the classpath and using UJMP's wrappers around them via a consistent API.&amp;nbsp; This turned out to be very helpful for benchmarking UJMP's native dense and sparse matrices against colt's, and parallel colt's.&lt;br /&gt;&lt;br /&gt;A special thanks to &lt;a rel="nofollow" id="cvy_" title="Holger Arndt" target="_blank" href="http://www.holger-arndt.com/"&gt;Holger Arndt&lt;/a&gt;, UJMP comitter, for help using the various sparse matrix implementations via UJMP and catching us up on the state of the art for jvm sparse matrix support.&lt;br /&gt;&lt;br /&gt;Holger shares the status for sparse matrices in UJMP:&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;matrix multiplication: full support&lt;/li&gt;
&lt;li&gt;add/subtract/times/divide: not optimized but working&lt;/li&gt;
&lt;li&gt;decomposition such as svd, inv, etc: treated as dense matrix&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;The DefaultSparseDoubleMatrix is UJMP's default implementation, which supports multi-dimensional sparse matrices and stores the entries in a HashMap of coordinate-value pairs.&lt;br /&gt;&lt;br /&gt;For two dimensions, this is not an optimal representation, so we test it out against ColtSparseDoubleMatrix2D and ParallelColtSparseDoubleMatrix2D, as well as the built in dense matrix operations.&lt;br /&gt;&lt;br /&gt;The only other libraries that I know of that support sparse matrix operations are MTJ (which, as Holger pointed out, only allows only immutable matrices) and Mahout, which can perform matrix multiplications and truncated svd on distributed disk-based sparse matrices.&amp;nbsp; We want to try this out in Infer, but distributed matrix operations is a later step - we want to find the best solution for in-memory sprase matrices first.&lt;br /&gt;&lt;br /&gt;Holger hypothesizes that for matrices of less than 5000x5000, we should probably be using UJMP's dense matrix implementation, as he thinks that it will be faster than Colt's or ParallelColt's sparse matrix.&amp;nbsp; We test this out below to see at what point sparse matrix operations are faster the dense.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Creating sparse matrices in Infer&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;To create a sparse matrix in Infer you just call sparse-matrix.&amp;nbsp; This creates a matrix backed by UJMP's DefaultSparseDoubleMatrix.&amp;nbsp; You pass it a seq of maps, where each map represents a row in the matrix, with the keys being the column indices, and the values being the entries in the matrix at the corresponding row and column index.&lt;/p&gt;
&lt;blockquote&gt;user&amp;gt; (use 'infer.matrix)&lt;br /&gt;nil&lt;br /&gt;user&amp;gt; (sparse-matrix [{0 1, 5 2, 9 3} {4 4, 9 5, 16 6}])&lt;br /&gt;&lt;/blockquote&gt;
&lt;p&gt;Then to get back to Clojure you can do:&lt;/p&gt;
&lt;blockquote&gt;user&amp;gt; (from-sparse-matrix (sparse-matrix [{0 1, 5 2, 9 3} {4 4,9 5, 16 6}]))&lt;br /&gt;&amp;gt; ([0 0 1.0] [0 5 2.0] [0 9 3.0] [1 4 4.0] [1 9 5.0] [1 16 6.0])&lt;br /&gt;&lt;/blockquote&gt;
&lt;p&gt;Notice that you get vectors of the available coordinates and the entry at that coordinate.&amp;nbsp; You can also get back the map representation for the 2d case.&lt;/p&gt;
&lt;blockquote&gt;user&amp;gt; (from-sparse-2d-matrix (sparse-matrix [{0 1, 5 2, 9 3} {4 4,9 5, 16 6}]))&lt;br /&gt;&amp;gt; ({0 1.0, 5 2.0, 9 3.0} {4 4.0, 9 5.0, 16 6.0})&lt;br /&gt;&lt;/blockquote&gt;
&lt;p&gt;You can also create sparse colt matrices and sparse parallel colt matrices.&lt;/p&gt;
&lt;blockquote&gt;user&amp;gt; (sparse-colt-matrix [{0 1, 5 2, 9 3} {4 4,9 5, 16 6}])&lt;br /&gt;user&amp;gt; (sparse-pcolt-matrix [{0 1, 5 2, 9 3} {4 4,9 5, 16 6}])&lt;br /&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;br /&gt;&lt;strong&gt;OK, now we're ready to do some benchmarks&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;We are benching UJMP dense matrices vs. UJMP built in default sparse matrices vs. colt sparse matrices vs. parallel colt sparse matrices.&lt;br /&gt;&lt;br /&gt;In order, the benchmarks below reflect the timings for the following fns from infer.matrix-bench in infer/test:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;bench-dense&lt;/li&gt;
&lt;li&gt;bench-sparse&lt;/li&gt;
&lt;li&gt;bench-sparse-colt&lt;/li&gt;
&lt;li&gt;bench-sparse-pcolt&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;infer.matrix-bench&amp;gt; (bench-all [10 times 100 1000 1000 100 0.01])&lt;br /&gt;"Elapsed time: 88.47919 msecs"&lt;br /&gt;"Elapsed time: 126.646131 msecs"&lt;br /&gt;"Elapsed time: 40.448648 msecs"&lt;br /&gt;"Elapsed time: 232.068246 msecs"&lt;br /&gt;&lt;br /&gt;infer.matrix-bench&amp;gt; (bench-all [10 times 1000 1000 1000 1000 0.01])&lt;br /&gt;"Elapsed time: 9330.419378 msecs"&lt;br /&gt;"Elapsed time: 1254.609118 msecs"&lt;br /&gt;"Elapsed time: 415.164851 msecs"&lt;br /&gt;"Elapsed time: 2351.761057 msecs"&lt;br /&gt;&lt;br /&gt;infer.matrix-bench&amp;gt; (bench-all [10 times 1000 10000 10000 1000 0.01])&lt;br /&gt;"Elapsed time: 115559.75808 msecs"&lt;br /&gt;"Elapsed time: 12666.080122 msecs"&lt;br /&gt;"Elapsed time: 4827.539895 msecs"&lt;br /&gt;"Elapsed time: 25237.850561 msecs"&lt;br /&gt;&lt;/blockquote&gt;
&lt;p&gt;This benchmark runs matrix multiplication (the "times" fn) 10 times, and the sparse matrices in the benchmark have 1% column sparsity.&amp;nbsp; In order to take advantage of sparsity, your matrix should be sufficiently sparse (probably &amp;lt;= 1% is a good start) and the dimensions of your matrix should be sufficiently large.&lt;br /&gt;&lt;br /&gt;We can see that we are generally taking advantage of sparsity already with 1000X1000 matrices, and colt sparse matrices are faster even for the 100X1000 case.&amp;nbsp; &lt;br /&gt;&lt;br /&gt;I've seen many times that parallel colt is slower, even on multiple cores.&amp;nbsp; It's strange.&amp;nbsp; I have no explination for this other than a guess that perhaps we need to configure things differently and it is currently just paying synchronization costs but not threading properly.&lt;br /&gt;&lt;br /&gt;Looking at SVD:&lt;/p&gt;
&lt;blockquote&gt;infer.matrix-bench&amp;gt; (bench-all [10 #(svd %2) 100 1000 1000 100 0.01])&lt;br /&gt;"Elapsed time: 3069.474062 msecs"&lt;br /&gt;"Elapsed time: 3000.594768 msecs"&lt;br /&gt;"Elapsed time: 1925.07847 msecs"&lt;br /&gt;"Elapsed time: 1923.685277 msecs"&lt;br /&gt;&lt;br /&gt;infer.matrix-bench&amp;gt; (bench-sparse-colt [10 #(svd %2) 1000 1000 1000 1000 0.01])&lt;br /&gt;; Evaluation aborted.&lt;br /&gt;infer.matrix-bench&amp;gt; (bench-sparse-colt 10 #(svd %2) 1000 1000 1000 1000 0.01)&lt;br /&gt;; Evaluation aborted.&lt;br /&gt;infer.matrix-bench&amp;gt; (bench-sparse-colt 10 #(svd %2) 100 10000 10000 100 0.01)&lt;br /&gt;"Elapsed time: 60045.680803 msecs"&lt;br /&gt;&lt;/blockquote&gt;
&lt;p&gt;We can see that the SVD is taking so long that we have kill it for 1000X1000 matrices, so we tried to just run the benchmark once rather than 10 times so we can tolerate it.&lt;/p&gt;
&lt;blockquote&gt;infer.matrix-bench&amp;gt; (bench-dense 1 #(svd %2) 1000 1000 1000 1000)&lt;br /&gt; "Elapsed time: 55596.25651 msecs"&lt;br /&gt;&lt;br /&gt;infer.matrix-bench&amp;gt; (bench-sparse-colt 1 #(svd %2) 1000 1000 1000 1000 0.01)&lt;br /&gt;"Elapsed time: 59941.746648 msecs"&lt;br /&gt;&lt;/blockquote&gt;
&lt;p&gt;So we can do 1 SVD on a 1000X1000 matrix with 1% of it's values populated in about 60 seconds.&amp;nbsp; This is not fast.&lt;br /&gt;&lt;br /&gt;To get some perspective, let's compare this with with the SVD of a 1000X1000 dense matrix in &lt;a rel="nofollow" id="a4dz" title="R" target="_blank" href="http://www.r-project.org/"&gt;R&lt;/a&gt; and &lt;a rel="nofollow" id="qund" title="NumPy" target="_blank" href="http://numpy.scipy.org/"&gt;NumPy&lt;/a&gt; on the same machine.&lt;br /&gt;&lt;br /&gt;First, in R.&lt;/p&gt;
&lt;blockquote&gt;&amp;gt; a &amp;lt;- matrix(rnorm(1000*1000), nrow=1000)&lt;br /&gt;&amp;gt; system.time(svd(a))&lt;br /&gt;&lt;br /&gt;user&amp;nbsp; system elapsed &lt;br /&gt;7.704&amp;nbsp;&amp;nbsp; 0.056&amp;nbsp;&amp;nbsp; 7.773&lt;br /&gt;&lt;/blockquote&gt;
&lt;p&gt;Then numpy.&lt;/p&gt;
&lt;blockquote&gt;&amp;gt;&amp;gt;&amp;gt; import numpy&lt;br /&gt;&amp;gt;&amp;gt;&amp;gt; import time&lt;br /&gt;&amp;gt;&amp;gt;&amp;gt; &lt;br /&gt;&amp;gt;&amp;gt;&amp;gt; a = numpy.random.random((1000,1000))&lt;br /&gt;&amp;gt;&amp;gt;&amp;gt; &lt;br /&gt;&amp;gt;&amp;gt;&amp;gt; t = time.time(); numpy.linalg.svd(a); print time.time() - t&lt;br /&gt;&lt;br /&gt;7.57887601852&lt;br /&gt;&lt;/blockquote&gt;
&lt;p&gt;So we see that the java SVD implementations are about 10X slower than what is achievable in R or NumPy.&amp;nbsp; This makes us want to explore better decompositions in Infer.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Conclusions and next steps&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;You can see that you start to get performance enhancements from sparse multiplications with pretty small dimensions as long as your matrices have sufficient sparsity.&amp;nbsp; The colt sparse matrix is as fast as it gets on the jvm, and you can create these with sparse-colt-matrix, and the matrix operations will work on them just as with any other Infer matrix (wrapping UJMP matrices).&lt;br /&gt;&lt;br /&gt;SVD performance is disappointing in general, and is something we plan to look into implementing in Java ourselves.&lt;br /&gt;&lt;br /&gt;Thanks again to to for &lt;a rel="nofollow" id="kxbv" title="Holger Arndt" target="_blank" href="http://www.holger-arndt.com/"&gt;Holger Arndt&lt;/a&gt; for help with UJMP&amp;nbsp; and understanding the state of sparse matrices on the jvm, and to &lt;a rel="nofollow" id="fgks" title="Hamilton Ulmer" target="_blank" href="http://twitter.com/hamiltonulmer"&gt;Hamilton Ulmer&lt;/a&gt; for pairing with me on sparse matrices in Infer.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/clojure?a=CytfgFH8BOs:D3hjccZlDeo:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/clojure?a=CytfgFH8BOs:D3hjccZlDeo:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/clojure/~4/CytfgFH8BOs" height="1" width="1"/&gt;</content>
		<author>
			<name>Bradford Cross</name>
			<uri>http://pipes.yahoo.com/pipes/pipe.info?_id=bb5649628a7f97318cb84845387521ef</uri>
		</author>
		<source>
			<title type="html">Bradford Cross&amp;amp;#39;s Clojure posts</title>
			<subtitle type="html">Pipes Output</subtitle>
			<link rel="self" href="http://pipes.yahoo.com/pipes/pipe.run?_id=bb5649628a7f97318cb84845387521ef&amp;_render=rss" />
			<id>http://pipes.yahoo.com/pipes/pipe.run?_id=bb5649628a7f97318cb84845387521ef&amp;_render=rss</id>
			<updated>2010-09-03T21:02:07+00:00</updated>
		</source>
	<feedburner:origLink>http://measuringmeasures.com/blog/2010/8/26/sparse-matrices-infer-clojure-and-the-jvm.html</feedburner:origLink></entry>

	<entry xml:lang="en">
		<title type="html">Best In Class: Developer Productivity - The Red Pill</title>
		<link href="http://feedproxy.google.com/~r/clojure/~3/XIdmm-ODCy8/developer-productivity--the-red-pill.html" />
		<id>http://www.bestinclass.dk/index.clj/2010/08/developer-productivity--the-red-pill.html</id>
		<updated>2010-08-26T10:19:22+00:00</updated>
		<content type="html">&lt;h1&gt;
	Preface&lt;/h1&gt;
&lt;p&gt;
	"&lt;em&gt;I know why you're here. I know what you've been doing... why you hardly sleep, why you live alone, and why night after night, you sit by your computer. You're looking for, it I know because I was once looking for the same thing. And when I found it, I knew what I'd been searching for. I was looking for an answer. It's the question that drives us. It's the question that brought you here. You know the question, just as I did.&lt;/em&gt;"                        --- &lt;strong&gt;The (sorta) Matrix&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;
	Last time I blogged, I had just returned from the first &lt;strong&gt;Conj Labs in Brussels&lt;/strong&gt; and coincidentally I've been tied up with Clojure development, so that now just as we open registrations for &lt;a href="http://conj-labs.eu" target="_blank"&gt;Conj Labs Frankfurt&lt;/a&gt; am I able to blog again. My last blogpost was meant as an inspiration to adapt your work environment to make you the most productive - I purposely didn't move into the 'how' as I just wanted to get people interested. It worked it seems so now I'm back to wrap up the series with some productivity tips as well as configs.&lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;h1&gt;
	Top 10 Productivity Boosters&lt;/h1&gt;
&lt;p&gt;
	&lt;sup&gt;(by request)&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;p&gt;
	I've tried to think about some of the deliberate choices I've made to function better in my job, but Im sure your mileage will vary.&lt;/p&gt;
&lt;h3&gt;
	1. Get around 7 hours of sleep every single night&lt;/h3&gt;
&lt;p&gt;
	If your sleep isn't good you will suffer mentally and energywise. Catching up on a bad nights sleep is trickier than it sounds, so the key is to stick to a routine.&lt;/p&gt;
&lt;h3&gt;
	2. Avoid caffeine entirely (coffee &amp;amp; tea)&lt;/h3&gt;
&lt;p&gt;
	Ive been a long time coffee drinker (&lt;strong&gt;read&lt;/strong&gt;: bottomless coffee pit), but after I returned from Conj Labs Brussels I considered the effect of the caffeine in my system and how I got up in the morning and felt like I was in a daze until I got my first cup. Taking that thought further I reasoned that after having slept through the first 2 hours of the night, the next 5 would be spent by my body craving the next cup, which was how I would wake up. Since I only have 2 settings (off or on) I quit coffee over night, cold turkey. It took 3 - 4 days before I mentally was on top again, but it took &lt;strong&gt;14 days&lt;/strong&gt; for the headaches to go away (they were &lt;u&gt;&lt;strong&gt;bad&lt;/strong&gt;&lt;/u&gt;). Now that its over and done with Im not touching that stuff again, Im mentally alert and sharp from the moment I roll out of bed till I get back in - No additives needed!&lt;/p&gt;
&lt;h3&gt;
	3. Maintain your tools&lt;/h3&gt;
&lt;p&gt;
	What good is a lumberjack who doesn't sharpen his axe? Only a little more than a developer who doesn't exercise his body. In our younger years most of us felt immortal, nothing we ever did gave us any lasting marks despite our parents warnings (at least I hope you were as fortunate as me), but as we grow older it becomes clear that the years take their toll. Lack of exercise is a killer - You'll feel it in your bones, when typing, in your energy levels, in your ability to focus - Everything works better if you maintain your primary tool: Your body. Personally I try to work in some exercise either into my lunch-break or in the evening - It takes a little time, but its worth it.&lt;/p&gt;
&lt;h3&gt;
	4. Dont be vain&lt;/h3&gt;
&lt;p&gt;
	In all honesty, one of the reasons I wanted to try out Linux way back when, was because of some of the Compiz/Beryl visual effects for the desktop - this is vanity. One of my friends recently saw my desktop (in all its Awesome Emacsy splendor) and his comment was "upgrade that ****" because he didn't feel that it was as pretty as his new Windows 7 installation, which it isn't. But in the time he has booted to his Desktop I've already answered 3 emails, said good morning on #clojure and written my first few lines of code - Vanity slows you down, whether its your choice of VM, OS (read: OSX or Windows) or anything else - If you want to be productive, aim for productivity not prettiness.&lt;/p&gt;
&lt;h3&gt;
	5. Avoid Social Networks&lt;/h3&gt;
&lt;p&gt;
	One of the strongest weapons for building quality systems is the ability to concentrate over prolonged periods of time. If you get regular Facebook updates, Twitter updates, or any other kind of updates which steals your attention, even if its just for a few seconds, I'm willing to bet that you're working at 50% of your full capacity. Why? Because even though it takes you 5 seconds to read a twitter update, I'm guessing it takes you 5 minutes to regain full mental focus. If your updates are coming in at a rate around 1 update every 5 minutes you're never running at full speed. If you are connected to something like twitter, &lt;a href="http://twitter.com/laujensen" target="_blank"&gt;which I am&lt;/a&gt;, I recommend that you check it once in a while - I do it in the morning or evening, but typically not during the day - and not every day. There are 2 exceptions: If my phone rings or if I get an email I usually reply ASAP whenever possible, since customers shouldn't have to wait.&lt;/p&gt;
&lt;h3&gt;
	6. Work off a TODO list&lt;/h3&gt;
&lt;p&gt;
	I showed this in my last screencast as well, how I organize my TODO bullets into categories A, B or C. A means 'will loose significant value if not done today', B means 'important, but will not loose significant value if not done today', C means 'optional'. I cannot stress how important this bullet is - On its own it might overshadow the other 9 in the short-term. When working as a Project Manager I have seen several developers who select some minor task to work on, and everytime they reach a milestone they look around, not knowing what to do, then start reading online newspapers or chit-chatting. Sure there's a time and a place for that, but if you're doing it consistently everytime you've put down 50 lines of code, you have a problem. Working off a TODO list means, that when you're in need of a high level of productivity you cross one item off the list and move on to the next! For many developers, huge wins in terms of productivity are available when the downtime between 2 tasks is cut out.&lt;/p&gt;
&lt;h3&gt;
	7. Use a tiling WM&lt;/h3&gt;
&lt;p&gt;
	If you're not on a tiling WM, you're constantly switching between the mouse and keyboard. Everytime you want to click an item with the mouse you have to find it visually, take aim, click, maybe miss, click again. In most cases you hit the first time, but you've wasted time context switching and taking aim. When I was younger I had shoulder/neck pains which I think came from using the mouse too much - These days I never have pains.&lt;/p&gt;
&lt;h3&gt;
	8. Use Emacs for Everything&lt;/h3&gt;
&lt;p&gt;
	This was a central theme in my &lt;a href="http://bestinclass.dk/index.clj/2010/07/trail-blazing-innovators.html" target="_blank"&gt;last blogpost&lt;/a&gt;: Integrate as much as you can into Emacs: Code editing, HTML editing, Emailing, reading Twitter streams, file management, Git integration, Day planning and whatever else you can think of. Have a uniform interface and heavy integration between your tools speeds you up enormously.&lt;/p&gt;
&lt;h3&gt;
	9. ...Use Conkeror for the rest&lt;/h3&gt;
&lt;p&gt;
	Whether you like it or not, you probably spend quite a bit of time in a webbrowser - Either finding javadocs, searching for libraries or something similar. When I switched from Chrome to &lt;a href="http://www.conkeror.org" target="_blank"&gt;Conkeror&lt;/a&gt; my ability to browse became almost equal to my ability to read and think. As soon as I could think of which link to click, the page was already loading - Thats the power of a keyboard-based browser, why settle for less?  (&lt;em&gt;preemptive strike&lt;/em&gt;: Some would argue that the lack of Firebug integration etc, would be an argument for not using Conkeror, but notice I said use it for 'browsing', I use many different browsers for debugging/testing)&lt;/p&gt;
&lt;h3&gt;
	10. Always keep looking&lt;/h3&gt;
&lt;p&gt;
	I didn't start out with neither Arch, Awesome or Emacs, but a continual focus on optimizing my tools eventually got me here - Who knows where I'll be in 10 years. Right now Im trying to learn the NEO keyboard layout, because Im told it greatly reduces the distance your fingers have to travel when typing, thus speeding you up and minimizing the risk of getting RSI.&lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;h2&gt;
	DISCLAIMER&lt;/h2&gt;
&lt;p&gt;
	You might be thinking after reading the above, that Im a sadistic terminator who is determined to run my colleaguees/employees into the ground, sweating, sobbing, broken. Nothing could be further from the truth. The truth is, &lt;strong&gt;relax time is important and fun time is important&lt;/strong&gt;. But I find that I can enjoy all of these the most if I've put in a good amount of work first. So if I am going to work for something like 3 - 4 hours in a row, doesn't it make sense to make those hours as productive as possible without wrecking yourself trying to cut down on breaks, sleep, family time and what not? I think a lot of the common problems that developers struggle with after years in the field can be avoided by adapting the techniques above, but as always I welcome input.&lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;h1&gt;
	Watch out for the pitfall&lt;/h1&gt;
&lt;p&gt;
	So what to do, when you've applied all of the above tips and your back is still against the wall timewise. Those who have the resources in terms of colleagues or coworkers tend to try and delegate. Delegation can be like taking a loan to buy something which you really cant afford: It comes back and bites you and ends up costing more than you wanted to pay. Why?&lt;/p&gt;
&lt;p&gt;
	I think primarily because people don't delegate intelligently enough. I recognize two kinds of delegation: Gopher Delegation and Delegation:&lt;/p&gt;
&lt;h3&gt;
	Distinguishing&lt;/h3&gt;
&lt;p&gt;
	Gopher delegation is the type of delegation that sounds like 'please go to this store, pick up these 3 items, come back and put them on the table in the cantina, arrange the plates, forks and glasses around the table, evenly distributed in the exact amount of people attending the lunch meeting'. This type of delegation is in stark contrast to true delegation which sounds like 'Please make the necessary preparations for our lunch meeting at 12:00'. The key thing to learn, is that &lt;strong&gt;gophers need gopher delegation&lt;/strong&gt; and &lt;strong&gt;trusted employees/colleagues need regular delegation&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;
	In the above example, the gopher given the first task would probably forget the knives - he was only asked to get forks and since the entire task had been nicely cut out into smaller tasks he felt no responsibility to go above and beyond, he simply follows orders. For gophers, this is what you want, fortunately there aren't too many of them.&lt;/p&gt;
&lt;p&gt;
	The trusted employee might feel free to pick up more than the 3 items, might clean the table, or apply any number of improvements to your original plan (which he wasn't told) because he feels its his task and his responsebility to work out a great solution. For &lt;a href="http://conj-labs.eu" target="_blank"&gt;Conj Labs&lt;/a&gt; we work out a number of lab exercises in advance of the course. Imagine I was to ask &lt;a href="http://twitter.com/cgrand" target="_blank"&gt;Christophe&lt;/a&gt; to prepare such a lab. Would I get the best result by telling him exact scope of the exercise, where to inject explanatory slides, which functions to use, etc etc? Or would it be better to say &lt;strong&gt;'Christophe, I would love a lab on DSLs can you try to come up with something?&lt;/strong&gt;' - Let me tell you, he has not yet failed to surprise me :)&lt;/p&gt;
&lt;p&gt;
	In the past I have been bit by delegating important tasks to gophers without being clear enough, and Im sure I have choked trusted employees creativity and intelligence by being too specific - Both are enormous errors where delegations ends up being a pain instead of giving you some freedom with your time. But now for the practical stuff:&lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;h1&gt;
	Emacs keys worth knowing:&lt;/h1&gt;
&lt;p&gt;
	I promised to list some of my most used keyboard bindings, so I've asked my fingers and here is the result. Since this is almost an inexhaustable topic, I'll keep it brief and open up the comments section :)&lt;/p&gt;
&lt;h3&gt;
	Small helpers&lt;/h3&gt;
&lt;p&gt;
	Zap-To-Char (M-z): Kills all characters up to and &lt;em&gt;including&lt;/em&gt; the one you supply as an argument&lt;/p&gt;
&lt;p&gt;
	Recenter (C-l): Try hitting it 3 times and see what happens each time (that's C-lower-case L)&lt;/p&gt;
&lt;p&gt;
	Query-replace (M-%): Regex replace, (y to replace, n to skip, ! to replace all, works on regions as well)&lt;/p&gt;
&lt;p&gt;
	Goto line (M-g g): Jumps to a specific line&lt;/p&gt;
&lt;h3&gt;
	These three guys go together and I use them constantly for rearranging text:&lt;/h3&gt;
&lt;p&gt;
	Kill-Line (C-k): Kills an entire line&lt;/p&gt;
&lt;p&gt;
	Kill-Region (C-w): Kills a region (region: Selected area)&lt;/p&gt;
&lt;p&gt;
	Kill-Ring-Save (M-w): Copies a region to the clipboard&lt;/p&gt;
&lt;p&gt;
	Paste-Ring (C-y): Pastes whatevers in the kill-ring&lt;/p&gt;
&lt;p&gt;
	Paste-again (M-y): Keeps replacing what you just pasted with the next item in the kill ring&lt;/p&gt;
&lt;h3&gt;
	For repetitive tasks, these are a must&lt;/h3&gt;
&lt;p&gt;
	record-macro-start (C-x (): Records all keystrokes until you stop recording&lt;/p&gt;
&lt;p&gt;
	record-macro-end (C-x )): Stops recording&lt;/p&gt;
&lt;p&gt;
	play-macro (C-x e): Plays the last recorded macro&lt;/p&gt;
&lt;p&gt;
	play-macro-on-region (C-x C-k r): Play its only on the selected region&lt;/p&gt;
&lt;p&gt;
	play-macro-n-times (C-u 10 C-x e): Plays the macro 10 times&lt;/p&gt;
&lt;p&gt;
	save-macro-with-name (C-x C-k n): Give it a name, refer to it later&lt;/p&gt;
&lt;p&gt;
	M-x insert-kbd-macro: Lets you save the Lisp code of your macro for use in future sessions&lt;/p&gt;
&lt;h3&gt;
	Optimizations&lt;/h3&gt;
&lt;p&gt;
	M-x paredit: Will disable paredit if you enabled it by accident&lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;h1&gt;
	Configs&lt;/h1&gt;
&lt;p&gt;
	I've put my configs on &lt;a href="http://github.com/LauJensen/Configs" target="_blank"&gt;Github&lt;/a&gt; - I dont plan on updating them, so they are there now and can be used as inspiration.&lt;/p&gt;
&lt;h3&gt;
	Emacs:&lt;/h3&gt;
&lt;p&gt;
	Nothing too special here. There's my swank setup, which has a very customized classpath, this is the times where I want to fiddle or contribute to some project - Most of my development goes on after calling M-x swank-clojure-project. If someone is pinging me in #clojure I hit F12 which makes the channel fullscreen, and once Im done I hit F12 again and the original window configuration is restored completely. At the very bottom Ive added some repos to technomancys new version of ELPA, which I never finished testing (sorry).&lt;/p&gt;
&lt;h3&gt;
	Awesome (rc.lua): The awesome config (rc.lua) is looted from anrxc (#archlinux)&lt;/h3&gt;
&lt;p&gt;
	This setup will likely save you half a lifetime - Installing Awesome takes a few seconds but configuring your way out of the lua madness (indices start at 1) takes quite some time. Thankfully #archlinux is a good place to get help. There's nothing too specific about this setup, except for when you hit M-q then a small Emacs-Orgmode-Remember window pops up, which allows you to quickly take notes. This feature wont work unless you use (parts of) my emacs config and you need to change a few paths. Finally, your battery is most likely not named as mine, so to get battery stats in the top bar fix the string on line 50 in /awesome/vicious/bat.lua. The entire config goes into ~/.config/awesome. (yes I know its ridicously hacky, I love using Awesome, not configuring it)&lt;/p&gt;
&lt;h3&gt;
	Wanderlust:&lt;/h3&gt;
&lt;p&gt;
	There are several Email applications for Emacs - They all suck, Wanderlust sucks the least. I use Wanderlust sporadically for sending emails and also for reading emails - I do however always keep a thunderbird icon in the tray to alert me to new emails, as this is one of the (many?) bugs of Wanderlusts IMAP integration - It doesn't notify you of new emails. Word of caution: If you subscribe to the Wanderlust ML, you can only unsubscribe by sending an email from within Wanderlust - Not knowing this, cause a little pain and a lot of flame. When they get the bugs ironed out, I might switch 100% to a fetchmail/wanderlust combo but its not quite ready yet.&lt;/p&gt;
&lt;p&gt;
	Note, that when you're composing an email, hit C-h to convert it to HTML using org-mode-htmlize.&lt;/p&gt;
&lt;p&gt;
	You can find the files: &lt;a href="http://github.com/LauJensen/Configs" target="_blank"&gt;here&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;h1&gt;
	Conclusion&lt;/h1&gt;
&lt;p&gt;
	Its important to be productive - I see it as driving a car where there's no speedlimits, why not see how fast it can go? I hope I was able to inspire some of you to revisit your setup and to start asking the question &lt;em&gt;&lt;strong&gt;"How productive can we become?"&lt;/strong&gt;&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;
	There's of course a final very definite way to be more productive and that is to use a screwdriver for screws instead of hammer, and to use Clojure for development of quality software. If you would like to learn more about Clojure and how to use it professionally, I'll recommend you to join us at the next installment of &lt;a href="http://conj-labs.eu" target="_blank"&gt;Conj Labs&lt;/a&gt; - This time in &lt;strong&gt;Frankfurt, Germany&lt;/strong&gt;. Once again I'm teaming up with the fantastic &lt;a href="http://twitter.com/cgrand" target="_blank"&gt;Christophe Grand&lt;/a&gt; (author of &lt;strong&gt;Enlive&lt;/strong&gt; and &lt;strong&gt;Moustache&lt;/strong&gt;) to provide 3 days of Clojure training - We hope to see you there. As a new thing, we have acquired the help of &lt;a href="http://innoq.com" target="_blank"&gt;InnoQ&lt;/a&gt; who are helping us in spreading the word, so we hope to see many Germans (as well as foreigners) there.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/oeHtrE6n_3Ftxu8cpD_UC8FODbQ/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/oeHtrE6n_3Ftxu8cpD_UC8FODbQ/0/di" border="0" ismap="true" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/oeHtrE6n_3Ftxu8cpD_UC8FODbQ/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/oeHtrE6n_3Ftxu8cpD_UC8FODbQ/1/di" border="0" ismap="true" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/bestinclass-the-blog?a=Y0Epj5mnVQI:pQ7YHmfXAsY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bestinclass-the-blog?d=yIl2AUoC8zA" border="0" /&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bestinclass-the-blog?a=Y0Epj5mnVQI:pQ7YHmfXAsY:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bestinclass-the-blog?d=7Q72WNTAKBA" border="0" /&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bestinclass-the-blog?a=Y0Epj5mnVQI:pQ7YHmfXAsY:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bestinclass-the-blog?i=Y0Epj5mnVQI:pQ7YHmfXAsY:gIN9vFwOqvQ" border="0" /&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/bestinclass-the-blog/~4/Y0Epj5mnVQI" height="1" width="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/clojure?a=XIdmm-ODCy8:Y0Epj5mnVQI:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/clojure?a=XIdmm-ODCy8:Y0Epj5mnVQI:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/clojure/~4/XIdmm-ODCy8" height="1" width="1"/&gt;</content>
		<author>
			<name>Lau Jensen</name>
			<email>lau.jensen@bestinclass.dk</email>
			<uri>http://www.bestinclass.dk</uri>
		</author>
		<source>
			<title type="html">Best In Class Atom Feed</title>
			<subtitle type="html">Best In Class - Software Innovator</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/bestinclass-the-blog" />
			<id>tag:www.bestinclass.dk,2010-01-01:/atom.xml</id>
			<updated>2010-08-26T10:31:17+00:00</updated>
		</source>
	<feedburner:origLink>http://feedproxy.google.com/~r/bestinclass-the-blog/~3/Y0Epj5mnVQI/developer-productivity--the-red-pill.html</feedburner:origLink></entry>

	<entry xml:lang="en">
		<title type="html">Today in the Intertweets (Aug 25th Ed)</title>
		<link href="http://feedproxy.google.com/~r/clojure/~3/Dg_G2s8qU5c/" />
		<id>http://disclojure.org/?p=1121</id>
		<updated>2010-08-26T05:37:47+00:00</updated>
		<content type="html">&lt;ul&gt;
&lt;li&gt;#Compojure Demystified with an example &amp;#8211; Part 4 (&lt;a href="http://techbehindtech.com/2010/08/24/compojure-demystified-with-an-example-part-4/"&gt;here&lt;/a&gt;, via @&lt;a href="http://twitter.com/sivajag" rel="nofollow" target="_blank" title="View sivajag's Twitter Profile"&gt;sivajag&lt;/a&gt;) &amp;#8212; Here are part &lt;a href="http://techbehindtech.com/2010/08/14/compojure-demystified-with-an-example-part-1/"&gt;1&lt;/a&gt;, &lt;a href="http://techbehindtech.com/2010/08/15/compojure-demystified-with-an-example-part-2/"&gt;2&lt;/a&gt; and &lt;a href="http://techbehindtech.com/2010/08/16/compojure-demystified-with-an-example-part-3/"&gt;3&lt;/a&gt;. This is a series about creating webapps with Compojure and Clojure.&lt;/li&gt;
&lt;li&gt;Looks like I can improve the Clojure section of DSLs In Action with the new Protocols introduced in 1.2. Non invasive abstractions FTW (via @&lt;a href="http://twitter.com/debasishg" rel="nofollow" target="_blank" title="View debasishg's Twitter Profile"&gt;debasishg&lt;/a&gt;) &amp;#8212; Those protocols sure are neat&amp;#8230;&lt;/li&gt;
&lt;li&gt;I joined Los Angeles Clojure Users Group on Meetup (&lt;a href="http://www.meetup.com/Los-Angeles-Clojure-Users-Group/"&gt;here&lt;/a&gt;, via @&lt;a href="http://twitter.com/nickmain_" rel="nofollow" target="_blank" title="View nickmain_'s Twitter Profile"&gt;nickmain_&lt;/a&gt; ) &amp;#8212; So there, there is a LA Clojure group now.&lt;/li&gt;
&lt;li&gt;Wrote up the details on getting #&lt;a href="http://search.twitter.com/search?q=%23zeromq" rel="nofollow" target="_blank" title="Search Twitter for "&gt;zeromq&lt;/a&gt; working with #&lt;a href="http://search.twitter.com/search?q=%23clojure" rel="nofollow" target="_blank" title="Search Twitter for "&gt;clojure&lt;/a&gt; on #&lt;a href="http://search.twitter.com/search?q=%23osx" rel="nofollow" target="_blank" title="Search Twitter for "&gt;osx&lt;/a&gt; (&lt;a href="http://blog.trydionel.com/2010/08/25/setting-up-0mq-for-clojure-on-osx/"&gt;here&lt;/a&gt;, via @&lt;a href="http://twitter.com/trydionel" rel="nofollow" target="_blank" title="View trydionel's Twitter Profile"&gt;trydionel&lt;/a&gt;) &amp;#8212; &lt;a href="http://www.zeromq.org/"&gt;ZeroMQ&lt;/a&gt; is a (very fast) messaging library, meant to be used programmatically, as opposed to being a shrink-wrap solution. Making it work with Clojure is not a walk in the park. This article might help if you want to do that on OSX.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/disclojure?a=LHLUs-TUoF0:hH5LAojVzIg:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/disclojure?d=yIl2AUoC8zA" border="0" /&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/disclojure?a=LHLUs-TUoF0:hH5LAojVzIg:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/disclojure?i=LHLUs-TUoF0:hH5LAojVzIg:D7DqB2pKExk" border="0" /&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/disclojure?a=LHLUs-TUoF0:hH5LAojVzIg:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/disclojure?i=LHLUs-TUoF0:hH5LAojVzIg:V_sGLiPBpWU" border="0" /&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/disclojure?a=LHLUs-TUoF0:hH5LAojVzIg:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/disclojure?i=LHLUs-TUoF0:hH5LAojVzIg:gIN9vFwOqvQ" border="0" /&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/disclojure/~4/LHLUs-TUoF0" height="1" width="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/clojure?a=Dg_G2s8qU5c:hH5LAojVzIg:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/clojure?a=Dg_G2s8qU5c:hH5LAojVzIg:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/clojure/~4/Dg_G2s8qU5c" height="1" width="1"/&gt;</content>
		<author>
			<name>Toni Batchelli</name>
			<uri>http://disclojure.org</uri>
		</author>
		<source>
			<title type="html">disclojure: all things clojure</title>
			<subtitle type="html">public disclosure of all things Clojure</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/disclojure" />
			<id>http://feeds.feedburner.com/disclojure</id>
			<updated>2010-09-03T08:30:53+00:00</updated>
		</source>
	<feedburner:origLink>http://feedproxy.google.com/~r/disclojure/~3/LHLUs-TUoF0/</feedburner:origLink></entry>

	<entry xml:lang="en">
		<title type="html">Setting up 0MQ for Clojure on OSX</title>
		<link href="http://feedproxy.google.com/~r/clojure/~3/mZbZrbTcHJI/" />
		<id>http://blog.trydionel.com/?p=195</id>
		<updated>2010-08-26T00:15:11+00:00</updated>
		<content type="html">&lt;p&gt;ZeroMQ is a simple and robust asynchronous messaging layer.&lt;sup class="footnote"&gt;&lt;a href="http://blog.trydionel.com/tag/clojure/feed/#fn-195-1" id="fnref-195-1"&gt;1&lt;/a&gt;&lt;/sup&gt;  Unfortunately, using it with Clojure is far from simple.  The steps below are the magic key that worked for me:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Starting out nice and slow, install the core zmq libraries and command line tools with homebrew:&lt;sup class="footnote"&gt;&lt;a href="http://blog.trydionel.com/tag/clojure/feed/#fn-195-2" id="fnref-195-2"&gt;2&lt;/a&gt;&lt;/sup&gt;
&lt;pre class="brush: bash;"&gt;brew install zmq&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;With ZMQ installed, you&amp;#8217;re ready to start building jzmq, the Java bindings.  You&amp;#8217;ll need to patch the homebrew formula for pkg-config, as jzmq requires the latest-and-greatest to build correctly&lt;sup class="footnote"&gt;&lt;a href="http://blog.trydionel.com/tag/clojure/feed/#fn-195-3" id="fnref-195-3"&gt;3&lt;/a&gt;&lt;/sup&gt;
&lt;pre class="brush: bash;"&gt;brew edit pkg-config&lt;/pre&gt;
&lt;pre class="brush: ruby;"&gt;
require 'formula'

class PkgConfig &amp;lt;Formula
  homepage 'http://pkgconfig.freedesktop.org'
  url 'http://pkgconfig.freedesktop.org/releases/pkg-config-0.25.tar.gz'
  md5 'a3270bab3f4b69b7dc6dbdacbcae9745'

  def install
    paths=%W[#{HOMEBREW_PREFIX}/lib/pkgconfig /usr/local/lib/pkgconfig /usr/lib/pkgconfig /usr/X11/lib/pkgconfig].uniq
    system &amp;quot;./configure&amp;quot;, &amp;quot;--with-pc-path=#{paths*':'}&amp;quot;, &amp;quot;--disable-debug&amp;quot;, &amp;quot;--prefix=#{prefix}&amp;quot;
    system &amp;quot;make install&amp;quot;
  end
end
&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;At this point, you&amp;#8217;ll need to copy one of the essential pkg-config files into a location that jzmq&amp;#8217;s build tools can find.&lt;sup class="footnote"&gt;&lt;a href="http://blog.trydionel.com/tag/clojure/feed/#fn-195-4" id="fnref-195-4"&gt;4&lt;/a&gt;&lt;/sup&gt;
&lt;pre class="brush: bash;"&gt;sudo cp /usr/local/Cellar/pkg-config/0.25/share/aclocal/pkg.m4 /usr/share/aclocal/pkg.m4&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;Now we&amp;#8217;re ready to build jzmq.  This will build the dylib you&amp;#8217;ll need to actually use the bindings, and places it in &lt;code&gt;/usr/local/lib&lt;/code&gt;.&lt;sup class="footnote"&gt;&lt;a href="http://blog.trydionel.com/tag/clojure/feed/#fn-195-5" id="fnref-195-5"&gt;5&lt;/a&gt;&lt;/sup&gt;
&lt;pre class="brush: bash;"&gt;
git clone git://github.com/zeromq/jzmq.git
cd jzmq
./autogen.sh
./configure
make
sudo make install
&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;Getting closer!  We&amp;#8217;ll need the zmq.jar file produced during the build, so copy that into your project&amp;#8217;s lib directory:&lt;sup class="footnote"&gt;&lt;a href="http://blog.trydionel.com/tag/clojure/feed/#fn-195-6" id="fnref-195-6"&gt;6&lt;/a&gt;&lt;/sup&gt;
&lt;pre class="brush: bash;"&gt;
cp ./src/zmq.jar /path/to/my/project/lib/zmq.jar
&lt;/pre&gt;
&lt;li&gt;Now we can actually start setting up Clojure for ZMQ.  Edit your leiningen project.clj file:
&lt;pre class="brush: clojure;"&gt;
(defproject my-project &amp;quot;1.0.0-SNAPSHOT&amp;quot;
  :description &amp;quot;FIXME: write&amp;quot;
  :dependencies [[org.clojure/clojure &amp;quot;1.2.0&amp;quot;]
                 [org.clojure/clojure-contrib &amp;quot;1.2.0&amp;quot;]
                 [org.clojars.mikejs/clojure-zmq &amp;quot;2.0.7-SNAPSHOT&amp;quot;]]
  :dev-dependencies [[swank-clojure &amp;quot;1.2.1&amp;quot;]]
  ; This sets the 'java.library.path' property
  ; so Java can find the ZeroMQ dylib
  :native-path &amp;quot;/usr/local/lib&amp;quot;)
&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;Collect the leiningen dependencies:
&lt;pre class="brush: bash;"&gt;
lein deps
&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;Start your swank server:
&lt;pre class="brush: bash;"&gt;
lein swank
&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;Bask in the results with the canonical example:
&lt;pre class="brush: clojure;"&gt;
(ns my-project.core
  (:use [org.zeromq.clojure :as zmq]))

(defn- string-to-bytes [s] (.getBytes s))
(defn- bytes-to-string [b] (String. b))

(defn test-zmq []
  (let [ctx (zmq/make-context 1)
	socket (zmq/make-socket ctx zmq/+upstream+)]
    (zmq/connect socket &amp;quot;tcp://127.0.0.1:5555&amp;quot;)
    (while true
      (println (bytes-to-string (zmq/recv socket))))))
&lt;/pre&gt;
&lt;/li&gt;
&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;This process is definitely rough around the edges, but I hope it helps you get started quickly!&lt;/p&gt;
&lt;div class="footnotes"&gt;
&lt;div class="footnotedivider"&gt;&lt;/div&gt;
&lt;ol&gt;
&lt;li id="fn-195-1"&gt;Read this &lt;a href="http://nichol.as/zeromq-an-introduction"&gt;excellent ZeroMQ introduction&lt;/a&gt; if you&amp;#8217;re not familiar with ZMQ.  You&amp;#8217;ll love it. &lt;span class="footnotereverse"&gt;&lt;a href="http://blog.trydionel.com/tag/clojure/feed/#fnref-195-1"&gt;&amp;#8617;&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li id="fn-195-2"&gt;This guide is EXTREMELY &lt;code&gt;brew&lt;/code&gt;-centric.  If you&amp;#8217;re running OS X, you should be using &lt;a href="http://www.github.com/mxcl/homebrew"&gt;homebrew for dependency management&lt;/a&gt;. &lt;span class="footnotereverse"&gt;&lt;a href="http://blog.trydionel.com/tag/clojure/feed/#fnref-195-2"&gt;&amp;#8617;&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li id="fn-195-3"&gt; There&amp;#8217;s an &lt;a href="http://github.com/mxcl/homebrew/issuesearch?state=open&amp;q=pkg-config#issue/2107"&gt;open ticked to update pkg-config&lt;/a&gt; in the homebrew backlog, so this may be unnecessary soon. &lt;span class="footnotereverse"&gt;&lt;a href="http://blog.trydionel.com/tag/clojure/feed/#fnref-195-3"&gt;&amp;#8617;&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li id="fn-195-4"&gt;This step should either be taken care of by homebrew, or by jzmq&amp;#8217;s &lt;code&gt;./configure&lt;/code&gt;, but I wasn&amp;#8217;t able to get it working.  Please leave a note if you know how I could resolve this step! &lt;span class="footnotereverse"&gt;&lt;a href="http://blog.trydionel.com/tag/clojure/feed/#fnref-195-4"&gt;&amp;#8617;&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li id="fn-195-5"&gt;This is another step that seems problematic.  It would be best to just install the dylib straight into OS X&amp;#8217;s Java extensions directory.  Again, please leave a comment if you can help! &lt;span class="footnotereverse"&gt;&lt;a href="http://blog.trydionel.com/tag/clojure/feed/#fnref-195-5"&gt;&amp;#8617;&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li id="fn-195-6"&gt;Another hacky step.  I gather it&amp;#8217;s possible to build jzmq with leiningen, but the &lt;code&gt;native-deps&lt;/code&gt; dependency doesn&amp;#8217;t seem to work with lein 1.3.0.  Suggestions? &lt;span class="footnotereverse"&gt;&lt;a href="http://blog.trydionel.com/tag/clojure/feed/#fnref-195-6"&gt;&amp;#8617;&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/clojure?a=mZbZrbTcHJI:VbseCsDuctI:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/clojure?a=mZbZrbTcHJI:VbseCsDuctI:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/clojure/~4/mZbZrbTcHJI" height="1" width="1"/&gt;</content>
		<author>
			<name>Jeff Tucker</name>
			<uri>http://blog.trydionel.com</uri>
		</author>
		<source>
			<title type="html">spiral_code » clojure</title>
			<link rel="self" href="http://blog.trydionel.com/tag/clojure/feed/" />
			<id>http://blog.trydionel.com/tag/clojure/feed/</id>
			<updated>2010-08-28T02:31:27+00:00</updated>
		</source>
	<feedburner:origLink>http://blog.trydionel.com/2010/08/25/setting-up-0mq-for-clojure-on-osx/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=setting-up-0mq-for-clojure-on-osx</feedburner:origLink></entry>

	<entry xml:lang="en">
		<title type="html">Quick update</title>
		<link href="http://feedproxy.google.com/~r/clojure/~3/ggv9xIVtFH4/" />
		<id>http://clj-me.cgrand.net/2010/08/26/quick-update/</id>
		<updated>2010-08-25T22:05:50+00:00</updated>
		<content type="html">&lt;p&gt;Long time no post. No code in this one though.&lt;br /&gt;
However I&amp;#8217;m pleased to announce that &lt;a href="http://bestinclass.dk/"&gt;Lau&lt;/a&gt; and me are going to give another &lt;a href="http://conj-labs.eu/"&gt;Clojure course&lt;/a&gt;: October 26-28 in Frankfurt, beginners welcome. So if you want to learn Clojure, register!&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/ClojureAndMe/~4/ggv9xIVtFH4" height="1" width="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/clojure?a=ggv9xIVtFH4:FA87S5uNEtE:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/clojure?a=ggv9xIVtFH4:FA87S5uNEtE:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/clojure/~4/ggv9xIVtFH4" height="1" width="1"/&gt;</content>
		<author>
			<name>Christophe Grand</name>
			<uri>http://clj-me.cgrand.net</uri>
		</author>
		<source>
			<title type="html">Clojure and me</title>
			<subtitle type="html">When the pupil is ready to learn, a teacher will appear.</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/ClojureAndMe" />
			<id>http://feeds.feedburner.com/ClojureAndMe</id>
			<updated>2010-08-25T22:30:59+00:00</updated>
		</source>
	<feedburner:origLink>http://clj-me.cgrand.net/2010/08/26/quick-update/</feedburner:origLink></entry>

	<entry xml:lang="en">
		<title type="html">Today in the Intertweets (Aug 24th Ed)</title>
		<link href="http://feedproxy.google.com/~r/clojure/~3/g5ZaRMvRLtY/" />
		<id>http://disclojure.org/?p=1118</id>
		<updated>2010-08-25T07:01:43+00:00</updated>
		<content type="html">&lt;ul&gt;
&lt;li&gt;Scala classes in clojure (&lt;a href="http://stackoverflow.com/questions/3555008/scala-classes-in-clojure"&gt;here&lt;/a&gt;, via @&lt;a href="http://twitter.com/ScalaAtSO" rel="nofollow" target="_blank" title="View ScalaAtSO's Twitter Profile"&gt;ScalaAtSO&lt;/a&gt;) &amp;#8212; That&amp;#8217;s right: make love, not war. It&amp;#8217;s refreshing to see Scala and Clojure in the same sentence without a &amp;#8216;vs.&amp;#8217; in between.&lt;/li&gt;
&lt;li&gt;Are github-hosted repos the maven gateway drug for my Clojure brethren? Sorry guys: it&amp;#8217;s a fact of life on the JVM.(&lt;a href="http://cemerick.com/2010/08/24/hosting-maven-repos-on-github/"&gt;here&lt;/a&gt;, via @&lt;a href="http://twitter.com/cemerick" rel="nofollow" target="_blank" title="View cemerick's Twitter Profile"&gt;cemerick&lt;/a&gt;) &amp;#8212; Yes, it is a fact of life that your project will be broken into a few modules that might evolve concurrently, and you&amp;#8217;ll have to manage their dependencies.  This article is actually only tangentially related to Clojure, as it applies to Java itself and all the other JVM-based languages. The fact of life is that you will need to setup a Maven repository which, as the article proposes, can be done without adding much infrastructure overhead.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/disclojure?a=iBRBWkNdHXY:kXm-befWIpE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/disclojure?d=yIl2AUoC8zA" border="0" /&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/disclojure?a=iBRBWkNdHXY:kXm-befWIpE:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/disclojure?i=iBRBWkNdHXY:kXm-befWIpE:D7DqB2pKExk" border="0" /&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/disclojure?a=iBRBWkNdHXY:kXm-befWIpE:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/disclojure?i=iBRBWkNdHXY:kXm-befWIpE:V_sGLiPBpWU" border="0" /&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/disclojure?a=iBRBWkNdHXY:kXm-befWIpE:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/disclojure?i=iBRBWkNdHXY:kXm-befWIpE:gIN9vFwOqvQ" border="0" /&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/disclojure/~4/iBRBWkNdHXY" height="1" width="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/clojure?a=g5ZaRMvRLtY:kXm-befWIpE:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/clojure?a=g5ZaRMvRLtY:kXm-befWIpE:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/clojure/~4/g5ZaRMvRLtY" height="1" width="1"/&gt;</content>
		<author>
			<name>Toni Batchelli</name>
			<uri>http://disclojure.org</uri>
		</author>
		<source>
			<title type="html">disclojure: all things clojure</title>
			<subtitle type="html">public disclosure of all things Clojure</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/disclojure" />
			<id>http://feeds.feedburner.com/disclojure</id>
			<updated>2010-09-03T08:30:53+00:00</updated>
		</source>
	<feedburner:origLink>http://feedproxy.google.com/~r/disclojure/~3/iBRBWkNdHXY/</feedburner:origLink></entry>

	<entry>
		<title type="html">SLIME debugger</title>
		<link href="http://feedproxy.google.com/~r/clojure/~3/lnVzChpEFVU/slime-debugger.html" />
		<id>tag:blogger.com,1999:blog-7056990295646173627.post-2096776481470839390</id>
		<updated>2010-08-24T22:30:37+00:00</updated>
		<content type="html">&lt;a href="http://hugoduncan.org/post/2010/swank_clojure_gets_a_break_with_the_local_environment.xhtml"&gt;http://hugoduncan.org/post/2010/swank_clojure_gets_a_break_with_the_local_environment.xhtml&lt;/a&gt;    &lt;!--      .clojure-body {        color: #fff8dc;        background-color: #000000;      }      .ATTRLIST {        /* (:foreground "orange1") */        color: #ffa500;      }      .ATTRLIST-1 {        /* (:foreground "yellow1") */        color: #ffff00;      }      .ATTRLIST-2 {        /* (:foreground "greenyellow") */        color: #adff2f;      }      .ATTRLIST-3 {        /* (:foreground "green1") */        color: #00ff00;      }      .ATTRLIST-4 {        /* (:foreground "springgreen1") */        color: #00ff7f;      }      .ATTRLIST-5 {        /* (:foreground "cyan1") */        color: #00ffff;      }      .ATTRLIST-6 {        /* (:foreground "slateblue1") */        color: #836fff;      }      .ATTRLIST-7 {        /* (:foreground "magenta1") */        color: #ff00ff;      }      .ATTRLIST-8 {        /* (:foreground "purple") */        color: #a020f0;      }      .comment {        /* font-lock-comment-face */        color: #ffd700;      }      .comment-delimiter {        /* font-lock-comment-delimiter-face */        color: #ffd700;      }      .function-name {        /* font-lock-function-name-face */        color: #00fa9a;      }      .keyword {        /* font-lock-keyword-face */        color: #00ffff;      }      a {        color: inherit;        background-color: inherit;        font: inherit;        text-decoration: inherit;      }      a:hover {        text-decoration: underline;      }    --&gt;        &lt;pre class="clojure-body"&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;All power to:&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;http://hugoduncan.org/post/2010/swank_clojure_gets_a_break_with_the_local_environment.xhtml&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;Who has given us a way to debug things under emacs/slime/swank, by stopping a&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;running program to examine the variables&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;First define this function under emacs/slime/swank&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;(&lt;span class="keyword"&gt;defn&lt;/span&gt; &lt;span class="function-name"&gt;factorial&lt;/span&gt; [n]&lt;br /&gt;  (&lt;span class="keyword"&gt;when&lt;/span&gt; (= n 23) (swank.core/break))&lt;br /&gt;        (&lt;span class="keyword"&gt;if&lt;/span&gt; (&amp;lt; n 2) n&lt;br /&gt;            (* n (factorial (dec n)))))&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;Then try &lt;br /&gt;&lt;/span&gt;(factorial 30)&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;at the repl, so it runs in the repl thread, rather than executing it with&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;C-M-x or C-x e, which for some reason doesn't work as well.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;Hugo's article explains how to view the local environment and create a repl&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;in context so that you can examine the state of the program when break was&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;called. You can then restart as if nothing had happened.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;It's not as wonderful as traditional SLIME/LISP debugging, but it's a good &lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;start!&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/7056990295646173627-2096776481470839390?l=learnclojure.blogspot.com" alt="" /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/clojure?a=lnVzChpEFVU:D4NF-sfdlnc:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/clojure?a=lnVzChpEFVU:D4NF-sfdlnc:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/clojure/~4/lnVzChpEFVU" height="1" width="1"/&gt;</content>
		<author>
			<name>John Lawrence Aspden</name>
			<email>noreply@blogger.com</email>
			<uri>http://learnclojure.blogspot.com/</uri>
		</author>
		<source>
			<title type="html">Learning Clojure</title>
			<link rel="self" href="http://learnclojure.blogspot.com/feeds/posts/default" />
			<id>tag:blogger.com,1999:blog-7056990295646173627</id>
			<updated>2010-08-30T06:00:17+00:00</updated>
		</source>
	<feedburner:origLink>http://learnclojure.blogspot.com/2010/08/slime-debugger.html</feedburner:origLink></entry>

	<entry>
		<title type="html">Reduce: Not Scary</title>
		<link href="http://feedproxy.google.com/~r/clojure/~3/0kBq1aeFyJE/reduce-not-scary.html" />
		<id>tag:blogger.com,1999:blog-7056990295646173627.post-2510167353824570411</id>
		<updated>2010-08-24T21:48:01+00:00</updated>
		<content type="html">&lt;!--      .clojure-body {        color: #fff8dc;        background-color: #000000;      }      .ATTRLIST {        /* (:foreground "orange1") */        color: #ffa500;      }      .ATTRLIST-1 {        /* (:foreground "yellow1") */        color: #ffff00;      }      .ATTRLIST-2 {        /* (:foreground "greenyellow") */        color: #adff2f;      }      .ATTRLIST-3 {        /* (:foreground "green1") */        color: #00ff00;      }      .ATTRLIST-4 {        /* (:foreground "springgreen1") */        color: #00ff7f;      }      .ATTRLIST-5 {        /* (:foreground "cyan1") */        color: #00ffff;      }      .ATTRLIST-6 {        /* (:foreground "slateblue1") */        color: #836fff;      }      .ATTRLIST-7 {        /* (:foreground "magenta1") */        color: #ff00ff;      }      .ATTRLIST-8 {        /* (:foreground "purple") */        color: #a020f0;      }      .builtin {        /* font-lock-builtin-face */        color: #b0c4de;      }      .comment {        /* font-lock-comment-face */        color: #ffd700;      }      .comment-delimiter {        /* font-lock-comment-delimiter-face */        color: #ffd700;      }      .doc {        /* font-lock-doc-face */        color: #ffa500;      }      .function-name {        /* font-lock-function-name-face */        color: #00fa9a;      }      .keyword {        /* font-lock-keyword-face */        color: #00ffff;      }      .string {        /* font-lock-string-face */        color: #ffa500;      }      a {        color: inherit;        background-color: inherit;        font: inherit;        text-decoration: inherit;      }      a:hover {        text-decoration: underline;      }    --&gt;        &lt;pre class="clojure-body"&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;Three very fundamental operators in any sort of programming are map, filter&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;and reduce.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;They represent the common programming tasks of transforming a collection,&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;selecting from it, and summing over it.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;Most people think that map and filter are fairly obvious, but there seems to&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;be a certain amount of confusion about reduce.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;But it's actually very simple in concept, and represents an easy idea.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;Often one needs to loop over a collection, and store results in an&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;accumulator.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;The simplest example of a reduction would be adding the numbers in a list.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;Suppose the numbers are 1,2,3,4,5,6,7,8,9,10 and we want to find their sum&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;In C, or another naturally imperative language, we'd say:&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;int list[]={1,2,3,4,5,6,7,8,9,10};&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;int len=10;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;int a=0;&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;int i;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;for (i=0; i&amp;lt;len; i++){&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;;      &lt;/span&gt;&lt;span class="comment"&gt;a += list[i];&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;}&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;Using atoms to provide mutable state, we can do something similar in Clojure:&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;(&lt;span class="keyword"&gt;def&lt;/span&gt; &lt;span class="function-name"&gt;lst&lt;/span&gt; '(1 2 3 4 5 6 7 8 9 10))&lt;br /&gt;(&lt;span class="keyword"&gt;def&lt;/span&gt; &lt;span class="function-name"&gt;len&lt;/span&gt; 10)&lt;br /&gt;&lt;br /&gt;(&lt;span class="keyword"&gt;def&lt;/span&gt; &lt;span class="function-name"&gt;a&lt;/span&gt; (atom 0))&lt;br /&gt;&lt;br /&gt;(&lt;span class="keyword"&gt;dotimes&lt;/span&gt; [i len]&lt;br /&gt;      (swap! a + (nth lst i)))&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;The value ends up in the atom a, just as in the C version.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;In clojure, this looks slightly more complicated.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;Partly because mutation in clojure is intrinsically more complicated, because&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;clojure is extremely concerned with thread safety, and so we need to allocate &lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;and dereference atoms rather than mutating local variables.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;And partly because C has very good notations for its fundamental operations.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;But logically they're the same algorithm.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;But I'd feel dirty writing this code in clojure, even though that would have&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;been a perfectly good piece of LISP in the sixties. It's just a feeling that&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;I have that it is better to avoid mutation unless it's actually necessary.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;Even though the mutation-less algorithms are often harder to write, they're&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;often easier to debug and test.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;A more natural way to accumulate over a list in clojure is the &lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;loop-as-function-call, with accumulator and iterator as parameters:&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;(&lt;span class="keyword"&gt;loop&lt;/span&gt; [a 0 i 0]&lt;br /&gt;  (&lt;span class="keyword"&gt;if&lt;/span&gt; (= i len) a&lt;br /&gt;  (&lt;span class="keyword"&gt;recur&lt;/span&gt; (+ a (nth lst i)) (&lt;span class="builtin"&gt;inc&lt;/span&gt; i))))&lt;br /&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;This is much more idiomatic code in clojure, and it doesn't mutate any values&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;even though the variable-rebinding in the recur call produces a very similar&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;effect.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;And here the final value is the value of the expression, which is nicer.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;Of course, clojure's lists know when they are empty, so we don't need an&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;explicit loop counter.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;So how about:&lt;br /&gt;&lt;/span&gt;(&lt;span class="keyword"&gt;loop&lt;/span&gt; [a 0 l lst]&lt;br /&gt;  (&lt;span class="keyword"&gt;if&lt;/span&gt; (&lt;span class="builtin"&gt;empty?&lt;/span&gt; l) a&lt;br /&gt;      (&lt;span class="keyword"&gt;recur&lt;/span&gt; (+ a (&lt;span class="builtin"&gt;first&lt;/span&gt; l)) (&lt;span class="builtin"&gt;rest&lt;/span&gt; l))))&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;l moves along the list, while a accumulates the values.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;It still looks a bit long-winded, but we can easily imagine that this is a&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;common pattern:&lt;br /&gt;&lt;/span&gt;(&lt;span class="keyword"&gt;loop&lt;/span&gt; [acc _ l _]&lt;br /&gt;  (&lt;span class="keyword"&gt;if&lt;/span&gt; (&lt;span class="builtin"&gt;empty?&lt;/span&gt; l) a&lt;br /&gt;      (&lt;span class="keyword"&gt;recur&lt;/span&gt; (_ a (&lt;span class="builtin"&gt;first&lt;/span&gt; l)) (&lt;span class="builtin"&gt;rest&lt;/span&gt; l))))&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;Where the blanks represent holes in the boilerplate we have to fill in.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;It should be almost as common as the equivalent pattern:&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;a= _ &lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;for(i=0; i&amp;lt;_; i++)&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;{ &lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;;   &lt;/span&gt;&lt;span class="comment"&gt;a _= _ [i] &lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;} &lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;is in C.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;Where in both cases we need to fill in the _ with the initial value of the&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;accumulator, the list to be accumulated over, and the operation to be&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;performed.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;Pretty much the first law of programming is:&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;If you see a common pattern, you should name it and abstract it so it goes away.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;The pattern is called reduce. &lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;We need to fill in the blanks with the function to do the accumulating,&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;the initial value of the accumulator, and the list&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;Since we're reducing the list lst, using the operation +, and starting &lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;with the value zero, we write:&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;(&lt;span class="builtin"&gt;reduce&lt;/span&gt; + 0 lst)&lt;br /&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;reduce is clojure's natural way of expressing accumulation over a list&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;in the same way as the for-loop over += and ++ is C's&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;Here are some other examples&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;(&lt;span class="builtin"&gt;reduce&lt;/span&gt; * 1 lst) &lt;br /&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;We use * instead of +, and start with 1 instead of 0&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;This produces the product of the numbers in the list.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;In these cases where the order of the arguments doesn't matter&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;we can think of reduce as 'put the function between the values'&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;(&lt;span class="builtin"&gt;reduce&lt;/span&gt; + 0 '(1 2 3 4 5 6 7 8 9 10)) &lt;span class="comment-delimiter"&gt;; &lt;/span&gt;&lt;span class="comment"&gt;(0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10)&lt;br /&gt;&lt;/span&gt;(&lt;span class="builtin"&gt;reduce&lt;/span&gt; * 1 '(1 2 3 4 5 6 7 8 9 10)) &lt;span class="comment-delimiter"&gt;; &lt;/span&gt;&lt;span class="comment"&gt;(1 * 1 * 2 * 3 * 4 * 5 * ........)&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;But this image is actually harmful when the ordering does matter.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;What's really going on is that the operator is being used to feed values&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;into the accumulator one by one.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;(&lt;span class="builtin"&gt;reduce&lt;/span&gt; + 0 '(1 2 3))   &lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;proceeds like:&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;(+ 0 1) -&amp;gt; 1&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;;         &lt;/span&gt;&lt;span class="comment"&gt;(+ 1 2) -&amp;gt; 3&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;;                 &lt;/span&gt;&lt;span class="comment"&gt;(+ 3 3) -&amp;gt; 6&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;If this seems confusing, even though you're happy with the C version,&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;think about the C loop.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;They're actually just different ways of expressing the same idea,&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;and should look equally natural. Seeing how either one can always be &lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;transformed into the other will help.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;Here's an example where the order does matter:&lt;br /&gt;&lt;/span&gt;(&lt;span class="builtin"&gt;reduce&lt;/span&gt; conj '() '(1 2 3))&lt;br /&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;How do we think about this?&lt;br /&gt;&lt;/span&gt;(&lt;span class="builtin"&gt;conj&lt;/span&gt; '()  1)   &lt;span class="comment-delimiter"&gt;; &lt;/span&gt;&lt;span class="comment"&gt;-&amp;gt; '(1)&lt;br /&gt;&lt;/span&gt;               (&lt;span class="builtin"&gt;conj&lt;/span&gt; '(1) 2)   &lt;span class="comment-delimiter"&gt;; &lt;/span&gt;&lt;span class="comment"&gt;-&amp;gt; '(2 1)&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;                              (&lt;span class="builtin"&gt;conj&lt;/span&gt; '(2 1) 3) &lt;span class="comment-delimiter"&gt;; &lt;/span&gt;&lt;span class="comment"&gt;-&amp;gt; '(3 2 1)&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;So &lt;br /&gt;&lt;/span&gt;(&lt;span class="builtin"&gt;reduce&lt;/span&gt; conj '() '(1 2 3)) -&amp;gt; '(3 2 1)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;Of course this simple reduction is so common that the pattern &lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;(reduce conj '() _ ) already has a name&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;(&lt;span class="builtin"&gt;reverse&lt;/span&gt; '( 1 2 3 ))&lt;br /&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;Here's the definition of reverse in the clojure.core source code!&lt;br /&gt;&lt;/span&gt;(&lt;span class="keyword"&gt;defn&lt;/span&gt; &lt;span class="function-name"&gt;reverse&lt;/span&gt;&lt;br /&gt;  &lt;span class="doc"&gt;"Returns a seq of the items in coll in reverse order. Not lazy."&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  {&lt;span class="builtin"&gt;:added&lt;/span&gt; &lt;span class="string"&gt;"1.0"&lt;/span&gt;}&lt;br /&gt;  [coll]&lt;br /&gt;    (&lt;span class="builtin"&gt;reduce&lt;/span&gt; conj () coll))&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;An acceptable definition of reduce itself would be:&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;(&lt;span class="keyword"&gt;defn&lt;/span&gt; &lt;span class="function-name"&gt;my-reduce&lt;/span&gt; [fn init coll]&lt;br /&gt;  (&lt;span class="keyword"&gt;loop&lt;/span&gt; [acc init l (seq coll)]&lt;br /&gt;    (&lt;span class="keyword"&gt;if&lt;/span&gt; (&lt;span class="builtin"&gt;empty?&lt;/span&gt; l) acc&lt;br /&gt;        (&lt;span class="keyword"&gt;recur&lt;/span&gt; (&lt;span class="keyword"&gt;fn&lt;/span&gt; &lt;span class="function-name"&gt;acc&lt;/span&gt; (&lt;span class="builtin"&gt;first&lt;/span&gt; l)) (&lt;span class="builtin"&gt;rest&lt;/span&gt; l)))))&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;This works on any collection that can be made into a sequence:&lt;br /&gt;&lt;/span&gt;(my-reduce * 1 '(1 2 3)) &lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;a list&lt;br /&gt;&lt;/span&gt;(my-reduce * 1 #{1,2,3}) &lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;a set&lt;br /&gt;&lt;/span&gt;(my-reduce * 1  [1,2,3]) &lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;a vector&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;The real reduce in clojure.core is an optimised version and can deal with all&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;sorts of collections efficiently, but in spirit it is just making every&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;collection into a sequence and then doing what my little skeleton above did.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;It also has another feature, which is that if you don't provide an initial&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;value for the accumulator, then it takes the first element of the sequence as&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;its initial value, and accumulates over the rest of the sequence.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;For operations which produce answers of the same type as their arguments,&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;this is often what you want.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;(&lt;span class="builtin"&gt;reduce&lt;/span&gt; * '(1 2 3 4)) &lt;span class="comment-delimiter"&gt;;&lt;/span&gt;&lt;span class="comment"&gt;24 &lt;br /&gt;&lt;br /&gt;&lt;/span&gt;(&lt;span class="builtin"&gt;reduce&lt;/span&gt; +  [1 2 3 4])  &lt;span class="comment-delimiter"&gt;;&lt;/span&gt;&lt;span class="comment"&gt;10&lt;br /&gt;&lt;/span&gt;(&lt;span class="builtin"&gt;reduce&lt;/span&gt; bit-xor '(1 2 3 4 5)) &lt;span class="comment-delimiter"&gt;;&lt;/span&gt;&lt;span class="comment"&gt;1&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;So why has this simple operation got a scary reputation?&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;I think it's because all the common cases are so useful that they have&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;already been further abstracted away, like reverse.  So in fact you don't&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;meet it that often in practice.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;Let's see if we can construct something more interesting:&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;Suppose you had a list of strings&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;(&lt;span class="keyword"&gt;def&lt;/span&gt; &lt;span class="function-name"&gt;strlist&lt;/span&gt; '(&lt;span class="string"&gt;"fred"&lt;/span&gt; &lt;span class="string"&gt;"barney"&lt;/span&gt; &lt;span class="string"&gt;"fred"&lt;/span&gt; &lt;span class="string"&gt;"wilma"&lt;/span&gt;))&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;And wanted to count how many times each string occurs in the list.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;We want an accumulator to keep the strings and counts in, and a function&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;which will take that accumulator, and a new string, and return the updated&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;accumulator.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;The obvious accumulator is a map. We'd want the answer to be something like&lt;br /&gt;&lt;/span&gt;{&lt;span class="string"&gt;"fred"&lt;/span&gt; 2, &lt;span class="string"&gt;"barney"&lt;/span&gt; 1, &lt;span class="string"&gt;"wilma"&lt;/span&gt; 1}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;So what function will add strings to a map?  &lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;;&lt;/span&gt;&lt;span class="comment"&gt;In a rather naive and long-winded way:&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;(&lt;span class="keyword"&gt;defn&lt;/span&gt; &lt;span class="function-name"&gt;addtomap&lt;/span&gt; [map string]&lt;br /&gt;  (&lt;span class="keyword"&gt;let&lt;/span&gt; [oldval&lt;br /&gt;        (&lt;span class="keyword"&gt;if&lt;/span&gt; (contains? map string) &lt;br /&gt;          (&lt;span class="builtin"&gt;map&lt;/span&gt; string) &lt;br /&gt;          0)]&lt;br /&gt;        (&lt;span class="builtin"&gt;assoc&lt;/span&gt; map string (&lt;span class="builtin"&gt;inc&lt;/span&gt; oldval))))&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;Here's how we'd use it to count our list, starting from the empty map {}, and&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;using addtomap to add each string into the accumulator returned by each call.&lt;br /&gt;&lt;/span&gt;(addtomap {} &lt;span class="string"&gt;"fred"&lt;/span&gt;)                      &lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;{"fred" 1}&lt;br /&gt;&lt;/span&gt;(addtomap {&lt;span class="string"&gt;"fred"&lt;/span&gt; 1} &lt;span class="string"&gt;"barney"&lt;/span&gt;)            &lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;{"barney" 1, "fred" 1}&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;(addtomap {&lt;span class="string"&gt;"fred"&lt;/span&gt; 1, &lt;span class="string"&gt;"barney"&lt;/span&gt; 1} &lt;span class="string"&gt;"fred"&lt;/span&gt;)  &lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;{"fred" 2, "barney" 1}&lt;br /&gt;&lt;/span&gt;(addtomap {&lt;span class="string"&gt;"fred"&lt;/span&gt; 2, &lt;span class="string"&gt;"barney"&lt;/span&gt; 1} &lt;span class="string"&gt;"wilma"&lt;/span&gt;) &lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;{"wilma" 1, "fred" 2, "barney" 1}&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;So the reduce part is obvious, once you have addtomap&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;(&lt;span class="builtin"&gt;reduce&lt;/span&gt; addtomap {} strlist)&lt;br /&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;But a real Clojure programmer would look at addtomap and think:&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;We can write (map string 0) instead of &lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;(if (contains? map string) &lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;;           &lt;/span&gt;&lt;span class="comment"&gt;(map string) &lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;;           &lt;/span&gt;&lt;span class="comment"&gt;0)&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;So a better version of addtomap would be:&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;(&lt;span class="keyword"&gt;defn&lt;/span&gt; &lt;span class="function-name"&gt;addtomap&lt;/span&gt; [map string]&lt;br /&gt;  (&lt;span class="keyword"&gt;let&lt;/span&gt; [oldval (&lt;span class="builtin"&gt;map&lt;/span&gt; string 0)]&lt;br /&gt;        (&lt;span class="builtin"&gt;assoc&lt;/span&gt; map string (&lt;span class="builtin"&gt;inc&lt;/span&gt; oldval))))&lt;br /&gt;&lt;br /&gt;(&lt;span class="builtin"&gt;reduce&lt;/span&gt; addtomap {} strlist)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;And now the let statement looks redundant, so let's say&lt;br /&gt;&lt;/span&gt;(&lt;span class="keyword"&gt;defn&lt;/span&gt; &lt;span class="function-name"&gt;addtomap&lt;/span&gt; [map string]&lt;br /&gt;  (&lt;span class="builtin"&gt;assoc&lt;/span&gt; map string (&lt;span class="builtin"&gt;inc&lt;/span&gt; (&lt;span class="builtin"&gt;map&lt;/span&gt; string 0))))&lt;br /&gt;&lt;br /&gt;(&lt;span class="builtin"&gt;reduce&lt;/span&gt; addtomap {} strlist)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;And then he might say &lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;"since I'm only going to use this function here, why not make it anonymous?"&lt;br /&gt;&lt;/span&gt;(&lt;span class="keyword"&gt;fn&lt;/span&gt; [map string] (&lt;span class="builtin"&gt;assoc&lt;/span&gt; map string (&lt;span class="builtin"&gt;inc&lt;/span&gt; (&lt;span class="builtin"&gt;map&lt;/span&gt; string 0))))&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;And now the reduce looks like:&lt;br /&gt;&lt;/span&gt;(&lt;span class="builtin"&gt;reduce&lt;/span&gt; (&lt;span class="keyword"&gt;fn&lt;/span&gt; [map string] (&lt;span class="builtin"&gt;assoc&lt;/span&gt; map string (&lt;span class="builtin"&gt;inc&lt;/span&gt; (&lt;span class="builtin"&gt;map&lt;/span&gt; string 0)))) {} strlist)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;And, well, at this point, any reasonable man is going to think:&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;"Since I'm writing a one-liner, I might as well use the anonymous shorthand"&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;#(&lt;span class="builtin"&gt;assoc&lt;/span&gt; %1 %2 (&lt;span class="builtin"&gt;inc&lt;/span&gt; (%1 %2 0)))&lt;br /&gt;&lt;br /&gt;(&lt;span class="builtin"&gt;reduce&lt;/span&gt; #(&lt;span class="builtin"&gt;assoc&lt;/span&gt; %1 %2 (&lt;span class="builtin"&gt;inc&lt;/span&gt; (%1 %2 0))) {} strlist)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;And if you already understand reduce and anonymous functions, and how maps&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;work, this is actually not too hard to understand.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;In fact this is the version of the function that I originally wrote.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;But I can see it might be a bit off-putting if you thought reduce itself was&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;scary. &lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;Actually the obfuscation / pleasing terseness is all in the anonymous&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;function, and the behaviour of maps, and the reduce bit isn't scary at all.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;Here's another deliberately obscure example, using a little structure as an&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;accumulator.  See if you can figure out what it does using the above ideas to&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;unpack it. I'm using the destructuring notation to take the little structure&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;apart, and then the function modifies each part and puts them back together again&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;(&lt;span class="builtin"&gt;reduce&lt;/span&gt; (fn[[c s] n] [(+ c n), (&lt;span class="builtin"&gt;str&lt;/span&gt; s n)]) [0,&lt;span class="string"&gt;""&lt;/span&gt;] lst)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;The trick is to work out what the anonymous function does to the starting &lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;value of the accumulator when it gets a value from the list.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;&lt;/span&gt;&lt;span class="comment"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;Clojure's natural facility with abstractions and small functions allows&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;some truly terse code.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;This little piece of code counts words in a file and orders them by popularity:&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;(&lt;span class="builtin"&gt;sort&lt;/span&gt; #(&amp;lt; (%1 1) (%2 1)) &lt;br /&gt;      (&lt;span class="builtin"&gt;reduce&lt;/span&gt; #(&lt;span class="builtin"&gt;assoc&lt;/span&gt; %1 %2 (&lt;span class="builtin"&gt;inc&lt;/span&gt; (%1 %2 0))) {}&lt;br /&gt;       (clojure.contrib.string/split &lt;br /&gt;        #&lt;span class="string"&gt;"\W"&lt;/span&gt; &lt;br /&gt;        (slurp &lt;span class="string"&gt;"/home/john/hobby-code/reduce.clj"&lt;/span&gt;))))&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;With practice this sort of thing is actually readable. Promise!&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;But if I was actually writing it for someone else to read, &lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;I'd probably split it up and give the bits names.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;(&lt;span class="keyword"&gt;let&lt;/span&gt; [filecontents (slurp &lt;span class="string"&gt;"/home/john/hobby-code/reduce.clj"&lt;/span&gt;)&lt;br /&gt;      words        (clojure.contrib.string/split #&lt;span class="string"&gt;"\W"&lt;/span&gt; filecontents)&lt;br /&gt;      wordmap      (&lt;span class="builtin"&gt;reduce&lt;/span&gt; #(&lt;span class="builtin"&gt;assoc&lt;/span&gt; %1 %2 (&lt;span class="builtin"&gt;inc&lt;/span&gt; (%1 %2 0))) {}  words)&lt;br /&gt;      sortedwords  (&lt;span class="builtin"&gt;sort&lt;/span&gt; #(&amp;lt; (%1 1) (%2 1)) wordmap)]&lt;br /&gt;  sortedwords)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;And if I knew the library, I'd remember that two of those little operations&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;actually already have names:&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;The idiom&lt;br /&gt;&lt;/span&gt;( reduce #(&lt;span class="builtin"&gt;assoc&lt;/span&gt; %1 %2 (&lt;span class="builtin"&gt;inc&lt;/span&gt; (%1 %2 0)) {} .... )&lt;br /&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;which I used to find myself writing all the time, is such a useful thing &lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;that it too has made it into clojure.core as the function frequencies:&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;(frequencies strlist)&lt;br /&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;and the sort with the comparator on the second elements can be replaced by sort-by, and second&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;(&lt;span class="keyword"&gt;let&lt;/span&gt; [filecontents (slurp &lt;span class="string"&gt;"/home/john/hobby-code/reduce.clj"&lt;/span&gt;)&lt;br /&gt;      words        (clojure.contrib.string/split #&lt;span class="string"&gt;"\W"&lt;/span&gt; filecontents)&lt;br /&gt;      wordmap      (frequencies words)&lt;br /&gt;      sortedwords  (&lt;span class="builtin"&gt;sort-by&lt;/span&gt; second wordmap)]&lt;br /&gt;  sortedwords)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;And then I'd abstract away the word counting operations from the file reading part&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;(&lt;span class="keyword"&gt;defn&lt;/span&gt; &lt;span class="function-name"&gt;sorted-word-frequencies&lt;/span&gt; [string]&lt;br /&gt;  (&lt;span class="builtin"&gt;sort-by&lt;/span&gt; second (frequencies&lt;br /&gt;                   (clojure.contrib.string/split #&lt;span class="string"&gt;"\W+"&lt;/span&gt; string))))&lt;br /&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;So now I can ask for the 10 most popular words:&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;(&lt;span class="builtin"&gt;take&lt;/span&gt; 10 (&lt;span class="builtin"&gt;reverse&lt;/span&gt; (sorted-word-frequencies (slurp &lt;span class="string"&gt;"/home/john/hobby-code/reduce.clj"&lt;/span&gt;))))&lt;br /&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;which is also pleasingly terse, but I think more readable.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;  &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/7056990295646173627-2510167353824570411?l=learnclojure.blogspot.com" alt="" /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/clojure?a=0kBq1aeFyJE:DCKqh2w_rfA:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/clojure?a=0kBq1aeFyJE:DCKqh2w_rfA:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/clojure/~4/0kBq1aeFyJE" height="1" width="1"/&gt;</content>
		<author>
			<name>John Lawrence Aspden</name>
			<email>noreply@blogger.com</email>
			<uri>http://learnclojure.blogspot.com/</uri>
		</author>
		<source>
			<title type="html">Learning Clojure</title>
			<link rel="self" href="http://learnclojure.blogspot.com/feeds/posts/default" />
			<id>tag:blogger.com,1999:blog-7056990295646173627</id>
			<updated>2010-08-30T06:00:17+00:00</updated>
		</source>
	<feedburner:origLink>http://learnclojure.blogspot.com/2010/08/reduce-not-scary.html</feedburner:origLink></entry>

	<entry xml:lang="en">
		<title type="html">Hosting Maven Repos on Github</title>
		<link href="" />
		<id>http://cemerick.com/?p=183</id>
		<updated>2010-08-24T18:00:17+00:00</updated>
		<content type="html">Hosting Maven repos has gotten easier and easier over the years.  We&amp;#8217;ve run the free version of Nexus for a couple of years now, which owns all the other options feature-wise as far as I can tell, and is a &amp;#8230; &lt;a href="http://cemerick.com/2010/08/24/hosting-maven-repos-on-github/"&gt;Continue reading &lt;span class="meta-nav"&gt;&amp;#8594;&lt;/span&gt;&lt;/a&gt;&lt;img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cemerick.com&amp;blog=14971344&amp;post=183&amp;subd=chasemerick&amp;ref=&amp;feed=1" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/clojure?a=Ro2eosQjYao:qGxxyXSceFI:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/clojure?a=Ro2eosQjYao:qGxxyXSceFI:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content>
		<author>
			<name>Chas Emerick</name>
			<uri>http://cemerick.com</uri>
		</author>
		<source>
			<title type="html">cemerick » Clojure</title>
			<subtitle type="html">...knowing just enough to be dangerous.</subtitle>
			<link rel="self" href="http://cemerick.com/category/clojure/feed/" />
			<id>http://cemerick.com/category/clojure/feed/</id>
			<updated>2010-09-03T21:00:42+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">One Language, Many Implementations</title>
		<link href="" />
		<id>http://framegen.wordpress.com/?p=408</id>
		<updated>2010-08-24T14:43:29+00:00</updated>
		<content type="html">The interpreter model that I use to implement Lisp is very simple and flexible. It was originally derived from Peter Norvig&amp;#8217;s SILK interpreter, but has gone through multiple revisions over the years. Here is a list of various versions that are currently working: Gwt-Clojure &amp;#8211; Clojure syntax, built inJava/Javascript using Google&amp;#8217;s GWT compiler and libraries [...]&lt;img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=framegen.wordpress.com&amp;blog=12509741&amp;post=408&amp;subd=framegen&amp;ref=&amp;feed=1" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/clojure?a=Ro2eosQjYao:hHgjVEJitsw:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/clojure?a=Ro2eosQjYao:hHgjVEJitsw:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content>
		<author>
			<name>Framegen Site Generator</name>
			<uri>http://framegen.wordpress.com</uri>
		</author>
		<source>
			<title type="html">Framegen Site Generator » Clojure</title>
			<subtitle type="html">Automated html, css, and javascript generation</subtitle>
			<link rel="self" href="http://framegen.wordpress.com/category/clojure/feed/" />
			<id>http://framegen.wordpress.com/category/clojure/feed/</id>
			<updated>2010-09-03T21:00:40+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">Today in the Intertweets (Aug 23rd Ed)</title>
		<link href="http://feedproxy.google.com/~r/clojure/~3/7Iw6y0y5ah8/" />
		<id>http://disclojure.org/?p=1114</id>
		<updated>2010-08-24T07:39:22+00:00</updated>
		<content type="html">&lt;ul&gt;
&lt;li&gt;Alle drei Teile unserer Clojure-Serie im JavaSPEKTRUM sind mittlerweile online (&lt;a href="http://www.innoq.com/de/resources/clojure-intro-neppert"&gt;here&lt;/a&gt;, via @&lt;a href="http://twitter.com/stilkov" rel="nofollow" target="_blank" title="View stilkov's Twitter Profile"&gt;stilkov&lt;/a&gt;) &amp;#8212; For the German speakers (well, readers would be fine too!), here are the three parts of a series of articles on Clojure for JavaSPEKTRUM (Overview, Data Types and Java Integration, and Concurrency).&lt;/li&gt;
&lt;li&gt;Version 0.6 of the Grails Clojure plugin utilizes Clojure 1.2.0 (&lt;a href="http://grails.org/plugin/clojure"&gt;here&lt;/a&gt;, via @&lt;a href="http://twitter.com/jeffscottbrown" rel="nofollow" target="_blank" title="View jeffscottbrown's Twitter Profile"&gt;jeffscottbrown&lt;/a&gt;) &amp;#8212; Grails is a Groovy-based web development framework. This plugin lets you use clojure from within the framework, which makes it very easy to develop webapps and use Clojure in the backend.&lt;/li&gt;
&lt;li&gt;Securing #&lt;a href="http://search.twitter.com/search?q=%23Clojure" rel="nofollow" target="_blank" title="Search Twitter for "&gt;Clojure&lt;/a&gt; web applications with Sandbar &amp;#8211; Part 2. Form-based authentication and channel security (&lt;a href="http://formpluslogic.blogspot.com/2010/08/securing-clojure-web-applications-with.html"&gt;here&lt;/a&gt;, via @&lt;a href="http://twitter.com/brentonashworth" rel="nofollow" target="_blank" title="View brentonashworth's Twitter Profile"&gt;brentonashworth&lt;/a&gt;) &amp;#8212; Sandbar is a library intended to work on top of Compojure/Ring and that simplifies writing web applications.&lt;/li&gt;
&lt;li&gt;Basic authentication for ring (and compojure etc.) (&lt;a href="http://twitter.com/planetclojure/status/21940410037"&gt;here&lt;/a&gt;, via @&lt;a href="http://twitter.com/planetclojure" rel="nofollow" target="_blank" title="View planetclojure's Twitter Profile"&gt;planetclojure&lt;/a&gt;) &amp;#8212; Basic Authentication, but this time without Sandbar ;)&lt;/li&gt;
&lt;li&gt;A micro-manual for LISP Implemented in C (&lt;a href="http://nakkaya.com/2010/08/24/a-micro-manual-for-lisp-implemented-in-c/"&gt;here&lt;/a&gt;, via @&lt;a href="http://twitter.com/planetclojure" rel="nofollow" target="_blank" title="View planetclojure's Twitter Profile"&gt;planetclojure&lt;/a&gt;) &amp;#8212; Ok, bear with me here. Nurullah has a free weekend, and what do you normally do with a free weekend? Well, it turns out he decides to write a LISP in C. So he writes it, and it works. Let me ask here, how many of you pull this kind of software over the weekends?!? I don&amp;#8217;t. I would if I could though!&lt;/li&gt;
&lt;li&gt;Are we to static for a dynamic world? (&lt;a href="http://kotka.de/blog/2010/08/Static_vs_Dynamic.html"&gt;here&lt;/a&gt;, via @&lt;a href="http://twitter.com/kotarak" rel="nofollow" target="_blank" title="View kotarak's Twitter Profile"&gt;kotarak&lt;/a&gt;) &amp;#8212; The pros and cons of extending records statically or dynamically (speed vs. flexibility). Good insight, you might want to tread this, since these features are new to Clojure 1.2.0&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/disclojure?a=EWSfdwPQjsg:NIcBdmEZzBI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/disclojure?d=yIl2AUoC8zA" border="0" /&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/disclojure?a=EWSfdwPQjsg:NIcBdmEZzBI:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/disclojure?i=EWSfdwPQjsg:NIcBdmEZzBI:D7DqB2pKExk" border="0" /&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/disclojure?a=EWSfdwPQjsg:NIcBdmEZzBI:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/disclojure?i=EWSfdwPQjsg:NIcBdmEZzBI:V_sGLiPBpWU" border="0" /&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/disclojure?a=EWSfdwPQjsg:NIcBdmEZzBI:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/disclojure?i=EWSfdwPQjsg:NIcBdmEZzBI:gIN9vFwOqvQ" border="0" /&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/disclojure/~4/EWSfdwPQjsg" height="1" width="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/clojure?a=7Iw6y0y5ah8:NIcBdmEZzBI:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/clojure?a=7Iw6y0y5ah8:NIcBdmEZzBI:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/clojure/~4/7Iw6y0y5ah8" height="1" width="1"/&gt;</content>
		<author>
			<name>Toni Batchelli</name>
			<uri>http://disclojure.org</uri>
		</author>
		<source>
			<title type="html">disclojure: all things clojure</title>
			<subtitle type="html">public disclosure of all things Clojure</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/disclojure" />
			<id>http://feeds.feedburner.com/disclojure</id>
			<updated>2010-09-03T08:30:53+00:00</updated>
		</source>
	<feedburner:origLink>http://feedproxy.google.com/~r/disclojure/~3/EWSfdwPQjsg/</feedburner:origLink></entry>

	<entry>
		<title type="html">Basic authentication for ring (and compojure etc.)</title>
		<link href="http://feedproxy.google.com/~r/clojure/~3/WoUNUB6Vno0/Basic_authentication_for_ring_and_compojure_etc" />
		<id>http://blog.remvee.net/2010/08/23/Basic_authentication_for_ring_and_compojure_etc</id>
		<updated>2010-08-23T19:26:00+00:00</updated>
		<content type="html">&lt;p&gt;I&amp;#8217;ve always liked &lt;span class="caps"&gt;HTTP&lt;/span&gt; authentication (like basic and digest) over login pages because they look so..  technically savvy.  Finally somebody who bothered to read an &lt;span class="caps"&gt;RFC&lt;/span&gt; to implement it and make me feel warm and welcome like peers do.&lt;/p&gt;
&lt;p&gt;Okay, I must admit, it takes a customer just a couple of moments to request a logout button, which is a real pain to implement, if possible at all.  And I wouldn&amp;#8217;t want to login on something I care about from a public computer either.  But it is very nice for services!&lt;/p&gt;
&lt;p&gt;Anyway here&amp;#8217;s my implementation as ring middleware: &lt;a href="http://github.com/remvee/ring-basic-authentication"&gt;ring-basic-authentication&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/clojure?a=WoUNUB6Vno0:XmfQsY8s1OE:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/clojure?a=WoUNUB6Vno0:XmfQsY8s1OE:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/clojure/~4/WoUNUB6Vno0" height="1" width="1"/&gt;</content>
		<author>
			<name>Remco van 't Veer</name>
			<email>remco@remvee.net</email>
			<uri>http://blog.remvee.net/</uri>
		</author>
		<source>
			<title type="html">RemVee.blog</title>
			<subtitle type="html">RemVee.blog do { |item| item.mangle }</subtitle>
			<link rel="self" href="http://blog.remvee.net/category/clojure/rss.xml" />
			<id>http://blog.remvee.net/category/clojure/rss.xml</id>
			<updated>2010-08-23T19:31:23+00:00</updated>
		</source>
	<feedburner:origLink>http://blog.remvee.net/2010/08/23/Basic_authentication_for_ring_and_compojure_etc</feedburner:origLink></entry>

	<entry>
		<title type="html">Syntax highlighting for clojure code</title>
		<link href="http://feedproxy.google.com/~r/clojure/~3/0Gh7gu5-V9w/syntax-highlighting-for-clojure-code.html" />
		<id>tag:blogger.com,1999:blog-3444118573883320615.post-9045040388315121358</id>
		<updated>2010-08-23T13:25:51+00:00</updated>
		<content type="html">Having left people hanging last week, the tool I used to format thecode for the blog hosted on blogger is:GNU enscript.None of the available tools would work out of the box. GNU enscript provides the most bang for the buck. I've been using it for printing text for a while now - it has all the flexibility the "in the browser" highlighters have, at least when printing postscript. While it's natural&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/clojure?a=0Gh7gu5-V9w:h67RHB-wsAM:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/clojure?a=0Gh7gu5-V9w:h67RHB-wsAM:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/clojure/~4/0Gh7gu5-V9w" height="1" width="1"/&gt;</content>
		<author>
			<name>MIke Meyer</name>
			<email>noreply@blogger.com</email>
			<uri>http://blog.mired.org/search/label/clojure</uri>
		</author>
		<source>
			<title type="html">Mired in code</title>
			<subtitle type="html">An ongoing blog of my programming interests</subtitle>
			<link rel="self" href="http://blog.mired.org/feeds/posts/default/-/clojure" />
			<id>tag:blogger.com,1999:blog-3444118573883320615</id>
			<updated>2010-08-28T04:31:25+00:00</updated>
		</source>
	<feedburner:origLink>http://blog.mired.org/2010/08/syntax-highlighting-for-clojure-code.html</feedburner:origLink></entry>

	<entry>
		<title type="html">Securing Clojure Web Applications with Sandbar - Part 2</title>
		<link href="http://feedproxy.google.com/~r/clojure/~3/549FnZPVGWY/securing-clojure-web-applications-with.html" />
		<id>tag:blogger.com,1999:blog-4851261502438710182.post-5545562259451614697</id>
		<updated>2010-08-23T08:44:54+00:00</updated>
		<content type="html">In &lt;a href="http://formpluslogic.blogspot.com/2010/08/securing-web-applications-with-sandbar.html"&gt;part 1&lt;/a&gt; of this series, a simple authorization scheme was added to a &lt;a href="http://github.com/brentonashworth/sandbar-examples/blob/master/security/src/sandbar/examples/part_one/complete.clj"&gt;small Clojure web application&lt;/a&gt;. Continuing with this example, this post will demonstrate how features of &lt;code&gt;sandbar.auth&lt;/code&gt; may be used to add form-based authentication and channel security.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Form-based authentication and channel security&lt;/h3&gt;&lt;br /&gt;If you would like to follow along:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;$ git clone git://github.com/brentonashworth/sandbar-examples.git&lt;br /&gt;$ cd sandbar-examples/security&lt;br /&gt;$ open src/sandbar/examples/part_two/start.clj&lt;br /&gt;$ lein deps&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;This code is a bit different from what we ended with last time. A stylesheet has been added and the layout has been improved. The complete source for our starting point is shown below. Make sure you understand this code before moving on.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(ns sandbar.examples.part-two.start&lt;br /&gt;  (:use (ring.adapter jetty)&lt;br /&gt;        (ring.middleware file)&lt;br /&gt;        (compojure core)&lt;br /&gt;        (hiccup core page-helpers)&lt;br /&gt;        (sandbar core stateful-session auth)))&lt;br /&gt;&lt;br /&gt;(defn query [type]&lt;br /&gt;  (ensure-any-role-if (= type :top-secret) #{:admin}&lt;br /&gt;                      (= type :members-only) #{:member}&lt;br /&gt;                      (str (name type) " data")))&lt;br /&gt;&lt;br /&gt;(defn layout [content]&lt;br /&gt;  (html&lt;br /&gt;   (doctype :html4)&lt;br /&gt;   [:html&lt;br /&gt;    [:head&lt;br /&gt;     (stylesheet "sandbar.css")&lt;br /&gt;     (icon "icon.png")]&lt;br /&gt;    [:body&lt;br /&gt;     [:h2 "Sandbar Security Example"]&lt;br /&gt;     content&lt;br /&gt;     [:br]&lt;br /&gt;     [:div (if-let [username (current-username)]&lt;br /&gt;             [:div&lt;br /&gt;              (str "You are logged in as " username ". ")&lt;br /&gt;              (link-to "logout" "Logout")])]]]))&lt;br /&gt;&lt;br /&gt;(defn data-view [title data &amp;amp; links]&lt;br /&gt;  [:div&lt;br /&gt;   [:h3 title]&lt;br /&gt;   [:p data]&lt;br /&gt;   (if (seq links) links [:div (link-to "home" "Home")])])&lt;br /&gt;&lt;br /&gt;(defn home-view []&lt;br /&gt;  (data-view "Home"&lt;br /&gt;             (query :public)&lt;br /&gt;             [:div (link-to "member" "Member Data")]&lt;br /&gt;             [:div (link-to "admin" "Admin Data")]&lt;br /&gt;             [:br]&lt;br /&gt;             [:div (cond (any-role-granted? :admin)&lt;br /&gt;                         "Hello administrator!"&lt;br /&gt;                         (any-role-granted? :member)&lt;br /&gt;                         "Hello member!"&lt;br /&gt;                         :else "Click on one of the links above to log in.")]))&lt;br /&gt;&lt;br /&gt;(defn member-view []&lt;br /&gt;  (data-view "Member Page"&lt;br /&gt;             (query :members-only)))&lt;br /&gt;&lt;br /&gt;(defn admin-view []&lt;br /&gt;  (data-view "Admin Page"&lt;br /&gt;             (query :top-secret)))&lt;br /&gt;&lt;br /&gt;(defn permission-denied-view []&lt;br /&gt; [:div&lt;br /&gt;  [:h3 "Permission Denied"]&lt;br /&gt;  [:div (link-to "home" "Home")]])&lt;br /&gt;&lt;br /&gt;(defroutes my-routes&lt;br /&gt;  (GET "/home*" [] (layout (home-view)))&lt;br /&gt;  (GET "/member*" [] (layout (member-view)))&lt;br /&gt;  (GET "/admin*" [] (layout (admin-view)))&lt;br /&gt;  (GET "/logout*" [] (logout! {}))&lt;br /&gt;  (GET "/permission-denied*" [] (layout (permission-denied-view)))&lt;br /&gt;  (ANY "*" [] (layout (home-view))))&lt;br /&gt;&lt;br /&gt;(defn authenticate [request]&lt;br /&gt;  (let [uri (:uri request)]&lt;br /&gt;    (cond (= uri "/member") {:name "joe" :roles #{:member}}&lt;br /&gt;          (= uri "/admin") {:name "sue" :roles #{:admin}})))&lt;br /&gt;&lt;br /&gt;(def app (-&gt; my-routes&lt;br /&gt;             (with-security authenticate)&lt;br /&gt;             wrap-stateful-session&lt;br /&gt;             (wrap-file "public")))&lt;br /&gt;&lt;br /&gt;(defn run []&lt;br /&gt;  (run-jetty (var app) {:join? false :port 8080}))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;h3&gt;Encryption&lt;/h3&gt;&lt;br /&gt;Our application must ensure that passwords are not sent across the network in plain text. In a production environment, one would enable SSL support on the web server and purchase a legitimate SSL certificate from a valid authority for use with the site's domain. For development, it is good enough to create a self-signed certificate and turn on Jetty's SSL support.&lt;br /&gt;&lt;br /&gt;Use Java's &lt;code&gt;keytool&lt;/code&gt; to create a self-signed certificate.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;$ keytool -genkey -alias sandbar -keyalg RSA -keystore my.keystore -keypass foobar&lt;br /&gt;Enter keystore password:  &lt;br /&gt;Re-enter new password: &lt;br /&gt;What is your first and last name?&lt;br /&gt;[Unknown]:  localhost&lt;br /&gt;What is the name of your organizational unit?&lt;br /&gt;[Unknown]:  dev&lt;br /&gt;What is the name of your organization?&lt;br /&gt;[Unknown]:  clojure&lt;br /&gt;What is the name of your City or Locality?&lt;br /&gt;[Unknown]:  New York     &lt;br /&gt;What is the name of your State or Province?&lt;br /&gt;[Unknown]:  New York&lt;br /&gt;What is the two-letter country code for this unit?&lt;br /&gt;[Unknown]:  US&lt;br /&gt;Is CN=localhost, OU=dev, O=clojure, L=New York, ST=New York, C=US correct?&lt;br /&gt;[no]:  y&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;For this example, the password "foobar" was entered. &lt;code&gt;keytool&lt;/code&gt; has created a keystore in the file named &lt;code&gt;my.keystore&lt;/code&gt;. Make sure this file is located in the root directory of the security module (at the same level as the public directory).&lt;br /&gt;&lt;br /&gt;To make use of this keystore, update the &lt;code&gt;run&lt;/code&gt; function so that it matches the version shown below.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(defn run []&lt;br /&gt;  (run-jetty (var app) {:join? false :ssl? true :port 8080 :ssl-port 8443&lt;br /&gt;                        :keystore "my.keystore"&lt;br /&gt;                        :key-password "foobar"}))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Setting &lt;code&gt;:join?&lt;/code&gt; to false will cause the call to &lt;code&gt;run-jetty&lt;/code&gt; to return so that the REPL may still be used.  The &lt;code&gt;:ssl-port&lt;/code&gt; defaults to 443; here we set it here to 8443. Everything else is straight forward. If you are following along, now would be a great time to start a REPL and test that everything is working as expected.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;$ lein repl&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;user=&gt; (use 'sandbar.examples.part-two.start)&lt;br /&gt;user=&gt; (run)&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Navigating to &lt;code&gt;https://localhost:8443/&lt;/code&gt; and &lt;code&gt;http://localhost:8080/&lt;/code&gt; confirms that the application may be used over SSL or standard http and that everything works the same as it did before.&lt;br /&gt;&lt;br /&gt;Note: You will get a warning message because the certificate that we are using is not legitimate. This is fine for development; do what you need to do to add an exception for this certificate. &lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Adding form-based authentication&lt;/h3&gt;&lt;br /&gt;In the last post, the &lt;code&gt;with-security&lt;/code&gt; middleware was added and configured to use our &lt;code&gt;authenticate&lt;/code&gt; function. In this section, the &lt;code&gt;authenticate&lt;/code&gt; function will be replaced with an authentication function from &lt;code&gt;sandbar.form-authentication&lt;/code&gt; and a pre-built login form will be added. &lt;br /&gt;&lt;br /&gt;Start by adding the required namespaces &lt;code&gt;sandbar.form-authentication&lt;/code&gt; and &lt;code&gt;sandbar.validation&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;Delete the &lt;code&gt;authenticate&lt;/code&gt; function and replace &lt;code&gt;authenticate&lt;/code&gt; with &lt;code&gt;form-authentication&lt;/code&gt; in our &lt;code&gt;with-security&lt;/code&gt; middleware. &lt;code&gt;form-authentication&lt;/code&gt; will redirect a user to a login form when that user is not authenticated.&lt;br /&gt;&lt;br /&gt;To implement the login form, add &lt;code&gt;form-authentication-routes&lt;/code&gt; to the list of routes.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(form-authentication-routes (fn [_ c] (layout c))&lt;br /&gt;                            (form-authentication-adapter))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;The parameters to &lt;code&gt;form-authentication-routes&lt;/code&gt; are: a layout function and something that satisfies the protocol &lt;code&gt;FormAuthAdapter&lt;/code&gt;. The layout function must take two parameters: the request and the content to layout. The &lt;code&gt;FormAuthAdapter&lt;/code&gt; protocol specifies two functions which allow us to adapt this component to our system. The functions are &lt;code&gt;load-user&lt;/code&gt; and &lt;code&gt;validate-password&lt;/code&gt;. &lt;code&gt;load-user&lt;/code&gt; takes a username and password and returns a user map. A user map must at least have the keys &lt;code&gt;:username&lt;/code&gt; and &lt;code&gt;:roles&lt;/code&gt;. &lt;code&gt;validate-password&lt;/code&gt; returns a function that can validate the user map created by &lt;code&gt;load-user&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(defrecord DemoAdapter []&lt;br /&gt;  FormAuthAdapter&lt;br /&gt;  (load-user&lt;br /&gt;   [this username password]&lt;br /&gt;   (let [login {:username username :password password}]&lt;br /&gt;     (cond (= username "member")&lt;br /&gt;           (merge login {:roles #{:member}})&lt;br /&gt;           (= username "admin")&lt;br /&gt;           (merge login {:roles #{:admin}})&lt;br /&gt;           :else login)))&lt;br /&gt;  (validate-password&lt;br /&gt;   [this]&lt;br /&gt;   (fn [m]&lt;br /&gt;     (if (= (:password m) (:username m))&lt;br /&gt;       m&lt;br /&gt;       (add-validation-error m "Username and password do not match!")))))&lt;br /&gt;&lt;br /&gt;(defn form-authentication-adapter []&lt;br /&gt;  (DemoAdapter.))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;This implementation of &lt;code&gt;load-user&lt;/code&gt; will simply look at the username to determine if the user is a member or admin. The &lt;code&gt;validate-password&lt;/code&gt; implementation will ensure that the username and password are the same. &lt;code&gt;add-validation-error&lt;/code&gt; is a function from &lt;code&gt;sandbar.validation&lt;/code&gt; which is being used here to display an error message. &lt;br /&gt;&lt;br /&gt;(For more information about validators, see the post &lt;a href="http://formpluslogic.blogspot.com/2010/04/clojure-macros-make-me-happy.html"&gt;Clojure Macros Make Me Happy&lt;/a&gt;. I will not go into any more detail here.)&lt;br /&gt;&lt;br /&gt;After making these changes, saving them and reloading the namespace, &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;user=&gt; (use :reload-all 'sandbar.examples.part-two.start)&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;we can return to our application where we should now have an operational login form. Try submitting the form while it is empty. Try entering a username and password that do not match. The form does the right thing in each situation.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Form Customization&lt;/h3&gt;&lt;br /&gt;At this point you may want to customize the field names on the form as well as the error messages that are displayed. While we are at it, let's make a custom logout landing page. Create a map with keys that correspond to the fields and errors that we would like to update as well as the key &lt;code&gt;:logout-page&lt;/code&gt; that indicates where to go after we logout.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(def properties&lt;br /&gt;     {:username "Username"&lt;br /&gt;      :password "Password"&lt;br /&gt;      :username-validation-error "Enter either admin or member"&lt;br /&gt;      :password-validation-error "Enter a password!"&lt;br /&gt;      :logout-page "/after-logout"})&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Update the &lt;code&gt;form-authentication-adapter&lt;/code&gt; constructor to merge these properties into our &lt;code&gt;DemoAdapter&lt;/code&gt;. Because Clojure's records implement the persistent map interface, the form-authentication module uses the &lt;code&gt;FormAuthAdapter&lt;/code&gt; as a map to look up field names and error messages for the login form. &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(defn basic-auth-adapter []&lt;br /&gt;  (merge (DemoAdapter.) properties))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;After making this change, we will see our own field names and error messages displayed on the login form.&lt;br /&gt;&lt;br /&gt;Next, create the logout landing page by replacing the empty map that was passed to &lt;code&gt;logout!&lt;/code&gt; with &lt;code&gt;properties&lt;/code&gt; and then creating a route&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(GET "/after-logout" [] (layout (after-logout-view)))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;and view.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(defn after-logout-view []&lt;br /&gt; [:div&lt;br /&gt;  [:h3 "Logout"]&lt;br /&gt;  [:p "You are no longer logged in!"]&lt;br /&gt;  [:div (link-to "home" "Home")]])&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;In all the changes that have been made so far, a pattern is emerging; add components in the form of middleware or parametrized routes then adapt it to our project. This same pattern will be used in the next section to add channel security.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Channel security&lt;/h3&gt;&lt;br /&gt;One thing that you may have noticed is that even though SSL is enabled, there is no way to control when it is used and when not. The goal in this application is to secure passwords sent from the client to the server and, because of the additional delay, to use SSL on as few pages as possible. This may be done by adding the &lt;code&gt;with-secure-channel&lt;/code&gt; middleware which takes four parameters: the routes to be wrapped, a security configuration, the port and the SSL port. After adding this middleware, the &lt;code&gt;app&lt;/code&gt; var definition now looks like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(def app (-&gt; my-routes&lt;br /&gt;            (with-security basic-auth)&lt;br /&gt;            wrap-stateful-session&lt;br /&gt;            (wrap-file "public")&lt;br /&gt;            (with-secure-channel security-config 8080 8443)))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;The security configuration &lt;code&gt;security-config&lt;/code&gt; is a vector of pairs. Each pair is a regular expression literal followed by a configuration. We use a vector here instead of a map because each entry is checked against the current URI in order with the first match being selected.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(def security-config&lt;br /&gt;     [#"/login.*" :ssl&lt;br /&gt;      #".*.css|.*.png" :any-channel&lt;br /&gt;      #".*" :nossl])&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Three keywords are used to represent the three kinds of channel security: &lt;code&gt;:ssl&lt;/code&gt;, &lt;code&gt;:nossl&lt;/code&gt; and &lt;code&gt;:any-channel&lt;/code&gt;. The above configuration causes the login screen to always be accessed through SSL, images and stylesheets to go over any channel and everything else to go through standard http.&lt;br /&gt;&lt;br /&gt;A future post will show how this same vector may be used to authorized access based on URI patterns.&lt;br /&gt;&lt;br /&gt;If you did not follow along, you may want to take a look at the &lt;a href="http://github.com/brentonashworth/sandbar-examples/blob/master/security/src/sandbar/examples/part_two/complete.clj"&gt;final version of the source for this exmaple&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Conclusion&lt;/h3&gt;&lt;br /&gt;Progress has been made, but this app is still not secure. Passwords should not be hard coded into an application like this. The application may be improved by having a way to easily assign different passwords to each user and store them securely. There will be at least two more posts in this series; one them will cover some of the new features of Sandbar which can help make this easy for the most common cases. The other will demonstrate how to authorize access to resources based on URI patterns.&lt;div class="blogger-post-footer"&gt;&lt;img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/4851261502438710182-5545562259451614697?l=formpluslogic.blogspot.com" alt="" /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/clojure?a=549FnZPVGWY:cXDsSQPnvw4:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/clojure?a=549FnZPVGWY:cXDsSQPnvw4:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/clojure/~4/549FnZPVGWY" height="1" width="1"/&gt;</content>
		<author>
			<name>Brenton Ashworth</name>
			<email>noreply@blogger.com</email>
			<uri>http://formpluslogic.blogspot.com/</uri>
		</author>
		<source>
			<title type="html">Form plus Logic</title>
			<link rel="self" href="http://formpluslogic.blogspot.com/feeds/posts/default" />
			<id>tag:blogger.com,1999:blog-4851261502438710182</id>
			<updated>2010-08-23T16:01:05+00:00</updated>
		</source>
	<feedburner:origLink>http://formpluslogic.blogspot.com/2010/08/securing-clojure-web-applications-with.html</feedburner:origLink></entry>

	<entry xml:lang="en">
		<title type="html">This weekend in the intertweets (Aug 22nd Ed)</title>
		<link href="http://feedproxy.google.com/~r/clojure/~3/FgphG_KB3Pw/" />
		<id>http://disclojure.org/?p=1112</id>
		<updated>2010-08-23T07:33:56+00:00</updated>
		<content type="html">&lt;ul&gt;
&lt;li&gt;32 days after Leiningen 1.2.0: Leiningen 1.3.0 is released (&lt;a href="http://groups.google.com/group/clojure/browse_thread/thread/6780a2571c2b3336"&gt;here&lt;/a&gt;, via @&lt;a href="http://twitter.com/technomancy" rel="nofollow" target="_blank" title="View technomancy's Twitter Profile"&gt;technomancy&lt;/a&gt;) &amp;#8212; Multiple connections to the same REPL, task chaining, user-level plugins, and shell script launchers for your jar files.&lt;/li&gt;
&lt;li&gt;Clojure, concurrency and silver bullets (&lt;a href="http://beust.com/weblog/2010/08/19/clojure-concurrency-and-silver-bullets/"&gt;here&lt;/a&gt;, via @&lt;a href="http://twitter.com/cbeust" rel="nofollow" target="_blank" title="View cbeust's Twitter Profile"&gt;cbeust&lt;/a&gt;) &amp;#8212; Cedric Beust, the author of amongst other things TestNG, comments on Bob Martin&amp;#8217;s article&amp;#8221;Why Clojure?&amp;#8221; and argues that clojure is no silver bullet when it comes to concurrency, arguing that straight Java with the Concurrent library is better.&lt;/li&gt;
&lt;li&gt;Modularization of #&lt;a href="http://search.twitter.com/search?q=%23clojure" rel="nofollow" target="_blank" title="Search Twitter for "&gt;clojure&lt;/a&gt; contrib is complete; lib authors please read (&lt;a href="http://groups.google.com/group/clojure/msg/c5cdfec990efb6f4"&gt;here&lt;/a&gt;, via @&lt;a href="http://twitter.com/stuartsierra" rel="nofollow" target="_blank" title="View stuartsierra's Twitter Profile"&gt;stuartsierra&lt;/a&gt;) &amp;#8212; This will allow authors to provide updates to each library in clojure.contrib much faster than before.&lt;/li&gt;
&lt;li&gt;There are two kind of databases, those that can do map-reduce queries in Clojure on those that don&amp;#8217;t (&lt;a href="http://videlalvaro.github.com/2010/08/riak-map-reduce-queries-in-clojure.html"&gt;here&lt;/a&gt;, via @&lt;a href="http://twitter.com/old_sound" rel="nofollow" target="_blank" title="View old_sound's Twitter Profile"&gt;old_sound&lt;/a&gt;) &amp;#8212; The author attempts to using Clojure to perform the computations related to ma-preduce in &lt;a href="http://www.basho.com/Riak.html"&gt;Riak&lt;/a&gt;. Note that you can already do this in &lt;a href="http://couchdb.apache.org/"&gt;CouchDB&lt;/a&gt; via &lt;a href="http://github.com/ashafa/clutch"&gt;clutch&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;rolled the SIGHUP config reloading business for #&lt;a href="http://search.twitter.com/search?q=%23clojure" rel="nofollow" target="_blank" title="Search Twitter for "&gt;clojure&lt;/a&gt; into a library (&lt;a href="http://github.com/alandipert/reconfig"&gt;here&lt;/a&gt;, via @&lt;a href="http://twitter.com/alandipert" rel="nofollow" target="_blank" title="View alandipert's Twitter Profile"&gt;alandipert&lt;/a&gt;) &amp;#8212; &amp;#8220;Reload configuration files in Clojure daemons when the JVM receives a SIGHUP. Configuration files are Clojure code, and can contain any Clojure data structures&amp;#8221;. Un*x only.&lt;/li&gt;
&lt;li&gt;any sufficiently advanced magic is indistinguishable from #&lt;a href="http://search.twitter.com/search?q=%23clojure" rel="nofollow" target="_blank" title="Search Twitter for "&gt;clojure&lt;/a&gt; (via @&lt;a href="http://twitter.com/alandipert" rel="nofollow" target="_blank" title="View alandipert's Twitter Profile"&gt;alandipert&lt;/a&gt;) &amp;#8212; And with this, somebody in the Internet will call you a &amp;#8216;fanboy&amp;#8217;.&lt;/li&gt;
&lt;li&gt;A Clojurist&amp;#8217;s Guide to Java (&lt;a href="http://copperthoughts.com/p/clojurists-guide-to-java/"&gt;here&lt;/a&gt;, via @&lt;a href="http://twitter.com/ihodes" rel="nofollow" target="_blank" title="View ihodes's Twitter Profile"&gt;ihodes&lt;/a&gt;) &amp;#8212; From the article: &amp;#8220;it should serve as a &amp;#8220;Getting Started with Java from Clojure&amp;#8221; guide that will hopefully enable you to more easily navigate the Java documentation and use Java in your Clojure projects when the need arises&amp;#8221;&lt;/li&gt;
&lt;li&gt;Clojure in Python (&lt;a href="http://framegen.wordpress.com/2010/08/22/clojure-in-python/"&gt;here&lt;/a&gt;, via @&lt;a href="http://twitter.com/HNTweets" rel="nofollow" target="_blank" title="View HNTweets's Twitter Profile"&gt;HNTweets&lt;/a&gt;) &amp;#8212; What do you do if Clojure takes to long to start (or re-start) when hosted in Google App Engine? Rewrite  Clojure in Python, of course, since Python starts way faster!&lt;/li&gt;
&lt;li&gt;Clojure programmers don&amp;#8217;t write their apps in Clojure. They write the language that they use to write their apps in Clojure. (via @&lt;a href="http://twitter.com/fogus" rel="nofollow" target="_blank" title="View fogus's Twitter Profile"&gt;fogus&lt;/a&gt;) &amp;#8212; I think it should read &amp;#8220;Good Clojure programmers&amp;#8230;&amp;#8221;, my code doesn&amp;#8217;t quite look like that (yet)&lt;/li&gt;
&lt;li&gt;equiv branch has been merged to #&lt;a href="http://search.twitter.com/search?q=%23clojure" rel="nofollow" target="_blank" title="Search Twitter for "&gt;clojure&lt;/a&gt; master branch. primitive args have arrived.(&lt;a href="http://www.assembla.com/wiki/show/clojure/Enhanced_Primitive_Support"&gt;here&lt;/a&gt;, via @&lt;a href="http://twitter.com/wmacgyver" rel="nofollow" target="_blank" title="View wmacgyver's Twitter Profile"&gt;wmacgyver&lt;/a&gt;) &amp;#8212; Get ready to see your Clojure code fly even faster!&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/disclojure?a=pI2s-13AU_Q:qktR0_RsWOo:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/disclojure?d=yIl2AUoC8zA" border="0" /&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/disclojure?a=pI2s-13AU_Q:qktR0_RsWOo:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/disclojure?i=pI2s-13AU_Q:qktR0_RsWOo:D7DqB2pKExk" border="0" /&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/disclojure?a=pI2s-13AU_Q:qktR0_RsWOo:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/disclojure?i=pI2s-13AU_Q:qktR0_RsWOo:V_sGLiPBpWU" border="0" /&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/disclojure?a=pI2s-13AU_Q:qktR0_RsWOo:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/disclojure?i=pI2s-13AU_Q:qktR0_RsWOo:gIN9vFwOqvQ" border="0" /&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/disclojure/~4/pI2s-13AU_Q" height="1" width="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/clojure?a=FgphG_KB3Pw:qktR0_RsWOo:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/clojure?a=FgphG_KB3Pw:qktR0_RsWOo:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/clojure/~4/FgphG_KB3Pw" height="1" width="1"/&gt;</content>
		<author>
			<name>Toni Batchelli</name>
			<uri>http://disclojure.org</uri>
		</author>
		<source>
			<title type="html">disclojure: all things clojure</title>
			<subtitle type="html">public disclosure of all things Clojure</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/disclojure" />
			<id>http://feeds.feedburner.com/disclojure</id>
			<updated>2010-09-03T08:30:53+00:00</updated>
		</source>
	<feedburner:origLink>http://feedproxy.google.com/~r/disclojure/~3/pI2s-13AU_Q/</feedburner:origLink></entry>

	<entry xml:lang="en">
		<title type="html">Penumbra (unknown severity): Another breaking change in leiningen</title>
		<link href="http://feedproxy.google.com/~r/clojure/~3/ZUwjE6Vbh8E/" />
		<id>http://github.com/ztellman/penumbra/issues/#issue/28</id>
		<updated>2010-08-23T00:00:00+00:00</updated>
		<content type="html">Penumbra (unknown severity): Another breaking change in leiningen&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/clojure?a=ZUwjE6Vbh8E:GTN1kArecUM:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/clojure?a=ZUwjE6Vbh8E:GTN1kArecUM:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/clojure?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/clojure/~4/ZUwjE6Vbh8E" height="1" width="1"/&gt;</content>
		<author>
			<name>BugSpy</name>
			<uri>http://bugspy.net</uri>
		</author>
		<source>
			<title type="html">BugSpy.net - Reports By Tag: clojure</title>
			<link rel="self" href="http://bugspy.net/tag/clojure/?format=rss" />
			<id>http://bugspy.net/tag/clojure/?format=rss</id>
			<updated>2010-09-03T21:01:14+00:00</updated>
		</source>
	<feedburner:origLink>http://github.com/ztellman/penumbra/issues/#issue/28</feedburner:origLink></entry>

</feed>
