<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Best In Class Atom Feed</title>
  <subtitle>Best In Class - Software Innovator</subtitle>
  <link type="application/atom+xml" rel="self" href="http://www.bestinclass.dk/atom.xml" />
  <updated>2012-04-15T21:45:42+08:00</updated>
  <id>tag:www.bestinclass.dk,2010-01-01:/atom.xml</id>
  <author>
    <name>Lau Jensen</name>
    <email>lau.jensen@bestinclass.dk</email>
  </author>
  <entry>
    <title>Best In Class: Google Code Jam #1</title>
    <link href="http://www.bestinclass.dk/index.clj/2012/04/google-code-jam-1.html" />
    <id>http://www.bestinclass.dk/index.clj/2012/04/google-code-jam-1.html</id>
    <updated>2012-04-15T09:45:41Z</updated>
    <summary type="html">
    &lt;h1 id="title"&gt;Google Code Jam #1&lt;/h1&gt;
    &lt;div id="pubdate"&gt;2012-04-15 09:45:41&lt;/div&gt;
    &lt;img id="thumb" src="http://www.bestinclass.dk/wp-content/uploads/avatars/1334518976_social_google_box.png" /&gt;
  &lt;div id="box"&gt;&lt;p&gt;Google is getting ready for another Code Jam and here I'll provide the solution to their first challenge&lt;/p&gt;&lt;/div&gt;</summary>
    <content type="html">&lt;p&gt;These Google challenges are typically a great suit for functional languages as the point is often to arrive at an algorithm which you can apply to the problem at hand. When reviewing the solutions, its interesting to compare high/low level languages as well as imperative/funtional languages. After having solved the problem, I went to find other solutions on Google and here is one I came across written in Java: &lt;a href="http://www.harshadura.net/2012/04/googlecodejam-my-answer-algorithm-for.html"&gt;Java Solution&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;The Java Solution&lt;/h1&gt;

&lt;p&gt;When reading the solution I notice the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The developer spent 1.5 hours on it&lt;/li&gt;
&lt;li&gt;A large part of the code is spent on reading/writing files&lt;/li&gt;
&lt;li&gt;The solution itself is handwritten - the program does not learn from the data&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;The Problem&lt;/h1&gt;

&lt;p&gt;You can read the official explanation here: &lt;a href="http://code.google.com/codejam/contest/1460488/dashboard"&gt;Challenge #1&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The short version is this: Google provides you with an unreadable language for which you must develop a translator. In order to make the translator you get 3 lines of pre/post translated text as well as 3 character mappings. The task is then to discover the remaining 24 mappings.&lt;/p&gt;

&lt;h1&gt;Repl Play&lt;/h1&gt;

&lt;p&gt;Since we're trying to produce mappings we need to construct a hash map where the keys are english characters and the values are the &lt;em&gt;Googleresesian&lt;/em&gt; counterparts, so lets begin by loading the sample:&lt;/p&gt;

&lt;pre style="color: #eeeeec; background-color: #1c232c; font-size: 9pt"&gt;
(&lt;span style="color: #729fcf;"&gt;def&lt;/span&gt; &lt;span style="color: #edd400;"&gt;input&lt;/span&gt; [&lt;span style="color: #d3ef0b;"&gt;"ejp mysljylc kd kxveddknmc re jsicpdrysi"&lt;/span&gt;
            &lt;span style="color: #d3ef0b;"&gt;"rbcpc ypc rtcsra dkh wyfrepkym veddknkmkrkcd"&lt;/span&gt;
            &lt;span style="color: #d3ef0b;"&gt;"de kr kd eoya kw aej tysr re ujdr lkgc jv"&lt;/span&gt;])

(&lt;span style="color: #729fcf;"&gt;def&lt;/span&gt; &lt;span style="color: #edd400;"&gt;google&lt;/span&gt; [&lt;span style="color: #d3ef0b;"&gt;"our language is impossible to understand"&lt;/span&gt;
             &lt;span style="color: #d3ef0b;"&gt;"there are twenty six factorial possibilities"&lt;/span&gt;
             &lt;span style="color: #d3ef0b;"&gt;"so it is okay if you want to just give up"&lt;/span&gt;])&lt;/pre&gt;

In order to produce the initial mapping all we have to do is traverse each character in each string and store the relation:

&lt;pre style="color: #eeeeec; background-color: #1c232c; font-size: 9pt"&gt;
(&lt;span style="color: #729fcf;"&gt;-&amp;gt;&amp;gt;&lt;/span&gt; (&lt;span style="color: #e0f42f;"&gt;map&lt;/span&gt; #(&lt;span style="color: #e0f42f;"&gt;map&lt;/span&gt; (&lt;span style="color: #e0f42f;"&gt;fn&lt;/span&gt; [i g] (&lt;span style="color: #e0f42f;"&gt;hash-map&lt;/span&gt; i g)) %1 %2) input google)
     flatten
     (&lt;span style="color: #e0f42f;"&gt;apply&lt;/span&gt; merge))
{\space \space, \a \y, \b \h, \c \e, \d \s, \e \o, \f \c, \g \v, \h \x, \i \d, \j \u, \k \i, \l \g, \m \l, \n \b, \o \k, \p \r, \r \t, \s \n, \t \w, \u \j, \v \p, \w \f, \x \m, \y \a}&lt;/pre&gt;

The outer map walks the strings, the inner map walks the characters of each string, returning a hash-map with the key/val pair. All that's needed is now to manually add the mapping given by Google in the explanation of the problem:

&lt;pre style="color: #eeeeec; background-color: #1c232c; font-size: 9pt"&gt;
(&lt;span style="color: #729fcf;"&gt;def&lt;/span&gt; &lt;span style="color: #edd400;"&gt;dict&lt;/span&gt; (&lt;span style="color: #e0f42f;"&gt;assoc&lt;/span&gt; *1 \z \q))&lt;/pre&gt;

The *1 is simply short-hand for "the last result of evaluation", in this case the mappings. With the dictionary, dict, defined, we can look up simply by calling it as a function

&lt;pre style="color: #eeeeec; background-color: #1c232c; font-size: 9pt"&gt;
(dict \a)
&amp;gt; \y
&lt;/pre&gt;

&lt;p&gt;Here we see that an "a" translates to a "y". To make a translate function all we have to do is call &lt;em&gt;dict&lt;/em&gt; on every character and then return the resulting sequence of characters as a string:&lt;/p&gt;

&lt;pre style="color: #eeeeec; background-color: #1c232c; font-size: 9pt"&gt;
(&lt;span style="color: #729fcf;"&gt;defn&lt;/span&gt; &lt;span style="color: #edd400;"&gt;translate&lt;/span&gt; [in]
  (&lt;span style="color: #729fcf;"&gt;-&amp;gt;&amp;gt;&lt;/span&gt; (&lt;span style="color: #e0f42f;"&gt;map&lt;/span&gt; #(dict %) in) (&lt;span style="color: #e0f42f;"&gt;apply&lt;/span&gt; str)))&lt;/pre&gt;

&lt;p&gt;Now all of the work is basically done and all we need to do is apply our translate function to the dataset and properly format our output:&lt;/p&gt;

&lt;pre style="color: #eeeeec; background-color: #1c232c; font-size: 9pt"&gt;
(&lt;span style="color: #729fcf;"&gt;def&lt;/span&gt; &lt;span style="color: #edd400;"&gt;input&lt;/span&gt; (&lt;span style="color: #729fcf;"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color: #d3ef0b;"&gt;"A-small-practice.in"&lt;/span&gt; reader line-seq rest))
&amp;gt; input&lt;/pre&gt;

&lt;p&gt;The input file to Google is cast to a reader then read as a sequence of lines, dismissing the first line which simply contains an integer which we don't need.&lt;/p&gt;

&lt;p&gt;With a sequence of strings in &lt;em&gt;input&lt;/em&gt; we could simply run &lt;strong&gt;(map translate input)&lt;/strong&gt; and that would produce the correct translation, however to properly format the output we need to add an index and some text:&lt;/p&gt;

&lt;pre style="color: #eeeeec; background-color: #1c232c; font-size: 9pt"&gt;
(&lt;span style="color: #729fcf;"&gt;doseq&lt;/span&gt; [[idx txt] (&lt;span style="color: #e0f42f;"&gt;map&lt;/span&gt; #(&lt;span style="color: #e0f42f;"&gt;vector&lt;/span&gt; %1 %2) (&lt;span style="color: #e0f42f;"&gt;range&lt;/span&gt;) s)] 
                          (&lt;span style="color: #e0f42f;"&gt;println&lt;/span&gt; (&lt;span style="color: #e0f42f;"&gt;str&lt;/span&gt; &lt;span style="color: #d3ef0b;"&gt;"Case #"&lt;/span&gt; (&lt;span style="color: #e0f42f;"&gt;inc&lt;/span&gt; idx) &lt;span style="color: #d3ef0b;"&gt;": "&lt;/span&gt; (translate txt))))
&lt;span style="color: #d3ef0b;"&gt;Case&lt;/span&gt; #1: our language is impossible to understand
&lt;span style="color: #d3ef0b;"&gt;Case&lt;/span&gt; #2: there are twenty six factorial possibilities
&lt;span style="color: #d3ef0b;"&gt;Case&lt;/span&gt; #3: so it is okay if you want to just give up
&lt;span style="color: #d3ef0b;"&gt;Case&lt;/span&gt; #4: xoggk d yl wxo vkkvgo ekso uyl wonw sywy
&lt;span style="color: #d3ef0b;"&gt;Case&lt;/span&gt; #5: xkf yto akj
&lt;span style="color: #d3ef0b;"&gt;Case&lt;/span&gt; #6: yabba dabba yabba dabba yabba dabba yabba dabba yabba dabba yabba dabba yabba dabba yabba dooooooooo
&lt;span style="color: #d3ef0b;"&gt;Case&lt;/span&gt; #7: a b c d e f g h i j k l m n o p q r s t u v y w x y z now i know my abcs
&lt;span style="color: #d3ef0b;"&gt;Case&lt;/span&gt; #8: next time wont you sing with me
&lt;span style="color: #d3ef0b;"&gt;Case&lt;/span&gt; #9: for those who speak in a tongue do not speak to other people
&lt;span style="color: #d3ef0b;"&gt;Case&lt;/span&gt; #10: nobody understands them since they are speaking mysteries in the spirit
&lt;span style="color: #d3ef0b;"&gt;Case&lt;/span&gt; #11: this is so exciting i have to go the bathroom
&lt;span style="color: #d3ef0b;"&gt;Case&lt;/span&gt; #12: it was the best of times it was the blurst of times
&lt;span style="color: #d3ef0b;"&gt;Case&lt;/span&gt; #13: let lips do what hands do
&lt;span style="color: #d3ef0b;"&gt;Case&lt;/span&gt; #14: this here is gunpowder activated twenty seven caliber full auto no kickback nailthrowing mayhem
&lt;span style="color: #d3ef0b;"&gt;Case&lt;/span&gt; #15: i have bested fruit spike and moon now i shall best you the guy
&lt;span style="color: #d3ef0b;"&gt;Case&lt;/span&gt; #16: oh hai im in ur computer eating your cheezburgers and googleresing your textz
&lt;span style="color: #d3ef0b;"&gt;Case&lt;/span&gt; #17: an eye for an eye and a pigeon for a pigeon
&lt;span style="color: #d3ef0b;"&gt;Case&lt;/span&gt; #18: all your base are belong to error the spoony bard
&lt;span style="color: #d3ef0b;"&gt;Case&lt;/span&gt; #19: you pissed off the chicken lady
&lt;span style="color: #d3ef0b;"&gt;Case&lt;/span&gt; #20: now is the summer of our lack of discontent
&lt;span style="color: #d3ef0b;"&gt;Case&lt;/span&gt; #21: by the pricking of my thumbs something wicked this way comes
&lt;span style="color: #d3ef0b;"&gt;Case&lt;/span&gt; #22: in a world of direwolves and lions sometimes the rarest creature is a friend
&lt;span style="color: #d3ef0b;"&gt;Case&lt;/span&gt; #23: greetings cheese popsicle the number you have dialed is currently out of porkchops
&lt;span style="color: #d3ef0b;"&gt;Case&lt;/span&gt; #24: why do programmers always mix up halloween and christmas
&lt;span style="color: #d3ef0b;"&gt;Case&lt;/span&gt; #25: im commander shepard and this is my favorite problem on the google code jam
&lt;span style="color: #d3ef0b;"&gt;Case&lt;/span&gt; #26: f of two equals f of one equals one
&lt;span style="color: #d3ef0b;"&gt;Case&lt;/span&gt; #27: for i between three and n f of i equals f of i minus one plus f of i minus two
&lt;span style="color: #d3ef0b;"&gt;Case&lt;/span&gt; #28: how are you holding up because im a potato
&lt;span style="color: #d3ef0b;"&gt;Case&lt;/span&gt; #29: dr zaius dr zaius dr zaius dr zaius ooooooooooooh dr zaius
&lt;span style="color: #d3ef0b;"&gt;Case&lt;/span&gt; #30: whoooooooooooooooooooaaaaaaaaa i know c plus plus&lt;/pre&gt;

&lt;h1&gt;Conclusion&lt;/h1&gt;

&lt;p&gt;Working in a high-level language allow you to express your thoughts very quickly and succintly. Over time, working with high-level languages, changes the way you think about problems allowing you more easily to see the bigger picture. To this end Clojure has been an excellent companion.&lt;/p&gt;

&lt;p&gt;The above program took only a few minutes to write and never made it as far as a file, it was simply written in the repl while playing with the data.&lt;/p&gt;&lt;br /&gt;
&lt;div style="background: url(&amp;quot;/images/authorbg.png&amp;quot;) no-repeat scroll left top transparent; width: 705px; height: 175px; padding: 10px;"&gt;
  &lt;a href="http://feeds.feedburner.com/bestinclass-the-blog" target="_blank" style="float:right; margin-top: 70px; margin-right: 60px;"&gt;&lt;img alt="View the RSS feed" src="/images/rss.png" /&gt;&lt;/a&gt;
    &lt;a href="http://twitter.com/laujensen" target="_blank" style="float:right; margin-top: 70px; margin-right: 60px;"&gt;&lt;img alt="Follow Lau on Twitter" src="/images/twitter.png" /&gt;&lt;/a&gt;
  &lt;h1&gt;About the author:&lt;/h1&gt;
  &lt;p style="width: 400px"&gt;&lt;b&gt;Lau Jensen&lt;/b&gt; is the founder and owner of Best In Class a danish consultancy company which specializes in Clojure development. &lt;/p&gt;
  &lt;p style="width: 400px; margin-top: 1px;"&gt;&lt;b&gt;Lau&lt;/b&gt; is also one of the instructors driving the &lt;a href="http://www.conj-labs.eu"&gt;Conj Labs&lt;/a&gt; initiative. If you would like to be notified once new blogposts are published, you can follow Lau on &lt;a href="http://twitter.com/laujensen"&gt;Twitter.&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
</content>
  </entry><entry>
    <title>Best In Class: Building a Social Media site</title>
    <link href="http://www.bestinclass.dk/index.clj/2011/01/building-a-social-media-site.html" />
    <id>http://www.bestinclass.dk/index.clj/2011/01/building-a-social-media-site.html</id>
    <updated>2011-01-09T10:30:26Z</updated>
    <summary type="html">
    &lt;h1 id="title"&gt;Building a Social Media site&lt;/h1&gt;
    &lt;div id="pubdate"&gt;2011-01-09 10:30:26&lt;/div&gt;
    &lt;img src="http://www.bestinclass.dk/wp-content/uploads/avatars/socialmedia.png" id="thumb" /&gt;
  &lt;div id="box"&gt;
	&lt;p&gt;
		Following my now dated "Reddit Clone" tutorial, I've made a revised version which demonstrates how easy it is to build interactive websites using  Moustache, Enlive and ClojureQL. &lt;/p&gt;
	&lt;p&gt;
		 &lt;/p&gt;
&lt;/div&gt;
</summary>
    <content type="html">&lt;h1&gt;
	Preface&lt;/h1&gt;
&lt;p&gt;
	After many requests I've decided it would be a good idea to build a &lt;strong&gt;Clojure Driven Social Media&lt;/strong&gt; &lt;strong&gt;Community&lt;/strong&gt; website using some of the hottest tools available today to help us pull together. If you've read my old "&lt;a target="_blank" href="http://bestinclass.dk/index.clj/2010/02/reddit-clone-in-10-minutes-and-91-lines-of-clojure.html"&gt;Reddit Clone in 10 minutes and 91 lines of Clojure&lt;/a&gt;" this is on a very similar thread, however the core is now 98 lines and the tools have been updated. Lets get to it.&lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;h1&gt;
	Frontpage&lt;/h1&gt;
&lt;p&gt;
	We begin by simply getting a webserver (Jetty) up and running and set to render our frontpage. One of the great things about developing webapps using Ring/Moustache is that you can construct your source such that when loaded on your development machine, it'll spawn a Jetty instance, but when loaded as a war file it will run as a Servlet within Tomcat. This makes for insanely rapid development/deployment. First, we'll start building our namespace which contains all of our web templates - I usually start by building a master page, which all (most) other pages are derived from:&lt;/p&gt;
&lt;h3&gt;
	HTML&lt;/h3&gt;
&lt;pre&gt;
&amp;lt;&lt;span style="color: rgb(18, 65, 222);"&gt;!DOCTYPE&lt;/span&gt; html&amp;gt;
&amp;lt;&lt;span style="color: rgb(255, 66, 66);"&gt;html&lt;/span&gt;&amp;gt;
  &amp;lt;&lt;span style="color: rgb(255, 66, 66);"&gt;head&lt;/span&gt;&amp;gt;
    &amp;lt;&lt;span style="color: rgb(255, 66, 66);"&gt;meta&lt;/span&gt; &lt;span style="color: rgb(147, 74, 181);"&gt;http-equiv&lt;/span&gt;=&lt;span style="color: rgb(143, 143, 143);"&gt;"Content-Type"&lt;/span&gt; &lt;span style="color: rgb(147, 74, 181);"&gt;content&lt;/span&gt;=&lt;span style="color: rgb(143, 143, 143);"&gt;"text/html; charset=UTF-8"&lt;/span&gt; /&amp;gt;
    &amp;lt;&lt;span style="color: rgb(255, 66, 66);"&gt;title&lt;/span&gt;&amp;gt;&lt;span style="font-weight: bold; text-decoration: underline;"&gt;Clojure Driven Social Site&lt;/span&gt;&amp;lt;/&lt;span style="color: rgb(255, 66, 66);"&gt;title&lt;/span&gt;&amp;gt;
    &amp;lt;&lt;span style="color: rgb(255, 66, 66);"&gt;script&lt;/span&gt; &lt;span style="color: rgb(147, 74, 181);"&gt;type&lt;/span&gt;=&lt;span style="color: rgb(143, 143, 143);"&gt;"text/javascript"&lt;/span&gt; &lt;span style="color: rgb(147, 74, 181);"&gt;src&lt;/span&gt;=&lt;span style="color: rgb(143, 143, 143);"&gt;"/scripts/jquery.js"&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style="color: rgb(255, 66, 66);"&gt;script&lt;/span&gt;&amp;gt;
    &amp;lt;&lt;span style="color: rgb(255, 66, 66);"&gt;script&lt;/span&gt; &lt;span style="color: rgb(147, 74, 181);"&gt;class&lt;/span&gt;=&lt;span style="color: rgb(143, 143, 143);"&gt;"import"&lt;/span&gt; &lt;span style="color: rgb(147, 74, 181);"&gt;type&lt;/span&gt;=&lt;span style="color: rgb(143, 143, 143);"&gt;"text/javascript"&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style="color: rgb(255, 66, 66);"&gt;script&lt;/span&gt;&amp;gt;
    &amp;lt;&lt;span style="color: rgb(255, 66, 66);"&gt;link&lt;/span&gt; &lt;span style="color: rgb(147, 74, 181);"&gt;rel&lt;/span&gt;=&lt;span style="color: rgb(143, 143, 143);"&gt;"stylesheet"&lt;/span&gt; &lt;span style="color: rgb(147, 74, 181);"&gt;href&lt;/span&gt;=&lt;span style="color: rgb(143, 143, 143);"&gt;"/css/main.css"&lt;/span&gt; &lt;span style="color: rgb(147, 74, 181);"&gt;type&lt;/span&gt;=&lt;span style="color: rgb(143, 143, 143);"&gt;"text/css"&lt;/span&gt; &lt;span style="color: rgb(147, 74, 181);"&gt;media&lt;/span&gt;=&lt;span style="color: rgb(143, 143, 143);"&gt;"screen"&lt;/span&gt; /&amp;gt;
    &amp;lt;&lt;span style="color: rgb(255, 66, 66);"&gt;link&lt;/span&gt; &lt;span style="color: rgb(147, 74, 181);"&gt;class&lt;/span&gt;=&lt;span style="color: rgb(143, 143, 143);"&gt;"style"&lt;/span&gt;  &lt;span style="color: rgb(147, 74, 181);"&gt;rel&lt;/span&gt;=&lt;span style="color: rgb(143, 143, 143);"&gt;"stylesheet"&lt;/span&gt; &lt;span style="color: rgb(147, 74, 181);"&gt;type&lt;/span&gt;=&lt;span style="color: rgb(143, 143, 143);"&gt;"text/css"&lt;/span&gt; &lt;span style="color: rgb(147, 74, 181);"&gt;media&lt;/span&gt;=&lt;span style="color: rgb(143, 143, 143);"&gt;"screen"&lt;/span&gt; /&amp;gt;
  &amp;lt;/&lt;span style="color: rgb(255, 66, 66);"&gt;head&lt;/span&gt;&amp;gt;

  &amp;lt;&lt;span style="color: rgb(255, 66, 66);"&gt;body&lt;/span&gt;&amp;gt;
    &amp;lt;&lt;span style="color: rgb(255, 66, 66);"&gt;div&lt;/span&gt; &lt;span style="color: rgb(147, 74, 181);"&gt;class&lt;/span&gt;=&lt;span style="color: rgb(143, 143, 143);"&gt;"header"&lt;/span&gt;&amp;gt;
      &amp;lt;&lt;span style="color: rgb(255, 66, 66);"&gt;img&lt;/span&gt; &lt;span style="color: rgb(147, 74, 181);"&gt;src&lt;/span&gt;=&lt;span style="color: rgb(143, 143, 143);"&gt;"/images/logo.jpg"&lt;/span&gt;/&amp;gt;
    &amp;lt;/&lt;span style="color: rgb(255, 66, 66);"&gt;div&lt;/span&gt;&amp;gt;

    &amp;lt;&lt;span style="color: rgb(255, 66, 66);"&gt;div&lt;/span&gt; &lt;span style="color: rgb(147, 74, 181);"&gt;id&lt;/span&gt;=&lt;span style="color: rgb(143, 143, 143);"&gt;"content"&lt;/span&gt;&amp;gt;
    &amp;lt;/&lt;span style="color: rgb(255, 66, 66);"&gt;div&lt;/span&gt;&amp;gt;

    &amp;lt;&lt;span style="color: rgb(255, 66, 66);"&gt;div&lt;/span&gt; &lt;span style="color: rgb(147, 74, 181);"&gt;class&lt;/span&gt;=&lt;span style="color: rgb(143, 143, 143);"&gt;"footer"&lt;/span&gt;&amp;gt;
      &amp;lt;&lt;span style="color: rgb(255, 66, 66);"&gt;a&lt;/span&gt; &lt;span style="color: rgb(147, 74, 181);"&gt;href&lt;/span&gt;=&lt;span style="color: rgb(143, 143, 143);"&gt;"/"&lt;/span&gt;&amp;gt;home&amp;lt;/&lt;span style="color: rgb(255, 66, 66);"&gt;a&lt;/span&gt;&amp;gt;
      &amp;lt;&lt;span style="color: rgb(255, 66, 66);"&gt;a&lt;/span&gt; &lt;span style="color: rgb(147, 74, 181);"&gt;href&lt;/span&gt;=&lt;span style="color: rgb(143, 143, 143);"&gt;"/submit"&lt;/span&gt;&amp;gt;submit a link&amp;lt;/&lt;span style="color: rgb(255, 66, 66);"&gt;a&lt;/span&gt;&amp;gt;
      &amp;lt;&lt;span style="color: rgb(255, 66, 66);"&gt;a&lt;/span&gt; &lt;span style="color: rgb(147, 74, 181);"&gt;id&lt;/span&gt;=&lt;span style="color: rgb(143, 143, 143);"&gt;"loginout"&lt;/span&gt;/&amp;gt;
    &amp;lt;/&lt;span style="color: rgb(255, 66, 66);"&gt;div&lt;/span&gt;&amp;gt;

  &amp;lt;/&lt;span style="color: rgb(255, 66, 66);"&gt;body&lt;/span&gt;&amp;gt;
&amp;lt;/&lt;span style="color: rgb(255, 66, 66);"&gt;html&lt;/span&gt;&amp;gt;
&lt;/pre&gt;
&lt;p&gt;
	This HTML serves as a skeleton where &lt;a target="_blank" href="http://github.com/cgrand/enlive"&gt;Enlive&lt;/a&gt; will inject the dynamic components. Notice the places holders for &lt;strong&gt;scripts&lt;/strong&gt;, &lt;strong&gt;styles&lt;/strong&gt; and &lt;strong&gt;content&lt;/strong&gt; which Enlive will look for. What we want now, is a function which takes 3 arguments: The scripts and styles to be loaded in &lt;em&gt;&lt;strong&gt;head&lt;/strong&gt;&lt;/em&gt; and the content for the div tag with that id. In addition, we need to pass a 4th argument, which is the user session so that the Login link, becomes a Logout link if the user is already logged in - Enlive makes this trivial:&lt;/p&gt;
&lt;pre&gt;
(&lt;span style="color: rgb(18, 65, 222);"&gt;ns&lt;/span&gt; socialsite.templates
  (&lt;span style="color: rgb(152, 83, 243);"&gt;:use&lt;/span&gt; net.cgrand.enlive-html))

(deftemplate page &lt;span style="color: rgb(143, 143, 143);"&gt;"page.html"&lt;/span&gt; [session styles scripts cnt]
  [&lt;span style="color: rgb(152, 83, 243);"&gt;:link.style&lt;/span&gt;]   (clone-for [style styles]
                    (set-attr &lt;span style="color: rgb(152, 83, 243);"&gt;:href&lt;/span&gt; style))
  [&lt;span style="color: rgb(152, 83, 243);"&gt;:script.import&lt;/span&gt;] (clone-for [script scripts]
                    (set-attr &lt;span style="color: rgb(152, 83, 243);"&gt;:src&lt;/span&gt; script))
  [&lt;span style="color: rgb(152, 83, 243);"&gt;:a#loginout&lt;/span&gt;]   (&lt;span style="color: rgb(61, 61, 61);"&gt;content&lt;/span&gt;
                   (&lt;span style="color: rgb(18, 65, 222);"&gt;if&lt;/span&gt; (&lt;span style="color: rgb(152, 83, 243);"&gt;seq&lt;/span&gt; (&lt;span style="color: rgb(152, 83, 243);"&gt;:nick&lt;/span&gt; session))
                     {&lt;span style="color: rgb(152, 83, 243);"&gt;:tag&lt;/span&gt; &lt;span style="color: rgb(152, 83, 243);"&gt;:a&lt;/span&gt;, &lt;span style="color: rgb(152, 83, 243);"&gt;:attrs&lt;/span&gt; {&lt;span style="color: rgb(152, 83, 243);"&gt;:href&lt;/span&gt; &lt;span style="color: rgb(143, 143, 143);"&gt;"/logout"&lt;/span&gt;}, &lt;span style="color: rgb(152, 83, 243);"&gt;:content&lt;/span&gt; [&lt;span style="color: rgb(143, 143, 143);"&gt;"logout"&lt;/span&gt;]}
                     {&lt;span style="color: rgb(152, 83, 243);"&gt;:tag&lt;/span&gt; &lt;span style="color: rgb(152, 83, 243);"&gt;:a&lt;/span&gt;, &lt;span style="color: rgb(152, 83, 243);"&gt;:attrs&lt;/span&gt; {&lt;span style="color: rgb(152, 83, 243);"&gt;:href&lt;/span&gt; &lt;span style="color: rgb(143, 143, 143);"&gt;"/login"&lt;/span&gt;}, &lt;span style="color: rgb(152, 83, 243);"&gt;:content&lt;/span&gt; [&lt;span style="color: rgb(143, 143, 143);"&gt;"login"&lt;/span&gt;]}))
  [&lt;span style="color: rgb(152, 83, 243);"&gt;:div#content&lt;/span&gt;]  (&lt;span style="color: rgb(61, 61, 61);"&gt;content&lt;/span&gt; cnt))&lt;/pre&gt;
&lt;p&gt;
	As you can see, &lt;strong&gt;deftemplate&lt;/strong&gt; defines a template with the name 'page' based off the HTML file &lt;em&gt;&lt;strong&gt;page.html&lt;/strong&gt;&lt;/em&gt; and takes our 4 arguments which we can use in the body. In the body I use clone-for whenever I need to duplicate an item a certain number of times, set-attr when I need to set attributes and content when Im setting content. Enlive is fairly well documented, but for now all you need to know is that &lt;strong&gt;clone-for&lt;/strong&gt; works exactly like &lt;strong&gt;for&lt;/strong&gt;, so the above says "&lt;em&gt;clone for every style in styles&lt;/em&gt;" etc.&lt;/p&gt;
&lt;p&gt;
	If you're new to Enlive you're probably wondering about the way Im setting the login/logout text and its strictly a performance concern. Instead of passing an html-snippet, Im passing Enlives native datastruct, here's how I arrived at it:&lt;/p&gt;
&lt;pre&gt;
&lt;span style="color: rgb(18, 65, 222);"&gt;socialsite.templates&amp;gt; &lt;/span&gt;&lt;span style="font-weight: bold;"&gt;(html-snippet "&amp;lt;a href="/login"&amp;gt;Login&amp;lt;/a&amp;gt;")&lt;/span&gt;
({:tag :a, :attrs {:href "/login"}, :content ("Login")})
&lt;/pre&gt;
&lt;p&gt;
	Simply replace the lists with vectors or quoted lists and put that in your templates. With the template in place, we can write our handler:&lt;/p&gt;
&lt;pre&gt;
(&lt;span style="color: rgb(18, 65, 222);"&gt;defn&lt;/span&gt; &lt;span style="color: rgb(255, 66, 66);"&gt;view-frontpage&lt;/span&gt;
  [r]
  (&lt;span style="color: rgb(18, 65, 222);"&gt;-&amp;gt;&amp;gt;&lt;/span&gt; (page (&lt;span style="color: rgb(152, 83, 243);"&gt;:session&lt;/span&gt; r) nil nil &lt;span style="color: rgb(143, 143, 143);"&gt;"Welcome"&lt;/span&gt;)
       response))&lt;/pre&gt;
&lt;p&gt;
	The call to (page) returns the HTML as a seq of strings, passing that to response returns a hashmap which Ring understands. All thats left is defining a route to serve this and launch the server:&lt;/p&gt;
&lt;pre&gt;
(&lt;span style="color: rgb(18, 65, 222);"&gt;def&lt;/span&gt; &lt;span style="color: rgb(255, 66, 66);"&gt;routes&lt;/span&gt;
  (app
   (wrap-file "resources")
   [&lt;span style="color: rgb(143, 143, 143);"&gt;""&lt;/span&gt;] view-frontpage))

(&lt;span style="color: rgb(18, 65, 222);"&gt;doto&lt;/span&gt; (&lt;span style="color: rgb(165, 42, 42);"&gt;Thread.&lt;/span&gt; #(run-jetty #'routes {&lt;span style="color: rgb(152, 83, 243);"&gt;:port&lt;/span&gt; 8080})) &lt;span style="color: rgb(165, 42, 42);"&gt;.start&lt;/span&gt;)
&lt;/pre&gt;
&lt;p&gt;
	Notice that Im passing the routes argument as a var using #'. This forces Clojure to re-read the value on every read, meaning if I dynamically redef my routes while Im developing the results will show in the browser on the next reload - a must for interactive development. Here's the result:&lt;/p&gt;
&lt;p style="text-align: center;"&gt;
	&lt;img style="width: 700px; height: 536px;" src="http://www.bestinclass.dk/images/posts/social/first.png" alt="First screenshot" /&gt;&lt;/p&gt;
&lt;p&gt;
	Looks good - Partly because I used the wrap-file middleware which loads my images/css/scripts etc. You'll notice a big difference from my original &lt;a target="_blank" href="http://bestinclass.dk/index.clj/2010/02/reddit-clone-in-10-minutes-and-91-lines-of-clojure.html"&gt;Reddit clone&lt;/a&gt; in that I have now achieved a 100% separation between code and HTML. Originally I used &lt;a target="_blank" href="http://github.com/weavejester/hiccup"&gt;Hiccup&lt;/a&gt; which is a bit like PHP for Clojure in that you seamlessly mix HTML and code. If you want to dig deeper with Enlive, I suggest reading &lt;a href="http://github.com/swannodette/enlive-tutorial"&gt;this tutorial&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;h1&gt;
	Database&lt;/h1&gt;
&lt;p&gt;
	My original clone persisted everything in memory which was conveniet at the time. However with the release of &lt;a target="_blank" href="http://clojureql.org"&gt;ClojureQL 1.0.0&lt;/a&gt; it seems fitting to work with a real db backend. So here's what you can do if you have MySQL installed:&lt;/p&gt;
&lt;pre&gt;
&lt;span style="color: rgb(18, 65, 222);"&gt;mysql&amp;gt; &lt;/span&gt;&lt;span style="font-weight: bold;"&gt;create database social;&lt;/span&gt;
&lt;span style="color: rgb(18, 65, 222);"&gt;mysql&amp;gt; &lt;/span&gt;&lt;span style="font-weight: bold;"&gt;grant all privileges on social.* to "social"@"social" identified by "social";&lt;/span&gt;
&lt;span style="color: rgb(18, 65, 222);"&gt;mysql&amp;gt; &lt;/span&gt;&lt;span style="color: rgb(18, 65, 222); font-weight: bold;"&gt;CREATE TABLE `posts` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `title` varchar(255) NOT NULL,
  `upvotes` int(11) NOT NULL DEFAULT '0',
  `downvotes` int(11) NOT NULL DEFAULT '0',
  `submitter` int(11) NOT NULL,
  `url` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8;
&lt;/span&gt;&lt;span style="color: rgb(18, 65, 222);"&gt;mysql&amp;gt; &lt;/span&gt;&lt;span style="color: rgb(18, 65, 222); font-weight: bold;"&gt;CREATE TABLE `users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `fullname` varchar(255) NOT NULL,
  `nick` varchar(255) NOT NULL,
  `password` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
mysql&amp;gt; insert into posts (title,url,submitter) VALUES ("ClojureQL 1.0.0 released!", "http://clojureql.org", 1);
mysql&amp;gt; insert into users (fullname,nick,password) VALUES ("Lau Jensen", "Lau", "social");
&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;
	That will give you a new database called social, a user/pass social/social and two tables posts and users as well as your first user. As a convenience for you guys, I've put this SQL statement in the INSTALL.sql file in the Git repo linked at the bottom. (ps: This is not how you should design a production database!)&lt;/p&gt;
&lt;p&gt;
	Now we need to render the post(s) on the frontpage. In order to do that, we need to join the two tables together and sort them on the amount of upvotes each post has - ClojureQL makes this easy: First we define our connection object and reference our tables&lt;/p&gt;
&lt;pre&gt;
(&lt;span style="color: rgb(18, 65, 222);"&gt;def&lt;/span&gt; &lt;span style="color: rgb(255, 66, 66);"&gt;db&lt;/span&gt;   {&lt;span style="color: rgb(152, 83, 243);"&gt;:classname&lt;/span&gt;   &lt;span style="color: rgb(143, 143, 143);"&gt;"com.mysql.jdbc.Driver"&lt;/span&gt;
           &lt;span style="color: rgb(152, 83, 243);"&gt;:subprotocol&lt;/span&gt; &lt;span style="color: rgb(143, 143, 143);"&gt;"mysql"&lt;/span&gt;
           &lt;span style="color: rgb(152, 83, 243);"&gt;:user&lt;/span&gt;        &lt;span style="color: rgb(143, 143, 143);"&gt;"social"&lt;/span&gt;
           &lt;span style="color: rgb(152, 83, 243);"&gt;:password&lt;/span&gt;    &lt;span style="color: rgb(143, 143, 143);"&gt;"social"&lt;/span&gt;
           &lt;span style="color: rgb(152, 83, 243);"&gt;:subname&lt;/span&gt;     &lt;span style="color: rgb(143, 143, 143);"&gt;"//localhost:3306/social"&lt;/span&gt;})

(&lt;span style="color: rgb(18, 65, 222);"&gt;def&lt;/span&gt; &lt;span style="color: rgb(255, 66, 66);"&gt;posts&lt;/span&gt; (table db &lt;span style="color: rgb(152, 83, 243);"&gt;:posts&lt;/span&gt;))
(&lt;span style="color: rgb(18, 65, 222);"&gt;def&lt;/span&gt; &lt;span style="color: rgb(255, 66, 66);"&gt;users&lt;/span&gt; (table db &lt;span style="color: rgb(152, 83, 243);"&gt;:users&lt;/span&gt;))
&lt;/pre&gt;
&lt;p&gt;
	Then we simply emit the HTML as before:&lt;/p&gt;
&lt;pre&gt;
(&lt;span style="color: rgb(18, 65, 222);"&gt;defn&lt;/span&gt; &lt;span style="color: rgb(255, 66, 66);"&gt;view-frontpage&lt;/span&gt;
  [r]
  (&lt;span style="color: rgb(18, 65, 222);"&gt;-&amp;gt;&amp;gt;&lt;/span&gt; (frontpage @(&lt;span style="color: rgb(18, 65, 222);"&gt;-&amp;gt;&lt;/span&gt; (&lt;span style="color: rgb(61, 61, 61);"&gt;join&lt;/span&gt; posts (&lt;span style="color: rgb(61, 61, 61);"&gt;project&lt;/span&gt; users [&lt;span style="color: rgb(152, 83, 243);"&gt;:nick&lt;/span&gt;])
                             (where (&lt;span style="color: rgb(152, 83, 243);"&gt;=&lt;/span&gt; &lt;span style="color: rgb(152, 83, 243);"&gt;:posts.submitter&lt;/span&gt; &lt;span style="color: rgb(152, 83, 243);"&gt;:users.id&lt;/span&gt;)))
                       (&lt;span style="color: rgb(152, 83, 243);"&gt;sort&lt;/span&gt; [&lt;span style="color: rgb(152, 83, 243);"&gt;:upvotes#desc&lt;/span&gt;])))
       (page (&lt;span style="color: rgb(152, 83, 243);"&gt;:session&lt;/span&gt; r) [&lt;span style="color: rgb(143, 143, 143);"&gt;"/css/frontpage.css"&lt;/span&gt;] nil)
       response))
&lt;/pre&gt;
&lt;p&gt;
	Now the frontpage snippet gets an ordered list of all the posts, which we just need to inject into our skeleton. First the skeleton:&lt;/p&gt;
&lt;pre&gt;
&amp;lt;&lt;span style="color: rgb(255, 66, 66);"&gt;body&lt;/span&gt;&amp;gt;
  &amp;lt;&lt;span style="color: rgb(255, 66, 66);"&gt;div&lt;/span&gt; &lt;span style="color: rgb(147, 74, 181);"&gt;class&lt;/span&gt;=&lt;span style="color: rgb(143, 143, 143);"&gt;"post"&lt;/span&gt;&amp;gt;
    &amp;lt;&lt;span style="color: rgb(255, 66, 66);"&gt;div&lt;/span&gt; &lt;span style="color: rgb(147, 74, 181);"&gt;class&lt;/span&gt;=&lt;span style="color: rgb(143, 143, 143);"&gt;"voting"&lt;/span&gt;&amp;gt;
      &amp;lt;&lt;span style="color: rgb(255, 66, 66);"&gt;div&lt;/span&gt; &lt;span style="color: rgb(147, 74, 181);"&gt;class&lt;/span&gt;=&lt;span style="color: rgb(143, 143, 143);"&gt;"upvote"&lt;/span&gt;&amp;gt;
        &amp;lt;&lt;span style="color: rgb(255, 66, 66);"&gt;img&lt;/span&gt; &lt;span style="color: rgb(147, 74, 181);"&gt;src&lt;/span&gt;=&lt;span style="color: rgb(143, 143, 143);"&gt;"/images/up.png"&lt;/span&gt;/&amp;gt;
      &amp;lt;/&lt;span style="color: rgb(255, 66, 66);"&gt;div&lt;/span&gt;&amp;gt;
      &amp;lt;&lt;span style="color: rgb(255, 66, 66);"&gt;div&lt;/span&gt; &lt;span style="color: rgb(147, 74, 181);"&gt;class&lt;/span&gt;=&lt;span style="color: rgb(143, 143, 143);"&gt;"votes"&lt;/span&gt;/&amp;gt;
      &amp;lt;&lt;span style="color: rgb(255, 66, 66);"&gt;div&lt;/span&gt; &lt;span style="color: rgb(147, 74, 181);"&gt;class&lt;/span&gt;=&lt;span style="color: rgb(143, 143, 143);"&gt;"downvote"&lt;/span&gt;&amp;gt;
        &amp;lt;&lt;span style="color: rgb(255, 66, 66);"&gt;img&lt;/span&gt; &lt;span style="color: rgb(147, 74, 181);"&gt;src&lt;/span&gt;=&lt;span style="color: rgb(143, 143, 143);"&gt;"/images/down.png"&lt;/span&gt;/&amp;gt;
      &amp;lt;/&lt;span style="color: rgb(255, 66, 66);"&gt;div&lt;/span&gt;&amp;gt;
    &amp;lt;/&lt;span style="color: rgb(255, 66, 66);"&gt;div&lt;/span&gt;&amp;gt;
    &amp;lt;&lt;span style="color: rgb(255, 66, 66);"&gt;div&lt;/span&gt; &lt;span style="color: rgb(147, 74, 181);"&gt;class&lt;/span&gt;=&lt;span style="color: rgb(143, 143, 143);"&gt;"title"&lt;/span&gt;/&amp;gt;
    &amp;lt;&lt;span style="color: rgb(255, 66, 66);"&gt;div&lt;/span&gt; &lt;span style="color: rgb(147, 74, 181);"&gt;class&lt;/span&gt;=&lt;span style="color: rgb(143, 143, 143);"&gt;"submitter"&lt;/span&gt;/&amp;gt;
  &amp;lt;/&lt;span style="color: rgb(255, 66, 66);"&gt;div&lt;/span&gt;&amp;gt;
&amp;lt;/&lt;span style="color: rgb(255, 66, 66);"&gt;body&lt;/span&gt;&amp;gt;
&lt;/pre&gt;
&lt;p&gt;
	This is quite simple. We have 2 buttons to use for voting a title and a submitter. To fill in these tags we will use another of Enlives features namely the snippet, which allows me to pass a chunk of Enlive-HTML to a template:&lt;/p&gt;
&lt;pre&gt;
(defsnippet frontpage &lt;span style="color: rgb(143, 143, 143);"&gt;"frontpage.html"&lt;/span&gt; [&lt;span style="color: rgb(152, 83, 243);"&gt;:body&lt;/span&gt; &lt;span style="color: rgb(152, 83, 243);"&gt;:&amp;gt;&lt;/span&gt; any-node]
  [posts]
  [&lt;span style="color: rgb(152, 83, 243);"&gt;:div.post&lt;/span&gt;]
  (clone-for [{&lt;span style="color: rgb(152, 83, 243);"&gt;:keys&lt;/span&gt; [id title url nick upvotes downvotes]} posts]
    [&lt;span style="color: rgb(152, 83, 243);"&gt;:div.votes&lt;/span&gt;]     (&lt;span style="color: rgb(18, 65, 222);"&gt;-&amp;gt;&lt;/span&gt; (&lt;span style="color: rgb(152, 83, 243);"&gt;-&lt;/span&gt; upvotes downvotes) str content)
    [&lt;span style="color: rgb(152, 83, 243);"&gt;:div.title&lt;/span&gt;]     (&lt;span style="color: rgb(61, 61, 61);"&gt;content&lt;/span&gt;
                      {&lt;span style="color: rgb(152, 83, 243);"&gt;:tag&lt;/span&gt; &lt;span style="color: rgb(152, 83, 243);"&gt;:a&lt;/span&gt;, &lt;span style="color: rgb(152, 83, 243);"&gt;:attrs&lt;/span&gt; {&lt;span style="color: rgb(152, 83, 243);"&gt;:href&lt;/span&gt; url}, &lt;span style="color: rgb(152, 83, 243);"&gt;:content&lt;/span&gt; [title]})
    [&lt;span style="color: rgb(152, 83, 243);"&gt;:div.submitter&lt;/span&gt;] (&lt;span style="color: rgb(18, 65, 222);"&gt;-&amp;gt;&lt;/span&gt; (&lt;span style="color: rgb(152, 83, 243);"&gt;str&lt;/span&gt; &lt;span style="color: rgb(143, 143, 143);"&gt;"submitted by "&lt;/span&gt; nick) content)))
&lt;/pre&gt;
&lt;p&gt;
	Let see what we've got:&lt;/p&gt;
&lt;p style="text-align: center;"&gt;
	&lt;img style="width: 700px; height: 540px;" src="http://www.bestinclass.dk/images/posts/social/second.png" alt="Second screenshot" /&gt;&lt;/p&gt;
&lt;p&gt;
	Perfect. Now we need to make the voting work, which unfortuntely involves Javascript - Although I like JS it would be nice with a ClojureDSL for that as well:&lt;/p&gt;
&lt;pre&gt;
&amp;lt;&lt;span style="color: rgb(255, 66, 66);"&gt;script&lt;/span&gt; &lt;span style="color: rgb(147, 74, 181);"&gt;type&lt;/span&gt;=&lt;span style="color: rgb(143, 143, 143);"&gt;"text/javascript"&lt;/span&gt;&amp;gt;
    function vote(id, uri, output) {
        $.ajax({url: uri, type: 'POST', data: {id: id},
                success: function(data) {
                    if (data.substring(0, 2) == "OK") {
                        $(output).html(data.substring(4));
                    } else {
                        Alert(&lt;span style="color: rgb(143, 143, 143);"&gt;"Your vote could not be submitted"&lt;/span&gt;);
                    }
                }
               });
    }

    function attach_voter(objs, dir) {
        $(objs + ' img').each(function() {
            $(this).click(function() {
                vote($(this).parent().parent().attr(&lt;span style="color: rgb(143, 143, 143);"&gt;"pid"&lt;/span&gt;),
                     dir,
                     $(this).parent().parent().find(&lt;span style="color: rgb(143, 143, 143);"&gt;"div.votes"&lt;/span&gt;));
            }).css(&lt;span style="color: rgb(143, 143, 143);"&gt;"cursor"&lt;/span&gt;, &lt;span style="color: rgb(143, 143, 143);"&gt;"pointer"&lt;/span&gt;);
        });
    }

    $(function() {
        attach_voter(&lt;span style="color: rgb(143, 143, 143);"&gt;"div.upvote"&lt;/span&gt;, &lt;span style="color: rgb(143, 143, 143);"&gt;"/vote/up"&lt;/span&gt;);
        attach_voter(&lt;span style="color: rgb(143, 143, 143);"&gt;"div.downvote"&lt;/span&gt;, &lt;span style="color: rgb(143, 143, 143);"&gt;"/vote/down"&lt;/span&gt;);
    });
  &lt;!--&lt;span style="color: rgb(255, 66, 66);"--&gt;script&amp;gt;
&lt;/pre&gt;
&lt;p&gt;
	This is a pretty naive implementation:The function &lt;strong&gt;vote&lt;/strong&gt; calls an URL in the backend, receives a response and updates the votes count with whatever it gets back. The function &lt;strong&gt;attach_voter&lt;/strong&gt; finds all image tags under the select &lt;strong&gt;objs&lt;/strong&gt; and adds an onclick event which simply calls vote. This is clever, because if you only want to allow your users to vote once, simply let the backend keep track of the votes and it will always reply with the correct count.&lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;h1&gt;
	Voting&lt;/h1&gt;
&lt;p&gt;
	Now we can add the backend implementation:&lt;/p&gt;
&lt;pre&gt;
(&lt;span style="color: rgb(18, 65, 222);"&gt;defn&lt;/span&gt; &lt;span style="color: rgb(255, 66, 66);"&gt;vote&lt;/span&gt;
  [{id &lt;span style="color: rgb(152, 83, 243);"&gt;:form-params&lt;/span&gt;} direction]
  (&lt;span style="color: rgb(18, 65, 222);"&gt;let&lt;/span&gt; [predicate (where (&lt;span style="color: rgb(152, 83, 243);"&gt;=&lt;/span&gt; &lt;span style="color: rgb(152, 83, 243);"&gt;:id&lt;/span&gt; (&lt;span style="color: rgb(152, 83, 243);"&gt;get&lt;/span&gt; id &lt;span style="color: rgb(143, 143, 143);"&gt;"id"&lt;/span&gt;)))]
    (update-in! posts (where predicate)
     (&lt;span style="color: rgb(18, 65, 222);"&gt;if&lt;/span&gt; (&lt;span style="color: rgb(152, 83, 243);"&gt;=&lt;/span&gt; &lt;span style="color: rgb(143, 143, 143);"&gt;"up"&lt;/span&gt; direction)
       {&lt;span style="color: rgb(152, 83, 243);"&gt;:upvotes&lt;/span&gt;   (&lt;span style="color: rgb(152, 83, 243);"&gt;inc&lt;/span&gt; (&lt;span style="color: rgb(18, 65, 222);"&gt;-&amp;gt;&lt;/span&gt; (&lt;span style="color: rgb(61, 61, 61);"&gt;select&lt;/span&gt; posts (where predicate))
                            (pick! &lt;span style="color: rgb(152, 83, 243);"&gt;:upvotes&lt;/span&gt;)))}
       {&lt;span style="color: rgb(152, 83, 243);"&gt;:downvotes&lt;/span&gt; (&lt;span style="color: rgb(152, 83, 243);"&gt;inc&lt;/span&gt; (&lt;span style="color: rgb(18, 65, 222);"&gt;-&amp;gt;&lt;/span&gt; (&lt;span style="color: rgb(61, 61, 61);"&gt;select&lt;/span&gt; posts (where predicate))
                            (pick! &lt;span style="color: rgb(152, 83, 243);"&gt;:downvotes&lt;/span&gt;)))}))
    (&lt;span style="color: rgb(18, 65, 222);"&gt;-&amp;gt;&lt;/span&gt; (&lt;span style="color: rgb(152, 83, 243);"&gt;format&lt;/span&gt; &lt;span style="color: rgb(143, 143, 143);"&gt;"OK: %s"&lt;/span&gt; (&lt;span style="color: rgb(18, 65, 222);"&gt;-&amp;gt;&lt;/span&gt; (&lt;span style="color: rgb(61, 61, 61);"&gt;select&lt;/span&gt; posts (where predicate))
                             (aggregate [[&lt;span style="color: rgb(143, 143, 143);"&gt;"(upvotes - downvotes)"&lt;/span&gt; &lt;span style="color: rgb(152, 83, 243);"&gt;:as&lt;/span&gt; &lt;span style="color: rgb(152, 83, 243);"&gt;:sum&lt;/span&gt;]])
                             (pick! &lt;span style="color: rgb(152, 83, 243);"&gt;:sum&lt;/span&gt;)))
        response)))&lt;/pre&gt;
&lt;p&gt;
	Basically this function takes the arguments supplied by the JS and a direction in which to vote, ie. up or down. Then it &lt;strong&gt;updates&lt;/strong&gt; the row in &lt;strong&gt;posts&lt;/strong&gt; where &lt;strong&gt;predicate&lt;/strong&gt; is true. If direction is "up" it increments the &lt;strong&gt;upvotes&lt;/strong&gt;, otherwise increments the &lt;strong&gt;downvotes&lt;/strong&gt;. The function &lt;strong&gt;pick!&lt;/strong&gt; is particularily helpful as it derefences our table, checks if theres a single hit and then pulls out the value of the keyword supplied as the argument - this lets us call inc directly on the result. Once thats done, we want to return the score which is simply upvotes minus downvotes - notice how &lt;a target="_blank" href="http://clojureql.org"&gt;ClojureQL&lt;/a&gt; easily lets me slip in a string and alias that.&lt;/p&gt;
&lt;p&gt;
	Now we need moustache to call this function when somebody votes. As you saw in the JS voting is done by POSTing to either /vote/up or /vote/down, here's how to catch that with Moustache:&lt;/p&gt;
&lt;pre&gt;
(&lt;span style="color: rgb(18, 65, 222);"&gt;def&lt;/span&gt; &lt;span style="color: rgb(255, 66, 66);"&gt;routes&lt;/span&gt;
  (app
   (wrap-file "resources")
   [&lt;span style="color: rgb(143, 143, 143);"&gt;""&lt;/span&gt;]               view-frontpage
   [&lt;span style="color: rgb(143, 143, 143);"&gt;"vote"&lt;/span&gt; direction] (wrap-params (delegate vote direction))))&lt;/pre&gt;
&lt;p&gt;
	In a production system, I wouldn't do it like this - I would use the same URI for both calls and carry the direction in the POST data. But this lets me show off more of Moustaches syntax and the delegate function - You could use partial, but then you would have to re-arrange the argument order. The ["vote" direction] will match "/vote/*" where * can be anything except another slash - whatever is passed goes into the var &lt;strong&gt;direction&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;h1&gt;
	Submitting posts&lt;/h1&gt;
&lt;p&gt;
	Now we need to allow users to submit posts, which follows the outline above:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;
		Make a HTML skeleton&lt;/li&gt;
	&lt;li&gt;
		Define an Enlive snippet&lt;/li&gt;
	&lt;li&gt;
		Write a backend handler&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
	Since the first 2 are exceedingly trivial, I'll simply demonstrate the handler:&lt;/p&gt;
&lt;pre&gt;
(&lt;span style="color: rgb(18, 65, 222);"&gt;defn&lt;/span&gt; &lt;span style="color: rgb(255, 66, 66);"&gt;accept-submission&lt;/span&gt;
  [req]
  (&lt;span style="color: rgb(18, 65, 222);"&gt;let&lt;/span&gt; [params (&lt;span style="color: rgb(18, 65, 222);"&gt;-&amp;gt;&lt;/span&gt; req &lt;span style="color: rgb(152, 83, 243);"&gt;:form-params&lt;/span&gt;)
        user   1]&lt;span style="color: rgb(211, 211, 211);"&gt;;(-&amp;gt; req :session :id)]
&lt;/span&gt;    (&lt;span style="color: rgb(152, 83, 243);"&gt;conj!&lt;/span&gt; posts {&lt;span style="color: rgb(152, 83, 243);"&gt;:title&lt;/span&gt;     (params &lt;span style="color: rgb(143, 143, 143);"&gt;"title"&lt;/span&gt;)
                  &lt;span style="color: rgb(152, 83, 243);"&gt;:url&lt;/span&gt;       (params &lt;span style="color: rgb(143, 143, 143);"&gt;"url"&lt;/span&gt;)
                  &lt;span style="color: rgb(152, 83, 243);"&gt;:submitter&lt;/span&gt; user})
    (response &lt;span style="color: rgb(143, 143, 143);"&gt;"OK"&lt;/span&gt;)))&lt;/pre&gt;
&lt;p&gt;
	Because I haven't written the '&lt;em&gt;&lt;strong&gt;login&lt;/strong&gt;&lt;/em&gt;' functionality yet, I've hardcoded the user ID to 1. Then I simply &lt;strong&gt;conj!&lt;/strong&gt; the hasmap containing the values from the post onto posts and reply "OK". Normally, you would want to filter/sanitize your results and add some error handling but thats beyond the scope of this post. Next you might want to group both the POST and GET replies on the URI "/submit", here's how to do it:&lt;/p&gt;
&lt;pre&gt;
(&lt;span style="color: rgb(18, 65, 222);"&gt;def&lt;/span&gt; &lt;span style="color: rgb(255, 66, 66);"&gt;routes&lt;/span&gt;
  (app
   (wrap-file "resources")
   [&lt;span style="color: rgb(143, 143, 143);"&gt;""&lt;/span&gt;]               view-frontpage
   [&lt;span style="color: rgb(143, 143, 143);"&gt;"submit"&lt;/span&gt;]         {&lt;span style="color: rgb(152, 83, 243);"&gt;:get&lt;/span&gt;  view-submission-page
                       &lt;span style="color: rgb(152, 83, 243);"&gt;:post&lt;/span&gt; (wrap-params accept-submission)}
   [&lt;span style="color: rgb(143, 143, 143);"&gt;"vote"&lt;/span&gt; direction] (wrap-params (delegate vote direction))))&lt;/pre&gt;
&lt;p&gt;
	Passing Moustache a map, instead of a function lets you group related functionality on the same URI.&lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;h1&gt;
	Logging in/out&lt;/h1&gt;
&lt;p&gt;
	All we need now is to give users the ability to log in and out. In order to do that, we need to perform the usual steps ending with the handler:&lt;/p&gt;
&lt;pre&gt;
(&lt;span style="color: rgb(18, 65, 222);"&gt;defn&lt;/span&gt; &lt;span style="color: rgb(255, 66, 66);"&gt;authenticate-user&lt;/span&gt;
  [{params &lt;span style="color: rgb(152, 83, 243);"&gt;:form-params&lt;/span&gt;}]
  (&lt;span style="color: rgb(18, 65, 222);"&gt;let&lt;/span&gt; [user  @(&lt;span style="color: rgb(61, 61, 61);"&gt;select&lt;/span&gt; users (where (&lt;span style="color: rgb(18, 65, 222);"&gt;and&lt;/span&gt; (&lt;span style="color: rgb(152, 83, 243);"&gt;=&lt;/span&gt; &lt;span style="color: rgb(152, 83, 243);"&gt;:nick&lt;/span&gt;     (params &lt;span style="color: rgb(143, 143, 143);"&gt;"usr"&lt;/span&gt;))
                                         (&lt;span style="color: rgb(152, 83, 243);"&gt;=&lt;/span&gt; &lt;span style="color: rgb(152, 83, 243);"&gt;:password&lt;/span&gt; (params &lt;span style="color: rgb(143, 143, 143);"&gt;"psw"&lt;/span&gt;)))))]
    (&lt;span style="color: rgb(18, 65, 222);"&gt;if&lt;/span&gt; (&lt;span style="color: rgb(152, 83, 243);"&gt;=&lt;/span&gt; 1 (&lt;span style="color: rgb(152, 83, 243);"&gt;count&lt;/span&gt; user))
      (&lt;span style="color: rgb(152, 83, 243);"&gt;assoc&lt;/span&gt; (redirect &lt;span style="color: rgb(143, 143, 143);"&gt;"/"&lt;/span&gt;) &lt;span style="color: rgb(152, 83, 243);"&gt;:session&lt;/span&gt; (&lt;span style="color: rgb(152, 83, 243);"&gt;first&lt;/span&gt; user))
      (redirect &lt;span style="color: rgb(143, 143, 143);"&gt;"/login?err=true"&lt;/span&gt;))))&lt;/pre&gt;
&lt;p&gt;
	Ring has a middleware called &lt;strong&gt;wrap-session&lt;/strong&gt;, which when enabled keeps a :session key in every request which you can use to store information about each session. Here I simply select the row from the database which has the correct username/password combination and if I get a hit then I associate that record with the session - If I dont get a hit, I redirect the client to the login page and show an error. This brings us to the final piece of the puzzle...&lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;h1&gt;
	Middlewares&lt;/h1&gt;
&lt;p&gt;
	One of the great delights of working with Ring is its middlewares. They act as functions which work on each request and then passes the request down the line, possibly modified. One middleware which we definitely need now, is a security middleware which rejects unauthorized users from pages they're not allowed to see, here's a naive way to achieve that:&lt;/p&gt;
&lt;pre&gt;
(&lt;span style="color: rgb(18, 65, 222);"&gt;defn&lt;/span&gt; &lt;span style="color: rgb(255, 66, 66);"&gt;wrap-security&lt;/span&gt;
  [app]
  (&lt;span style="color: rgb(152, 83, 243);"&gt;fn&lt;/span&gt; [req]
    (&lt;span style="color: rgb(18, 65, 222);"&gt;let&lt;/span&gt; [uri (&lt;span style="color: rgb(152, 83, 243);"&gt;:uri&lt;/span&gt; req)]
      (&lt;span style="color: rgb(18, 65, 222);"&gt;if&lt;/span&gt; (&lt;span style="color: rgb(18, 65, 222);"&gt;or&lt;/span&gt; (&lt;span style="color: rgb(18, 65, 222);"&gt;-&amp;gt;&lt;/span&gt; req &lt;span style="color: rgb(152, 83, 243);"&gt;:session&lt;/span&gt; &lt;span style="color: rgb(152, 83, 243);"&gt;:nick&lt;/span&gt; seq)
              (&lt;span style="color: rgb(152, 83, 243);"&gt;=&lt;/span&gt; uri &lt;span style="color: rgb(143, 143, 143);"&gt;"/"&lt;/span&gt;)
              (&lt;span style="color: rgb(152, 83, 243);"&gt;=&lt;/span&gt; uri &lt;span style="color: rgb(143, 143, 143);"&gt;"/login"&lt;/span&gt;))
        (app req)
        (redirect &lt;span style="color: rgb(143, 143, 143);"&gt;"/?err=Not logged in"&lt;/span&gt;)))))&lt;/pre&gt;
&lt;p&gt;
	If the user is logged in or is trying to access one of the two public URIs the application handles the request as normally, but if not it redirects to the frontpage. The entire middleware stack for this app looks like so:&lt;/p&gt;
&lt;pre&gt;
(&lt;span style="color: rgb(18, 65, 222);"&gt;def&lt;/span&gt; &lt;span style="color: rgb(255, 66, 66);"&gt;routes&lt;/span&gt;
  (app
   (wrap-file   &lt;span style="color: rgb(143, 143, 143);"&gt;"resources"&lt;/span&gt;)
   (wrap-reload '[socialsite.templates])
   (wrap-session)
   (wrap-security)

   [&lt;span style="color: rgb(143, 143, 143);"&gt;""&lt;/span&gt;]               view-frontpage
   [&lt;span style="color: rgb(143, 143, 143);"&gt;"logout"&lt;/span&gt;]         logout
   [&lt;span style="color: rgb(143, 143, 143);"&gt;"login"&lt;/span&gt;]          {&lt;span style="color: rgb(152, 83, 243);"&gt;:get&lt;/span&gt; view-login-page
                       &lt;span style="color: rgb(152, 83, 243);"&gt;:post&lt;/span&gt; (wrap-params authenticate-user)}
   [&lt;span style="color: rgb(143, 143, 143);"&gt;"submit"&lt;/span&gt;]         {&lt;span style="color: rgb(152, 83, 243);"&gt;:get&lt;/span&gt;  view-submission-page
                       &lt;span style="color: rgb(152, 83, 243);"&gt;:post&lt;/span&gt; (wrap-params accept-submission)}
   [&lt;span style="color: rgb(143, 143, 143);"&gt;"vote"&lt;/span&gt; direction] (wrap-params (delegate vote direction))))&lt;/pre&gt;
&lt;p&gt;
	&lt;strong&gt;wrap-file&lt;/strong&gt; allows me to serve static files from the resources directory, &lt;strong&gt;wrap-reload&lt;/strong&gt; reloads the Enlive templates on every pageview, very handy for development, very no-no for production. The final two I've already commented on - Lets see what we ended up with:&lt;/p&gt;
&lt;p style="text-align: center;"&gt;
	&lt;img style="width: 700px; height: 540px;" src="http://www.bestinclass.dk/images/posts/social/third.png" alt="Third screenshot" /&gt;&lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;p&gt;
	There you go, your own &lt;strong&gt;Clojure Driven Social Media website&lt;/strong&gt; to help keep the community engaged and connected :)&lt;/p&gt;
&lt;p&gt;
	The source code for this app is on &lt;a href="http://github.com/LauJensen/SocialSite"&gt;Github&lt;/a&gt;, to launch it simply follow these simple steps:&lt;/p&gt;
&lt;pre&gt;
$ git clone http://github.com/LauJensen/SocialSite.git
$ cd SocialSite
$ mysql -u root -p &amp;lt; INSTALL.sql 
&lt;span style="color: rgb(0, 0, 0);"&gt;Enter&lt;/span&gt; password: *******
$ cake repl
user=&amp;gt; (&lt;span style="color: rgb(165, 42, 42);"&gt;use&lt;/span&gt; 'socialsite.core)
nil
&lt;/pre&gt;
&lt;p&gt;
	The &lt;strong&gt;INSTALL.sql&lt;/strong&gt; file will create the social/social user/pass on your local MySQL installation as well as the social database which is populates with two tables. Once you issue the &lt;em&gt;&lt;strong&gt;use&lt;/strong&gt;&lt;/em&gt; command in the repl, you can access the site on &lt;strong&gt;http://127.0.0.1:8080&lt;/strong&gt; - Here you can login with my user "Lau" / "social" - Enjoy!&lt;/p&gt;
&lt;br /&gt;
&lt;div style="background: url(&amp;quot;/images/authorbg.png&amp;quot;) no-repeat scroll left top transparent; width: 705px; height: 175px; padding: 10px;"&gt;
  &lt;a style="float:right; margin-top: 70px; margin-right: 60px;" target="_blank" href="http://feeds.feedburner.com/bestinclass-the-blog"&gt;&lt;img src="/images/rss.png" alt="View the RSS feed" /&gt;&lt;/a&gt;
    &lt;a style="float:right; margin-top: 70px; margin-right: 60px;" target="_blank" href="http://twitter.com/laujensen"&gt;&lt;img src="/images/twitter.png" alt="Follow Lau on Twitter" /&gt;&lt;/a&gt;
  &lt;h1&gt;About the author:&lt;/h1&gt;
  &lt;p style="width: 400px"&gt;&lt;b&gt;Lau Jensen&lt;/b&gt; is the founder and owner of Best In Class a danish consultancy company which specializes in Clojure development. &lt;/p&gt;
  &lt;p style="width: 400px; margin-top: 1px;"&gt;&lt;b&gt;Lau&lt;/b&gt; is also one of the instructors driving the &lt;a href="http://www.conj-labs.eu"&gt;Conj Labs&lt;/a&gt; initiative. If you would like to be notified once new blogposts are published, you can follow Lau on &lt;a href="http://twitter.com/laujensen"&gt;Twitter.&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
</content>
  </entry><entry>
    <title>Best In Class: ClojureQL - 1.0.0 now in beta</title>
    <link href="http://www.bestinclass.dk/index.clj/2010/11/clojureql--1.0.0-now-in-beta.html" />
    <id>http://www.bestinclass.dk/index.clj/2010/11/clojureql--1.0.0-now-in-beta.html</id>
    <updated>2010-11-18T01:50:40Z</updated>
    <summary type="html">
    &lt;h1 id="title"&gt;ClojureQL - 1.0.0 now in beta&lt;/h1&gt;
    &lt;div id="pubdate"&gt;2010-11-18 01:50:40&lt;/div&gt;
    &lt;img src="http://www.bestinclass.dk/wp-content/uploads/avatars/clojureql.png" id="thumb" /&gt;
  &lt;div id="box"&gt;
	&lt;p&gt;
		After 2.5 years ClojureQL got shredded and rebuilt in less than 3 weeks, today Im releasing 1.0 public beta! In this post I'll show you the basics of how ClojureQL lets you compose your queries using powerful abstractions in a short &lt;strong&gt;screencast&lt;/strong&gt;.&lt;/p&gt;
	&lt;p&gt;
		 &lt;/p&gt;
&lt;/div&gt;
</summary>
    <content type="html">&lt;h1&gt;
	Preface&lt;/h1&gt;
&lt;p&gt;
	Over 2.5 years ago I set out to develop THE database abstraction library and after 2.5 years I felt painted into a corner, so I deleted the whole thing and re-wrote it in less than 3 weeks (with a little help from my friends).&lt;/p&gt;
&lt;p&gt;
	The ClojureQL that Im presenting today is the public 1.0 beta release and hopefully it will meet all of your production needs. I've prepared this small screencast to get you started and I'll discuss the details below - If the quality of the video is unsatisfactory please download the original file from Vimeo instead of using the Flash player:&lt;/p&gt;
&lt;p style="text-align: center;"&gt;
	 &lt;/p&gt;
&lt;p style="text-align: center;"&gt;
	&lt;iframe width="600" height="465" frameborder="0" src="http://player.vimeo.com/video/16958466?title=0&amp;amp;byline=0"&gt;&lt;/iframe&gt;&lt;/p&gt;
&lt;p style="text-align: center;"&gt;
	 &lt;/p&gt;
&lt;p style="text-align: center;"&gt;
	&lt;a href="http://vimeo.com/16958466"&gt;ClojureQL (Beta)&lt;/a&gt; from &lt;a href="http://vimeo.com/laujensen"&gt;Lau Jensen&lt;/a&gt; on &lt;a href="http://vimeo.com"&gt;Vimeo&lt;/a&gt;.&lt;/p&gt;
&lt;h1&gt;
	 &lt;/h1&gt;
&lt;h1&gt;
	ClojureQL 1.0 - Bringing Relational Algebra, back to Relational Databases&lt;/h1&gt;
&lt;p&gt;
	ClojureQL 1.0 is has been a long time coming, but I feel confident that the interfaces and primitives of this implementation are whats needed to provide the ultimate SQL integration experience. ClojureQL is similar in intent to Rubys &lt;a target="_blank" href="http://magicscalingsprinkles.wordpress.com/2010/01/28/why-i-wrote-arel/"&gt;Arel&lt;/a&gt;. The current implementation is the refined experience of the previous 2.5 years boiled down into about 700 lines of pure Clojure.&lt;/p&gt;
&lt;p&gt;
	If you want the finer details of why the first version of ClojureQL got scrapped, &lt;a target="_blank" href="http://bestinclass.dk/index.clj/2010/11/clojureql--revolutions.html"&gt;read this post&lt;/a&gt;. As I was designing this re-write I was approached by &lt;a target="_blank" href="http://twitter.com/ninjudd"&gt;Justin Balthrop&lt;/a&gt; (&lt;strong&gt;ninjudd&lt;/strong&gt;), of &lt;a target="_blank" href="https://github.com/ninjudd/cake"&gt;Cake&lt;/a&gt; fame, who said "What you've got is 90% of the way towards getting true composability, &lt;a target="_blank" href="http://en.wikipedia.org/wiki/Relational_algebra"&gt;relational algebra&lt;/a&gt; (RA) primitives will get you all the way". I read up on RA and looked at some examples and knew that Justin was on to something, RA was definitely the key to making a truly composable library (well, that and the lack of macros), so off we went. The ClojureQL you've just seen demonstrated is totally RA based.&lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;h1&gt;
	Getting started&lt;/h1&gt;
&lt;p&gt;
	To get ClojureQL either include these artifacts in your project:&lt;/p&gt;
&lt;h3&gt;
	Cake / Lein:&lt;/h3&gt;
&lt;p&gt;
	&lt;span class="tag"&gt;[&lt;/span&gt;clojureql&lt;span class="string"&gt; "1.0.0-beta1-SNAPSHOT"&lt;/span&gt;&lt;span class="tag"&gt;]&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;
	&lt;span class="tag"&gt;Maven:    &lt;/span&gt;&lt;/h3&gt;
&lt;pre&gt;&lt;span class="tag"&gt;&lt;span style="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 205);"&gt;&lt;span style="font-weight: bold;"&gt;dependency&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255);"&gt;&amp;gt;&lt;/span&gt;
  &lt;span style="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 205);"&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="background-color: rgb(255, 255, 255);"&gt;groupId&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255);"&gt;clojureql&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255);"&gt;/&lt;/span&gt;&lt;span style="color: rgb(0, 0, 205);"&gt;&lt;span style="font-weight: bold;"&gt;groupId&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255);"&gt;&amp;gt;&lt;/span&gt;
  &lt;span style="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 205);"&gt;&lt;span style="font-weight: bold;"&gt;artifactId&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255);"&gt;clojureql&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255);"&gt;/&lt;/span&gt;&lt;span style="color: rgb(0, 0, 205);"&gt;&lt;span style="font-weight: bold;"&gt;artifactId&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255);"&gt;&amp;gt;&lt;/span&gt;
  &lt;span style="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 205);"&gt;&lt;span style="font-weight: bold;"&gt;version&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255);"&gt;1.0.0-beta1-SNAPSHOT&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255);"&gt;/&lt;/span&gt;&lt;span style="color: rgb(0, 0, 205);"&gt;&lt;span style="font-weight: bold;"&gt;version&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255);"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255);"&gt;/&lt;/span&gt;&lt;span style="color: rgb(0, 0, 205);"&gt;&lt;span style="font-weight: bold;"&gt;dependency&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;
	Or simply clone the Github Repo.&lt;/p&gt;
&lt;pre&gt;git clone git@github.com:LauJensen/clojureql.git&lt;/pre&gt;
&lt;p&gt;
	If you run into trouble that you think you yourself might be the cause of, you can get help on &lt;strong&gt;#clojureql &lt;/strong&gt;on &lt;strong&gt;irc.freenode.net&lt;/strong&gt; where you'll find both myself and Justin. If you've uncovered an issue with ClojureQL itself, please &lt;a _cke_saved_href="http://github.com/LauJensen/clojureql/issues" target="_blank" href="javascript:void(0)/*321*/"&gt;report it on Github&lt;/a&gt; and include instructions on how to reproduce.&lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;h1&gt;
	Documentation&lt;/h1&gt;
&lt;p&gt;
	I'll outline the various functions/interfaces that you need to know below, but generally you should refer to the &lt;a _cke_saved_href="http://github.com/LauJensen/clojureql" target="_blank" href="javascript:void(0)/*322*/"&gt;Github page&lt;/a&gt; which will serve as documentation henceforth!&lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;h1&gt;
	Shadows&lt;/h1&gt;
&lt;p&gt;
	In a few instances ClojureQL shadows functions from clojure.core and in two of these instances they behave different:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;
		conj! - In clojure.core this works on transients, in ClojureQL it only works on tables&lt;/li&gt;
	&lt;li&gt;
		disj! - Same as above&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
	Besides these 2 we shadow take, drop and sort but these all work as you would expect. If you call them on a Table they return a new table, if you call them on a collection they pass your arguments on to the clojure.core version. No mathematical operators or and/or are shadowed. You can make your code clearer by using ClojureQL :as cql.&lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;h1&gt;
	The interfaces&lt;/h1&gt;
&lt;p&gt;
	There are only a few functions that you need to get comfortable with in order to start composing powerful queries:&lt;/p&gt;
&lt;h3&gt;
	Table&lt;/h3&gt;
&lt;p&gt;
	Table lets you construct a reference to a table in a SQL database. As its arguments you can specificy the connection-object (keyword or hashmap, required), the table name (keyword or hash-map if you're aliasing).&lt;/p&gt;
&lt;h3&gt;
	Deref&lt;/h3&gt;
&lt;p&gt;
	When you dereference a table object (either (deref table) or @table) the query of that table is compiled and executed.&lt;/p&gt;
&lt;h3&gt;
	Select / Where&lt;/h3&gt;
&lt;p&gt;
	The select statement is not to be confused with SQL SELECT command. Select actually corresponds to WHERE from MySql. There are 2 ways in which you can build a select statement.&lt;/p&gt;
&lt;p&gt;
	1) Using the 'where' macro:&lt;/p&gt;
&lt;pre&gt;&lt;span style="color: rgb(18, 65, 222);"&gt;clojureql.core&amp;gt; &lt;/span&gt;&lt;span style="font-weight: bold;"&gt;(where (and (&amp;gt; :id 5) (&amp;lt;= :wage 100)))&lt;/span&gt;
"((id &amp;gt; 5) AND (wage &amp;lt;= 100))"
&lt;/pre&gt;
&lt;p&gt;
	Which accepts column references as keywords, standard mathematical operators and and/or. Or you can:&lt;/p&gt;
&lt;p&gt;
	2) Write out the datastructure which 'where' compiles manually by suffixing every function with a star* (this is the only thing which 'where' does for you). To do that, you must first use/require clojureql.predicates:&lt;/p&gt;
&lt;pre&gt;&lt;span style="color: rgb(18, 65, 222);"&gt;clojureql.core&amp;gt; &lt;/span&gt;&lt;span style="font-weight: bold;"&gt;(and* (&amp;gt;* :id 5) (&amp;lt;=* :wage 100))&lt;/span&gt;
"((id &amp;gt; 5) AND (wage &amp;lt;= 100))"
&lt;/pre&gt;
&lt;h3&gt;
	Rename&lt;/h3&gt;
&lt;p&gt;
	Rename is helpful when you need to alias a column after table construction. Here are 2 variants of renaming, both valid:&lt;/p&gt;
&lt;pre&gt;&lt;span style="color: rgb(18, 65, 222);"&gt;clojureql.core&amp;gt; &lt;/span&gt;&lt;span style="font-weight: bold;"&gt;(-&amp;gt; (table nil :users)
                    (project [:id :name])
                    (rename {:id :idx})
                    to-sql)&lt;/span&gt;
"SELECT users.id,users.name FROM users AS users(idx,name)"
&lt;span style="color: rgb(18, 65, 222);"&gt;clojureql.core&amp;gt; &lt;/span&gt;&lt;span style="font-weight: bold;"&gt;(-&amp;gt; (table nil :users)
                    (project [[:id :as :idx] :name])
                    to-sql)&lt;/span&gt;
"SELECT users.id AS idx,users.name FROM users"
&lt;/pre&gt;
&lt;p&gt;
	Note that a nested vector always denotes aliasing as does hashmaps. To rename a table, do the following:&lt;/p&gt;
&lt;pre&gt;&lt;span style="color: rgb(18, 65, 222);"&gt;clojureql.core&amp;gt; &lt;/span&gt;&lt;span style="font-weight: bold;"&gt;(-&amp;gt; (table nil {:users :u1})
                    to-sql)&lt;/span&gt;
"SELECT * FROM users u1"
&lt;/pre&gt;
&lt;h3&gt;
	Join&lt;/h3&gt;
&lt;p&gt;
	Join compiles to a regular join using either USING or ON depending on your predicate. As arguments it takes 2 tables and a predicate. If your predicate is a keyword it will compile to USING(keyword), if its a predicate built with the 'where' macro, it will be taken literally:&lt;/p&gt;
&lt;pre&gt;&lt;span style="color: rgb(18, 65, 222);"&gt;clojureql.core&amp;gt; &lt;/span&gt;&lt;span style="font-weight: bold;"&gt;(-&amp;gt; (join (-&amp;gt; (table nil :t1) (project [:c1]))
                          (-&amp;gt; (table nil :t2) (project [:c2]))
                          :id)
                    to-sql)
                    &lt;/span&gt;
"SELECT t1.c1,t2.c2 FROM t1 JOIN t2 USING(id)"
&lt;/pre&gt;
&lt;p&gt;
	And here's the equivalent join with a custom predicate&lt;/p&gt;
&lt;pre&gt;&lt;span style="color: rgb(18, 65, 222);"&gt;clojureql.core&amp;gt; &lt;/span&gt;&lt;span style="font-weight: bold;"&gt;(-&amp;gt; (join (-&amp;gt; (table nil :t1) (project [:id :c1]))
                          (-&amp;gt; (table nil :t2) (project [:id :c2]))
                          (where (= :t1.id :t2.id)))
                    to-sql)
                    &lt;/span&gt;
"SELECT t1.id,t1.c1,t2.id,t2.c2 FROM t1 JOIN t2 ON (t1.id = t2.id)"
&lt;/pre&gt;
&lt;p&gt;
	It's also a possibility to join a table unto itself using aliasing, like this next example where we find an employees manager:&lt;/p&gt;
&lt;pre&gt;&lt;span style="color: rgb(18, 65, 222);"&gt;clojureql.core&amp;gt; &lt;/span&gt;&lt;span style="font-weight: bold;"&gt;(-&amp;gt; (select (table {} {:employees :p})
                            (where (= :name "John")))
                    (join (table {} {:employees :b})
                          (where (= :p.manager :b.id)))
                    to-sql)&lt;/span&gt;
"SELECT p.*,b.* FROM employees p JOIN employees b ON (p.manager = b.id) WHERE (name = 'John')"
&lt;/pre&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;h3&gt;
	Outer-join&lt;/h3&gt;
&lt;p&gt;
	Outer-join does pretty much as advertised, it compiles to an outer-join either LEFT, RIGHT or FULL. It takes as its arguments 2 tables, the type of join as a keyword (&lt;strong&gt;:left|:right|:full&lt;/strong&gt;) and a predicate (again, either keyword or clause):&lt;/p&gt;
&lt;pre&gt;&lt;span style="color: rgb(18, 65, 222);"&gt;clojureql.core&amp;gt; &lt;/span&gt;&lt;span style="font-weight: bold;"&gt;(-&amp;gt; (outer-join (table nil :t1)
                                (table nil :t2)
                                :left
                                (where (= :t1.id :t2.id)))
                    to-sql)
                    &lt;/span&gt;
"SELECT t1.*,t2.* FROM t1 LEFT OUTER JOIN t2 ON (t1.id = t2.id)"
&lt;/pre&gt;
&lt;h3&gt;
	Aggregate&lt;/h3&gt;
&lt;p&gt;
	Aggregate lets you select aggregates from your tables in a composable fashion (they dont need to be defined up front). It simply takes a table and a collection of aggregates. All aggregates in ClojureQL follow this syntax for singular fields: &lt;strong&gt;:function/field&lt;/strong&gt; and this for multiple fields: &lt;strong&gt;:function/field1:field2:fieldn&lt;/strong&gt;. If you need to get even fancier, use strings they are supported literally:&lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;pre&gt;&lt;span style="color: rgb(18, 65, 222);"&gt;clojureql.core&amp;gt; &lt;/span&gt;&lt;span style="font-weight: bold;"&gt;(-&amp;gt; (table nil :users)
                    (aggregate [:count/* :avg/salary])
                    to-sql)&lt;/span&gt;
"SELECT count(*),avg(users.salary) FROM users"
&lt;span style="color: rgb(18, 65, 222);"&gt;clojureql.core&amp;gt; &lt;/span&gt;&lt;span style="font-weight: bold;"&gt;(-&amp;gt; (table nil :users)
                    (aggregate [:count/* :max/income:expenses])
                    to-sql)&lt;/span&gt;
"SELECT count(*),max(users.income,users.expenses) FROM users"
&lt;span style="color: rgb(18, 65, 222);"&gt;clojureql.core&amp;gt; &lt;/span&gt;&lt;span style="font-weight: bold;"&gt;(-&amp;gt; (table nil :users)
                    (aggregate ["corr(x + y)"])
                    to-sql)&lt;/span&gt;
"SELECT corr(x + y) FROM users"
&lt;/pre&gt;
&lt;h3&gt;
	Take/Drop&lt;/h3&gt;
&lt;p&gt;
	Just as with your regular collections in Clojure, you can use take/drop on tables and they act exactly the same way:&lt;/p&gt;
&lt;pre&gt;&lt;span style="color: rgb(18, 65, 222);"&gt;clojureql.core&amp;gt; &lt;/span&gt;&lt;span style="font-weight: bold;"&gt;(-&amp;gt; (table nil :users)
                    (take 4)
                    (drop 2)
                    to-sql)&lt;/span&gt;
"SELECT users.* FROM users   LIMIT 2,2"
&lt;/pre&gt;
&lt;p&gt;
	Are you wondering why it says LIMIT 2,2 and not 2,4? Well consider this:&lt;/p&gt;
&lt;pre&gt;&lt;span style="color: rgb(18, 65, 222);"&gt;clojureql.core&amp;gt; &lt;/span&gt;&lt;span style="font-weight: bold;"&gt;(-&amp;gt;&amp;gt; (range 10) (take 4) (drop 2))&lt;/span&gt;
(2 3)
&lt;/pre&gt;
&lt;p&gt;
	ClojureQL handles sequences exactly as in Clojure (btw. that all works in the same namespace).&lt;/p&gt;
&lt;h3&gt;
	Sort&lt;/h3&gt;
&lt;p&gt;
	Sort takes a table, a column to ORDER BY and a direction (keyword, :asc|:desc):&lt;/p&gt;
&lt;pre&gt;&lt;span style="color: rgb(18, 65, 222);"&gt;clojureql.core&amp;gt; &lt;/span&gt;&lt;span style="font-weight: bold;"&gt;(-&amp;gt; (table nil :users)
                    (sort [:id#asc])
                    to-sql)&lt;/span&gt;
"SELECT users.* FROM users ORDER BY users.id ASC"
&lt;/pre&gt;
&lt;h3&gt;
	Conj!&lt;/h3&gt;
&lt;p&gt;
	Conj! inserts a record or records into the table. A record is simply a hashmap and you can put multiple hashmaps inside a vector:&lt;/p&gt;
&lt;pre&gt;&lt;span style="color: rgb(18, 65, 222);"&gt;clojureql.core&amp;gt; &lt;/span&gt;&lt;span style="font-weight: bold;"&gt;@(-&amp;gt; (table db :users)
                     (project [:id])
                     (conj! {:name "Frank"}))&lt;/span&gt;
({:id 1} {:id 4} {:id 5} {:id 6} {:id 7} {:id 8} {:id 9} {:id 10} {:id 11} {:id 12})
&lt;/pre&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;h3&gt;
	Disj!&lt;/h3&gt;
&lt;p&gt;
	disj! removes a rename which matches the supplied predicate:&lt;/p&gt;
&lt;pre&gt;&lt;span style="color: rgb(18, 65, 222);"&gt;clojureql.core&amp;gt; &lt;/span&gt;&lt;span style="font-weight: bold;"&gt;@(-&amp;gt; (table db :users)
                     (project [:id])
                     (disj!  (where (= :name "Frank"))))&lt;/span&gt;
({:id 1} {:id 4} {:id 5} {:id 6} {:id 7} {:id 8} {:id 9} {:id 10})
&lt;/pre&gt;
&lt;h3&gt;
	Update-In!&lt;/h3&gt;
&lt;p&gt;
	update-in! again does as advertised, it finds the row(s) matching the predicate and update the information on them. If no rows match the predicate a new one is created:&lt;/p&gt;
&lt;pre&gt;&lt;span style="color: rgb(18, 65, 222);"&gt;clojureql.core&amp;gt; &lt;/span&gt;&lt;span style="font-weight: bold;"&gt;@(-&amp;gt; (table db :users)
                     (project [:id])
                     (update-in! (where (= :name "Frank"))
                                 {:name "John"}))&lt;/span&gt;
({:id 1} {:id 4} {:id 5} {:id 6} {:id 7} {:id 8} {:id 9} {:id 10} {:id 13})
&lt;/pre&gt;
&lt;h3&gt;
	With-Results&lt;/h3&gt;
&lt;p&gt;
	With-results is an alternative to deref which lets you pass a body that will be lazily evaluated on the open resultset. &lt;strike&gt;It takes a table first, then a placeholder for the results, then the body of code&lt;/strike&gt;: &lt;strong&gt;Updated&lt;/strong&gt;: It takes a binding vector, where you bind results to a table:&lt;br /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;span style="color: rgb(18, 65, 222);"&gt;clojureql.core&amp;gt; &lt;/span&gt;&lt;span style="font-weight: bold;"&gt;(with-results [rs users]&lt;br /&gt;                  (doseq [r rs]
                         (prn r)))&lt;/span&gt;
&lt;span style="color: rgb(143, 143, 143);"&gt;{:id 1}
{:id 4}
{:id 5}
{:id 6}
{:id 7}
{:id 8}
{:id 9}
{:id 10}
&lt;/span&gt;nil
&lt;/pre&gt;
&lt;p&gt;
	If you pass the optional :fetch-size argument to the database object you code will be called on each chunk, allowing you to work with huge datasets.&lt;/p&gt;
&lt;h2&gt;
	With-Connection&lt;/h2&gt;
&lt;p&gt;
	If you've constructed a table with nil as the connection object, you can simply wrap any database interaction with that table in (with-connection db-obj ..).&lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;h1&gt;
	Final words&lt;/h1&gt;
&lt;p&gt;
	I would like to thank both &lt;a target="_blank" href="http://twitter.com/kotarak"&gt;Meikel Brandmeyer&lt;/a&gt; and &lt;a target="_blank" href="http://twitter.com/zebudu"&gt;Nicolas Buduroi&lt;/a&gt; for helping me learn those tough lessons on the first, now scrapped, version of ClojureQL. I would also like to thank &lt;a target="_blank" href="http://twitter.com/cgrand"&gt;Christophe Grand&lt;/a&gt; who served as an inspiration to me in Frankfurt and finally a huge thank you goes out to &lt;a target="_blank" href="http://twitter.com/ninjudd"&gt;Justin Balthrop&lt;/a&gt; who has fought the good design fight with me on every step of the way towards ClojureQL(2) 1.0!&lt;/p&gt;
&lt;p&gt;
	Also my thanks go out to &lt;a target="_blank" href="http://joyofclojure.com/buy"&gt;Chris Houser&lt;/a&gt; who helped review the screencast, provide feedback and even contributed a slogan:&lt;/p&gt;
&lt;h2 style="text-align: center;"&gt;
	"ClojureQL - bringing Relational Algebra back to Relational Databases"&lt;/h2&gt;
&lt;p&gt;
	I hope you all take this library out for a spin and send some feedback (good, bad, cruel, performance related, all is accepted) back to me. Thanks and have fun!&lt;/p&gt;
&lt;br /&gt;
&lt;div style="background: url(&amp;quot;/images/authorbg.png&amp;quot;) no-repeat scroll left top transparent; width: 705px; height: 175px; padding: 10px;"&gt;
  &lt;a style="float: right; margin-top: 70px; margin-right: 60px;" target="_blank" href="http://feeds.feedburner.com/bestinclass-the-blog"&gt;&lt;img src="/images/rss.png" /&gt;&lt;/a&gt;
    &lt;a style="float: right; margin-top: 70px; margin-right: 60px;" target="_blank" href="http://twitter.com/laujensen"&gt;&lt;img src="/images/twitter.png" /&gt;&lt;/a&gt;
  &lt;h1&gt;About the author:&lt;/h1&gt;
  &lt;p style="width: 400px;"&gt;&lt;b&gt;Lau Jensen&lt;/b&gt; is the founder and owner of Best In Class a danish consultancy company which specializes in Clojure development. &lt;/p&gt;
  &lt;p style="width: 400px; margin-top: 1px;"&gt;&lt;b&gt;Lau&lt;/b&gt; is also one of the instructors driving the &lt;a href="http://www.conj-labs.eu"&gt;Conj Labs&lt;/a&gt; initiative. If you would like to be notified once new blogposts are published, you can follow Lau on &lt;a href="http://twitter.com/laujensen"&gt;Twitter.&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
</content>
  </entry><entry>
    <title>Best In Class: ClojureQL - Revolutions</title>
    <link href="http://www.bestinclass.dk/index.clj/2010/11/clojureql--revolutions.html" />
    <id>http://www.bestinclass.dk/index.clj/2010/11/clojureql--revolutions.html</id>
    <updated>2010-11-03T05:19:18Z</updated>
    <summary type="html">
    &lt;h1 id="title"&gt;ClojureQL - Revolutions&lt;/h1&gt;
    &lt;div id="pubdate"&gt;2010-11-03 05:19:18&lt;/div&gt;
    &lt;img id="thumb" src="http://www.bestinclass.dk/wp-content/uploads/avatars/clojureql.png" /&gt;
  &lt;div id="box"&gt;
	&lt;p&gt;
		With almost 2.5 years in the making, ClojureQL has taken its time coming into maturity. Recently Ive taken some drastic measures and trimmed the scope in order to get to the elusive 1.0.&lt;/p&gt;
	&lt;p&gt;
		 &lt;/p&gt;
&lt;/div&gt;
</summary>
    <content type="html">&lt;h1&gt;
	Preface&lt;/h1&gt;
&lt;p&gt;
	Two and half years ago I approached fellow Clojurian &lt;a href="http://twitter.com/kotarak" target="_blank"&gt;Meikel Brandmeyer&lt;/a&gt; to learn whether or not he would be interested in developing an advanced Clojure version of SchemeQL. We had 2 big dreams:&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;
		Being able to construct SQL statements using only pure Lisp&lt;/li&gt;
	&lt;li&gt;
		...and having those statements be valid on any backend (MySQL, Postgres, Oracle, you name it)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
	Both of us were just learning Clojure so the natural first step was to hammer out the fatal word "&lt;strong&gt;defmacro&lt;/strong&gt;". After a while of stepping on each others toes we decided to modularize the project, so that one of us could concentrate on the 'frontend' (user input) and the other on the backend (compiler output). Our first cut on the frontend received some insightful critique from Zef &lt;a href="http://zef.me/2637/on-language-design-my-problem-with-clojureql" target="_blank"&gt;here&lt;/a&gt;, which we took to heart and started improving upon - The problem was of course, the macros. Meikel volunteered to re-write the frontend to a system which relies on a Monad type of queries, but he quickly realized how much work this entailed and simply gassed out, so ClojureQL was at a stand still.&lt;/p&gt;
&lt;p&gt;
	The backend was quite advanced and even from its early days it could compile our own AST format into valid SQL for MySql, Sqlite, Derby and PostgresSQL. There were however two problems with this model.&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;
		It takes more work than any of us have time for, to maintain a myriad of backends&lt;/li&gt;
	&lt;li&gt;
		We started out too young.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
	Then what happend?&lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;h1&gt;
	Christophe happend&lt;/h1&gt;
&lt;p&gt;
	Christophe &lt;a href="http://twitter.com/cgrand" target="_blank"&gt;Grand&lt;/a&gt; is somewhat of an expert when it comes to designing DSLs. He's designed &lt;a href="http://github.com/cgrand/enlive" target="_blank"&gt;Enlive&lt;/a&gt; and &lt;a href="http://github.com/cgrand/moustache" target="_blank"&gt;Moustache&lt;/a&gt;, trained professionals in &lt;a href="http://conj-labs.eu" target="_blank"&gt;DSL design across Europe&lt;/a&gt; and even educated the &lt;a href="http://twitter.com/cgrand/status/28441353275" target="_blank"&gt;Americans on DSLs&lt;/a&gt; - So lets just say, he knows what he's talking about.&lt;/p&gt;
&lt;p&gt;
	Besides being a borderline genius, Christophe is also my co-instructor at the &lt;a href="http://conj-labs.eu" target="_blank"&gt;Conj Labs&lt;/a&gt; events and recently we just wrapped up such an event in Frankfurt. After 4 fast paced days, covering oceans of material, speaking, eating and drinking Clojure non-stop we finally ended up at a small round table in Frankfurt International Airport. Here we had about 4 hours just to chit/chat and since its impossible to tire of chatting about Clojure I wanted Christophes take on the direction ClojureQL was going in.&lt;/p&gt;
&lt;p&gt;
	Christophe looked down for a moment while he pondered ClojureQLs architecture and finally he looked up and said "I don't think I would have begun the way you did, I wouldnt go in that direction". In my mind that basically translated into "&lt;strong&gt;rm -rf clojureql/&lt;/strong&gt;", so he went on using yet another of his 70s shows analogies&lt;/p&gt;
&lt;blockquote&gt;
	&lt;p&gt;
		"Do you remember that 70s show about a Robot that acted like a Human? And how it was like 80% or 90% perfect human, but all anybody ever saw was the 10% that it was lacking? That's how it's going to be with ClojureQL. You might be able to make the backend stuff 90% transparent to the users, but they will see the 10% that's missing"&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;
	So to me that literally meant "&lt;strong&gt;rm -rf clojureql/&lt;/strong&gt;", so thats what I did.&lt;/p&gt;
&lt;p&gt;
	Then what happend?&lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;h1&gt;
	A simpler design&lt;/h1&gt;
&lt;p&gt;
	Deleting ClojureQL and picking it right back up again has been pleasant. Thankfully I've learned a lot about Clojure and DSL design since we put in the first lines of code 2.5 years ago, so its been a very rapid process of prototyping ideas and it's ongoing! Ultimately here's what I want to end up with:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;
		A simple, Clojuresque, interface for working with databases&lt;/li&gt;
	&lt;li&gt;
		A compiler which works only on datastructures, not macros&lt;/li&gt;
	&lt;li&gt;
		A compiler which lets users seamessly escape to raw SQL statements, for those odd syntax quirks of the various DBMs&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
	It's not done and here's what's driving the effort:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;
		I'm looking through applications I've developed trying to find better ways of expressing them from top to bottom&lt;/li&gt;
	&lt;li&gt;
		I'm requesting feedback from anybody and everybody who wants slick SQL integration for Clojure&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;h1&gt;
	Current Status&lt;/h1&gt;
&lt;p&gt;
	So with the fancy backend compiler that targets multiple DBMs out of the way, I am free to concentrate about the interface. Here's what I got jotted down so far:&lt;/p&gt;
&lt;h2&gt;
	Tables&lt;/h2&gt;
&lt;p&gt;
	Tables are at the heart of any SQL abstraction layer, so in ClojureQL they're first class citizens. Once you have defined a link to a table, you don't need to worry about specifying colums for every query, database connections, etc. Simply grab the name and act on it:&lt;/p&gt;
&lt;pre&gt;
user&amp;gt; (&lt;span style="color: rgb(18, 65, 222);"&gt;def&lt;/span&gt; &lt;span style="color: rgb(255, 66, 66);"&gt;users&lt;/span&gt; (table db-con &lt;span style="color: rgb(152, 83, 243);"&gt;:users&lt;/span&gt; [&lt;span style="color: rgb(152, 83, 243);"&gt;:id&lt;/span&gt; &lt;span style="color: rgb(152, 83, 243);"&gt;:name&lt;/span&gt; &lt;span style="color: rgb(152, 83, 243);"&gt;:title&lt;/span&gt;]))
#'user/users
&lt;/pre&gt;
A link to a table is like a reference type, it isn't its value but it just holds it. Dereferencing it at any point in time peeks at that value:
&lt;pre&gt;
user&amp;gt; @users
({&lt;span style="color: rgb(152, 83, 243);"&gt;:id&lt;/span&gt; 1, &lt;span style="color: rgb(152, 83, 243);"&gt;:name&lt;/span&gt; &lt;span style="color: rgb(143, 143, 143);"&gt;"Lau Jensen"&lt;/span&gt;, &lt;span style="color: rgb(152, 83, 243);"&gt;:title&lt;/span&gt; &lt;span style="color: rgb(143, 143, 143);"&gt;"Dev"&lt;/span&gt;} {&lt;span style="color: rgb(152, 83, 243);"&gt;:id&lt;/span&gt; 2, &lt;span style="color: rgb(152, 83, 243);"&gt;:name&lt;/span&gt; &lt;span style="color: rgb(143, 143, 143);"&gt;"Christophe"&lt;/span&gt;, &lt;span style="color: rgb(152, 83, 243);"&gt;:title&lt;/span&gt; &lt;span style="color: rgb(143, 143, 143);"&gt;"Design Guru"&lt;/span&gt;} {&lt;span style="color: rgb(152, 83, 243);"&gt;:id&lt;/span&gt; 3, &lt;span style="color: rgb(152, 83, 243);"&gt;:name&lt;/span&gt; &lt;span style="color: rgb(143, 143, 143);"&gt;"sthuebner"&lt;/span&gt;, &lt;span style="color: rgb(152, 83, 243);"&gt;:title&lt;/span&gt; &lt;span style="color: rgb(143, 143, 143);"&gt;"Mr. Macros"&lt;/span&gt;})&lt;/pre&gt;
&lt;p&gt;
	Typically in Clojure you can have two variations on a function. Take for example '&lt;strong&gt;conj'&lt;/strong&gt; which conjoins an item unto a copy of the original collection and compare it to '&lt;strong&gt;conj!&lt;/strong&gt;' which mutates a transient. In the same way ClojureQL provides &lt;strong&gt;conj!&lt;/strong&gt; and &lt;strong&gt;disj! &lt;/strong&gt;which both 'mutate' the table:&lt;/p&gt;
&lt;pre&gt;
user&amp;gt; @(&lt;span style="color: rgb(152, 83, 243);"&gt;disj!&lt;/span&gt; users {&lt;span style="color: rgb(152, 83, 243);"&gt;:id&lt;/span&gt; 3})
({&lt;span style="color: rgb(152, 83, 243);"&gt;:id&lt;/span&gt; 1, &lt;span style="color: rgb(152, 83, 243);"&gt;:name&lt;/span&gt; &lt;span style="color: rgb(143, 143, 143);"&gt;"Lau Jensen"&lt;/span&gt;, &lt;span style="color: rgb(152, 83, 243);"&gt;:title&lt;/span&gt; &lt;span style="color: rgb(143, 143, 143);"&gt;"Dev"&lt;/span&gt;} {&lt;span style="color: rgb(152, 83, 243);"&gt;:id&lt;/span&gt; 2, &lt;span style="color: rgb(152, 83, 243);"&gt;:name&lt;/span&gt; &lt;span style="color: rgb(143, 143, 143);"&gt;"Christophe"&lt;/span&gt;, &lt;span style="color: rgb(152, 83, 243);"&gt;:title&lt;/span&gt; &lt;span style="color: rgb(143, 143, 143);"&gt;"Design Guru"&lt;/span&gt;})&lt;span style="color: rgb(143, 143, 143);"&gt;"Mr. Macros"&lt;/span&gt;})

user&amp;gt; @(&lt;span style="color: rgb(152, 83, 243);"&gt;conj!&lt;/span&gt; users {&lt;span style="color: rgb(152, 83, 243);"&gt;:name&lt;/span&gt; &lt;span style="color: rgb(143, 143, 143);"&gt;"Frank"&lt;/span&gt; &lt;span style="color: rgb(152, 83, 243);"&gt;:title&lt;/span&gt; &lt;span style="color: rgb(143, 143, 143);"&gt;"Dev"&lt;/span&gt;})
({&lt;span style="color: rgb(152, 83, 243);"&gt;:id&lt;/span&gt; 1, &lt;span style="color: rgb(152, 83, 243);"&gt;:name&lt;/span&gt; &lt;span style="color: rgb(143, 143, 143);"&gt;"Lau Jensen"&lt;/span&gt;, &lt;span style="color: rgb(152, 83, 243);"&gt;:title&lt;/span&gt; &lt;span style="color: rgb(143, 143, 143);"&gt;"Dev"&lt;/span&gt;} {&lt;span style="color: rgb(152, 83, 243);"&gt;:id&lt;/span&gt; 2, &lt;span style="color: rgb(152, 83, 243);"&gt;:name&lt;/span&gt; &lt;span style="color: rgb(143, 143, 143);"&gt;"Christophe"&lt;/span&gt;, &lt;span style="color: rgb(152, 83, 243);"&gt;:title&lt;/span&gt; &lt;span style="color: rgb(143, 143, 143);"&gt;"Design Guru"&lt;/span&gt;} {&lt;span style="color: rgb(152, 83, 243);"&gt;:id&lt;/span&gt; 4 &lt;span style="color: rgb(152, 83, 243);"&gt;:name&lt;/span&gt; &lt;span style="color: rgb(143, 143, 143);"&gt;"Frank"&lt;/span&gt; &lt;span style="color: rgb(152, 83, 243);"&gt;:title&lt;/span&gt; &lt;span style="color: rgb(143, 143, 143);"&gt;"Dev"&lt;/span&gt;})&lt;/pre&gt;
&lt;p&gt;
	Notice how the returns from both calls have to be dereferenced to be read. This makes it easier to chain calls with the -&amp;gt; macro. In addition there are 2 less interesting helpers which I'll just mention as well:&lt;/p&gt;
&lt;pre&gt;
user&amp;gt; (&lt;span style="color: rgb(152, 83, 243);"&gt;take&lt;/span&gt; users 1)
({&lt;span style="color: rgb(152, 83, 243);"&gt;:id&lt;/span&gt; 1, &lt;span style="color: rgb(152, 83, 243);"&gt;:name&lt;/span&gt; &lt;span style="color: rgb(143, 143, 143);"&gt;"Lau Jensen"&lt;/span&gt;, &lt;span style="color: rgb(152, 83, 243);"&gt;:title&lt;/span&gt; &lt;span style="color: rgb(143, 143, 143);"&gt;"Dev"&lt;/span&gt;})

user&amp;gt; (&lt;span style="color: rgb(18, 65, 222);"&gt;-&amp;gt;&lt;/span&gt; (&lt;span style="color: rgb(152, 83, 243);"&gt;disj!&lt;/span&gt; users (either (&lt;span style="color: rgb(152, 83, 243);"&gt;=&lt;/span&gt; {&lt;span style="color: rgb(152, 83, 243);"&gt;:id&lt;/span&gt; 3}) (&lt;span style="color: rgb(152, 83, 243);"&gt;=&lt;/span&gt; {&lt;span style="color: rgb(152, 83, 243);"&gt;:id&lt;/span&gt; 4})))
          (&lt;span style="color: rgb(152, 83, 243);"&gt;sort&lt;/span&gt; &lt;span style="color: rgb(152, 83, 243);"&gt;:desc&lt;/span&gt;))
({&lt;span style="color: rgb(152, 83, 243);"&gt;:id&lt;/span&gt; 2, &lt;span style="color: rgb(152, 83, 243);"&gt;:name&lt;/span&gt; &lt;span style="color: rgb(143, 143, 143);"&gt;"Christophe"&lt;/span&gt;, &lt;span style="color: rgb(152, 83, 243);"&gt;:title&lt;/span&gt; &lt;span style="color: rgb(143, 143, 143);"&gt;"Design Guru"&lt;/span&gt;} {&lt;span style="color: rgb(152, 83, 243);"&gt;:id&lt;/span&gt; 1, &lt;span style="color: rgb(152, 83, 243);"&gt;:name&lt;/span&gt; &lt;span style="color: rgb(143, 143, 143);"&gt;"Lau Jensen"&lt;/span&gt;, &lt;span style="color: rgb(152, 83, 243);"&gt;:title&lt;/span&gt; &lt;span style="color: rgb(143, 143, 143);"&gt;"Dev"&lt;/span&gt;})&lt;/pre&gt;
&lt;p&gt;
	The first example is a simple LIMIT statement, but the second shows off a chained call and also the special predicate compiler which returns a statement that matches either id=3 or id=4.&lt;/p&gt;
&lt;p&gt;
	Finally, you have some freedom to do selects, here I'll demo both the escape and compiled version:&lt;/p&gt;
&lt;pre&gt;
user&amp;gt; (&lt;span style="color: rgb(61, 61, 61);"&gt;select&lt;/span&gt; users (where "id=%1 OR id&amp;gt;=%2" 1 10))
({&lt;span style="color: rgb(152, 83, 243);"&gt;:id&lt;/span&gt; 1, &lt;span style="color: rgb(152, 83, 243);"&gt;:name&lt;/span&gt; &lt;span style="color: rgb(143, 143, 143);"&gt;"Lau Jensen"&lt;/span&gt;, &lt;span style="color: rgb(152, 83, 243);"&gt;:title&lt;/span&gt; &lt;span style="color: rgb(143, 143, 143);"&gt;"Dev"&lt;/span&gt;})

user&amp;gt; (&lt;span style="color: rgb(61, 61, 61);"&gt;select&lt;/span&gt; users (where (either (&lt;span style="color: rgb(152, 83, 243);"&gt;=&lt;/span&gt; {&lt;span style="color: rgb(152, 83, 243);"&gt;:id&lt;/span&gt; 1}) (&lt;span style="color: rgb(152, 83, 243);"&gt;&amp;gt;=&lt;/span&gt; {&lt;span style="color: rgb(152, 83, 243);"&gt;:id&lt;/span&gt; 10}))))
({&lt;span style="color: rgb(152, 83, 243);"&gt;:id&lt;/span&gt; 1, &lt;span style="color: rgb(152, 83, 243);"&gt;:name&lt;/span&gt; &lt;span style="color: rgb(143, 143, 143);"&gt;"Lau Jensen"&lt;/span&gt;, &lt;span style="color: rgb(152, 83, 243);"&gt;:title&lt;/span&gt; &lt;span style="color: rgb(143, 143, 143);"&gt;"Dev"&lt;/span&gt;})&lt;/pre&gt;
&lt;p&gt;
	Use version1 if you have some very special syntax which the compiler cant generate and use version2 if you prefer to have a cleaner expression of your query. Finally, I provide a way of expressing joins which turns out to be quite simple since the table objects know about all the colums:&lt;/p&gt;
&lt;pre&gt;
user&amp;gt; (&lt;span style="color: rgb(61, 61, 61);"&gt;join&lt;/span&gt; users salary #{&lt;span style="color: rgb(152, 83, 243);"&gt;:users.id&lt;/span&gt; &lt;span style="color: rgb(152, 83, 243);"&gt;:salary.id&lt;/span&gt;})
({&lt;span style="color: rgb(152, 83, 243);"&gt;:wage&lt;/span&gt; 100, &lt;span style="color: rgb(152, 83, 243);"&gt;:title&lt;/span&gt; &lt;span style="color: rgb(143, 143, 143);"&gt;"Dev"&lt;/span&gt;, &lt;span style="color: rgb(152, 83, 243);"&gt;:name&lt;/span&gt; &lt;span style="color: rgb(143, 143, 143);"&gt;"Lau Jensen"&lt;/span&gt;, &lt;span style="color: rgb(152, 83, 243);"&gt;:id&lt;/span&gt; 1} {&lt;span style="color: rgb(152, 83, 243);"&gt;:wage&lt;/span&gt; 200, &lt;span style="color: rgb(152, 83, 243);"&gt;:title&lt;/span&gt; &lt;span style="color: rgb(143, 143, 143);"&gt;"Design Guru"&lt;/span&gt;, &lt;span style="color: rgb(152, 83, 243);"&gt;:name&lt;/span&gt; &lt;span style="color: rgb(143, 143, 143);"&gt;"Christophe"&lt;/span&gt;, &lt;span style="color: rgb(152, 83, 243);"&gt;:id&lt;/span&gt; 2} {&lt;span style="color: rgb(152, 83, 243);"&gt;:wage&lt;/span&gt; 300, &lt;span style="color: rgb(152, 83, 243);"&gt;:title&lt;/span&gt; &lt;span style="color: rgb(143, 143, 143);"&gt;"Mr. Macros"&lt;/span&gt;, &lt;span style="color: rgb(152, 83, 243);"&gt;:name&lt;/span&gt; &lt;span style="color: rgb(143, 143, 143);"&gt;"sthuebner"&lt;/span&gt;, &lt;span style="color: rgb(152, 83, 243);"&gt;:id&lt;/span&gt; 3})&lt;/pre&gt;
&lt;p&gt;
	Everything you see here and (especially) below is still in flux. It might change as this is a design phase, but I'm working quite quickly so I hope to cement a good design soon - But again, input is more than welcome!&lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;h2&gt;
	Predicates&lt;/h2&gt;
&lt;p&gt;
	Building predicates is the tricky part of SQL abstraction and also where we got burned the most in the early versions by relying heavily on macros - This time around I dare you to find a defmacro in the abstraction code! :)&lt;/p&gt;
&lt;p&gt;
	Basically what I have so far is an expression compiler and some helper functions to make that compiler more accessible. Here's how it works:&lt;/p&gt;
&lt;pre&gt;
user&amp;gt; (compile-expr [&lt;span style="color: rgb(152, 83, 243);"&gt;:or&lt;/span&gt; [&lt;span style="color: rgb(152, 83, 243);"&gt;:eq&lt;/span&gt; {&lt;span style="color: rgb(152, 83, 243);"&gt;:a&lt;/span&gt; 5}] [&lt;span style="color: rgb(152, 83, 243);"&gt;:gt&lt;/span&gt; {&lt;span style="color: rgb(152, 83, 243);"&gt;:b&lt;/span&gt; 5}]])
&lt;span style="color: rgb(143, 143, 143);"&gt;"(a = 5 OR b &amp;gt; 5)"&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;
	&lt;sup&gt;(thanks to Chousuke from #clojure for inspiration on the data-design)&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;
	The compiler simply walks a vector of vectors looking for special keywords denoting actions and colums. Colums have a little extra syntax in that they can be aggregates denoted by a period, like so:&lt;/p&gt;
&lt;pre&gt;
user&amp;gt; (compile-expr [&lt;span style="color: rgb(152, 83, 243);"&gt;:or&lt;/span&gt; [&lt;span style="color: rgb(152, 83, 243);"&gt;:eq&lt;/span&gt; {&lt;span style="color: rgb(152, 83, 243);"&gt;:a&lt;/span&gt; 5}] [&lt;span style="color: rgb(152, 83, 243);"&gt;:gt&lt;/span&gt; {&lt;span style="color: rgb(152, 83, 243);"&gt;:avg.b&lt;/span&gt; 5}]])
&lt;span style="color: rgb(143, 143, 143);"&gt;"(a = 5 OR avg(b) &amp;gt; 5)"&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;
	But of course, any sane person would rather write SQL directly than use such a syntax so here's the same code with the added layer of sugar:&lt;/p&gt;
&lt;pre&gt;
user&amp;gt; (compile-expr (either (&lt;span style="color: rgb(152, 83, 243);"&gt;=&lt;/span&gt; {&lt;span style="color: rgb(152, 83, 243);"&gt;:a&lt;/span&gt; 5}) (&lt;span style="color: rgb(152, 83, 243);"&gt;&amp;gt;&lt;/span&gt; {&lt;span style="color: rgb(152, 83, 243);"&gt;:avg.b&lt;/span&gt; 5})))
&lt;span style="color: rgb(143, 143, 143);"&gt;"(a = 5 OR avg(b) &amp;gt; 5)"&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;
	As a user you should never call &lt;strong&gt;compile-expr&lt;/strong&gt; yourself, I only show it here for demonstration purposes. Typically you'll use some function that requires matching and it will call &lt;strong&gt;compile-expr&lt;/strong&gt; for you. Two obvious example are &lt;strong&gt;disj!&lt;/strong&gt; and &lt;strong&gt;where&lt;/strong&gt;.&lt;/p&gt;
&lt;pre&gt;
user&amp;gt; (where (both (&lt;span style="color: rgb(152, 83, 243);"&gt;&amp;gt;&lt;/span&gt; {&lt;span style="color: rgb(152, 83, 243);"&gt;:a&lt;/span&gt; 5}) (&lt;span style="color: rgb(152, 83, 243);"&gt;&amp;lt;=&lt;/span&gt; {&lt;span style="color: rgb(152, 83, 243);"&gt;:b&lt;/span&gt; 10})))
&lt;span style="color: rgb(143, 143, 143);"&gt;"WHERE (a &amp;gt; 5 AND b&amp;lt;=10)"&lt;/span&gt;

user&amp;gt; (where (both (&lt;span style="color: rgb(152, 83, 243);"&gt;&amp;gt;&lt;/span&gt; {&lt;span style="color: rgb(152, 83, 243);"&gt;:a&lt;/span&gt; 5}) (either (&lt;span style="color: rgb(152, 83, 243);"&gt;&amp;lt;=&lt;/span&gt; {&lt;span style="color: rgb(152, 83, 243);"&gt;:b&lt;/span&gt; 10}) (&lt;span style="color: rgb(152, 83, 243);"&gt;&amp;gt;&lt;/span&gt; {&lt;span style="color: rgb(152, 83, 243);"&gt;:avg.y&lt;/span&gt; 100.0}))))
&lt;span style="color: rgb(143, 143, 143);"&gt;"WHERE (a &amp;gt; 5 AND (b&amp;lt;=10 OR avg(y) &amp;gt; 100.0))"&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;
	Both of these can be passed to a (select user ...) call, or the expression can be fed to disj! without the (where) call.&lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;h1&gt;
	Onwards!&lt;/h1&gt;
&lt;p&gt;
	So, if you're very sad and disgruntled that I deleted ClojureQL 0.9.7 Frontend 2.0 and you really wanted to see that make it all the way to version 1.0 don't dispair! The repo is still live on &lt;a href="http://gitorious.org/clojureql" target="_blank"&gt;Gitorious&lt;/a&gt; with both the master and frontend-2.0 branches so if you have mountain moving power, by all means, move it!&lt;/p&gt;
&lt;p&gt;
	If you're psyched about this type of SQL abstraction and want to contribute there's a number of ways you can do it:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;
		Send me design specs if you have good ideas&lt;/li&gt;
	&lt;li&gt;
		Attach patches if you have Clojure-fu&lt;/li&gt;
	&lt;li&gt;
		Convert some of your programs to use ClojureQL and get in touch with me if something doesn't work&lt;/li&gt;
	&lt;li&gt;
		...and tell me if something is so great that I absolutely musn't delete it&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
	If you're content just experimenting I recommend cloning &lt;a href="http://github.com/LauJensen/clojureql" target="_blank"&gt;the repo&lt;/a&gt; (which is now back on Github), adjusting the '&lt;strong&gt;db&lt;/strong&gt;' var in core.clj to match your local MySQL installation and then load the file core.clj and run '&lt;strong&gt;(test-suite)&lt;/strong&gt;'.&lt;/p&gt;
&lt;p&gt;
	Hope you enjoyed the read.&lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;&lt;br /&gt;
&lt;div style="background: url(&amp;quot;/images/authorbg.png&amp;quot;) no-repeat scroll left top transparent; width: 705px; height: 175px; padding: 10px;"&gt;
  &lt;a href="http://feeds.feedburner.com/bestinclass-the-blog" target="_blank" style="float:right; margin-top: 70px; margin-right: 60px;"&gt;&lt;img src="/images/rss.png" /&gt;&lt;/a&gt;
    &lt;a href="http://twitter.com/laujensen" target="_blank" style="float:right; margin-top: 70px; margin-right: 60px;"&gt;&lt;img src="/images/twitter.png" /&gt;&lt;/a&gt;
  &lt;h1&gt;About the author:&lt;/h1&gt;
  &lt;p style="width: 400px"&gt;&lt;b&gt;Lau Jensen&lt;/b&gt; is the founder and owner of Best In Class a danish consultancy company which specializes in Clojure development. &lt;/p&gt;
  &lt;p style="width: 400px; margin-top: 1px;"&gt;&lt;b&gt;Lau&lt;/b&gt; is also one of the instructors driving the &lt;a href="http://www.conj-labs.eu"&gt;Conj Labs&lt;/a&gt; initiative. If you would like to be notified once new blogposts are published, you can follow Lau on &lt;a href="http://twitter.com/laujensen"&gt;Twitter.&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
</content>
  </entry><entry>
    <title>Best In Class: Taking Uncle Bob to school</title>
    <link href="http://www.bestinclass.dk/index.clj/2010/10/taking-uncle-bob-to-school.html" />
    <id>http://www.bestinclass.dk/index.clj/2010/10/taking-uncle-bob-to-school.html</id>
    <updated>2010-10-08T09:23:11Z</updated>
    <summary type="html">
    &lt;h1 id="title"&gt;Taking Uncle Bob to school&lt;/h1&gt;
    &lt;div id="pubdate"&gt;2010-10-08 09:23:11&lt;/div&gt;
    &lt;img src="http://www.bestinclass.dk/wp-content/uploads/avatars/unclebob.png" id="thumb" /&gt;
  &lt;div id="box"&gt;
	&lt;p&gt;
		The Clojure community is one of the friendliest and most helpful communities around - Part of our charm comes from how whole heartedly we embrace new-comers and Uncle Bob is not going to be the exception. Normally I don't give out free consulting but for a fellow Clojurian, I'll make an exception so here's a lession in idiomatic Clojure for Uncle Bob.&lt;/p&gt;
	&lt;p&gt;
		 &lt;/p&gt;
&lt;/div&gt;
</summary>
    <content type="html">&lt;h1&gt;
	Preface&lt;/h1&gt;
&lt;p&gt;
	&lt;a target="_blank" href="http://www.objectmentor.com/omTeam/martin_r.html"&gt;Uncle Bob&lt;/a&gt; is a man shrouded in mystery, a man of opinions and contradictions - a developer and agile enthusiast. I hadn't heard about Uncle Bob until recently when he popped up on my radar as he was giving a talk about Clojure in Amsterdam. I asked around and learned that he wrote a book called "&lt;a target="_blank" href="http://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882"&gt;Clean code&lt;/a&gt;" and that he likes &lt;a target="_blank" href="http://www.c-sharpcorner.com/UploadFile/mgold/ZenGUIProgramming03122008231252PM/Images/BadGuiDesign.jpg"&gt;Ruby&lt;/a&gt;, which just makes no sense to me at all - How do you unify a tool as unstable, unpredictable, untamed as Ruby (second only to Perl) with Clean Code? Beats me, but maybe I should read his book.&lt;/p&gt;
&lt;p&gt;
	Recently I saw that Uncle Bob had written an &lt;a target="_blank" href="http://github.com/unclebob/clojureOrbit"&gt;Orbit Simulator&lt;/a&gt;, so I figured I'd read through it point out a few areas where the code could be more idiomatic, to help out Bob and other Ruby developers looking to take on Clojure.&lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;h1&gt;
	Orbital Overview&lt;/h1&gt;
&lt;p&gt;
	The Orbit Simulator is found &lt;a target="_blank" href="http://github.com/unclebob/clojureOrbit"&gt;here&lt;/a&gt;. Its very easy to run as Uncle Bob has made the package compilable to uberjar and thereby executable. Basically it generates about 500 objects all located at random positions around the sun and then simultates their orbit around the sun, checking for collisions, applying forces, that kind of thing. This particular simulation performs awfully because from top to bottom its expressed using functional sequences, &lt;strong&gt;which is great&lt;/strong&gt;. You can optimize this a bit, but not a lot, without loosing the purely functional but for a more performant version you'd have to rewrite the core to something a little less functional, which would defeat the purpose of the demo.&lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;h1&gt;
	Idiomatic Lisp&lt;/h1&gt;
&lt;p&gt;
	There are many things specific to Clojure that I want to run through, but before we get to that we need to examine the very basics: Our Lisp heritage. As the fantastic &lt;a target="_blank" href="http://blog.fogus.me/"&gt;Mr. Fogus&lt;/a&gt; talked about in his blogpost on &lt;a target="_blank" href="http://blog.fogus.me/2010/08/30/community-standards/"&gt;Community Standards&lt;/a&gt;, it's important not to alienate yourself from the community around you by inventing new odd personlized formats for your code. It will undoubtedly mean that a great deal of Clojurians will have a hard time looking at your code. Notice how Mr. Fogus uses his own brand of comma/period placement in that blogpost, that's how silly he thinks homemade Lisp formats are and I agree.&lt;/p&gt;
&lt;p&gt;
	Uncle Bob has unknowingly put himself on Mr. Fogus bad side, because he writes Lisp like so:&lt;/p&gt;
&lt;pre&gt;
(&lt;span style="color: rgb(18, 65, 222);"&gt;defn&lt;/span&gt; &lt;span style="color: rgb(255, 66, 66);"&gt;random-position&lt;/span&gt; [sun-position]
  (&lt;span style="color: rgb(18, 65, 222);"&gt;let&lt;/span&gt; [
        r (&lt;span style="color: rgb(152, 83, 243);"&gt;+&lt;/span&gt; (&lt;span style="color: rgb(152, 83, 243);"&gt;rand&lt;/span&gt; 300) 30)
        theta (&lt;span style="color: rgb(152, 83, 243);"&gt;rand&lt;/span&gt; (&lt;span style="color: rgb(152, 83, 243);"&gt;*&lt;/span&gt; 2 Math/PI))
        ]
    (position/add sun-position (position/make (&lt;span style="color: rgb(152, 83, 243);"&gt;*&lt;/span&gt; r (Math/cos theta)) (&lt;span style="color: rgb(152, 83, 243);"&gt;*&lt;/span&gt; r (Math/sin theta))))
    )
  )&lt;/pre&gt;
&lt;p&gt;
	Now to the untrained eye I dont know what that looks like. But to an eye trained on Lisp, it looks awful. Here's the idiomatic version:&lt;/p&gt;
&lt;pre&gt;
&lt;span style="color: rgb(255, 255, 255);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(18, 65, 222);"&gt;defn&lt;/span&gt; &lt;span style="color: rgb(255, 66, 66);"&gt;random-position&lt;/span&gt; [sun-position]
  (&lt;span style="color: rgb(18, 65, 222);"&gt;let&lt;/span&gt; [r     (&lt;span style="color: rgb(152, 83, 243);"&gt;+&lt;/span&gt; (&lt;span style="color: rgb(152, 83, 243);"&gt;rand&lt;/span&gt; 300) 30)
        theta (&lt;span style="color: rgb(152, 83, 243);"&gt;rand&lt;/span&gt; (&lt;span style="color: rgb(152, 83, 243);"&gt;*&lt;/span&gt; 2 Math/PI))]
    (position/add sun-position (position/make (&lt;span style="color: rgb(152, 83, 243);"&gt;*&lt;/span&gt; r (Math/cos theta)) (&lt;span style="color: rgb(152, 83, 243);"&gt;*&lt;/span&gt; r (Math/sin theta)))))&lt;span style="color: rgb(255, 255, 255);"&gt;)&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;
	Thats the kind of mistake that is easy to make when you take on a new language, however I've been kind of enough to clean up &lt;a target="_blank" href="http://github.com/LauJensen/clojureOrbit/commit/136021327aa9c06cce47fbe6a7ba44b7b469353e"&gt;every instance in his codebase&lt;/a&gt; :)&lt;/p&gt;
&lt;h1&gt;
	Namespaces&lt;/h1&gt;
&lt;p&gt;
	Lets have a look at namespace declarations. In Clojure we declare namespaces using the very versatile ns macro. Here's Uncle Bobs code:&lt;/p&gt;
&lt;pre&gt;
(&lt;span style="color: rgb(18, 65, 222);"&gt;ns&lt;/span&gt; orbit.world
  (&lt;span style="color: rgb(152, 83, 243);"&gt;:import&lt;/span&gt; (java.awt Color Dimension)
    (javax.swing JPanel JFrame Timer JOptionPane)
    (java.awt.event ActionListener KeyListener))
  (&lt;span style="color: rgb(152, 83, 243);"&gt;:use&lt;/span&gt; clojure.contrib.import-static))

(import-static java.awt.event.KeyEvent VK_LEFT VK_RIGHT VK_UP VK_DOWN)
(&lt;span style="color: rgb(152, 83, 243);"&gt;require&lt;/span&gt; ['physics.object &lt;span style="color: rgb(152, 83, 243);"&gt;:as&lt;/span&gt; 'object])
(&lt;span style="color: rgb(152, 83, 243);"&gt;require&lt;/span&gt; ['physics.vector &lt;span style="color: rgb(152, 83, 243);"&gt;:as&lt;/span&gt; 'vector])
(&lt;span style="color: rgb(152, 83, 243);"&gt;require&lt;/span&gt; ['physics.position &lt;span style="color: rgb(152, 83, 243);"&gt;:as&lt;/span&gt; 'position])&lt;/pre&gt;
&lt;p&gt;
	Although you see the ns macro doing both imports and uses here, it actually does require as well so here's a more idiomatic version:&lt;/p&gt;
&lt;pre&gt;
(&lt;span style="color: rgb(18, 65, 222);"&gt;ns&lt;/span&gt; orbit.world
  (&lt;span style="color: rgb(152, 83, 243);"&gt;:import&lt;/span&gt; (java.awt Color Dimension)
           (javax.swing JPanel JFrame Timer JOptionPane)
           (java.awt.event ActionListener KeyListener))
  (&lt;span style="color: rgb(152, 83, 243);"&gt;:use&lt;/span&gt; clojure.contrib.import-static)
  (&lt;span style="color: rgb(152, 83, 243);"&gt;:require&lt;/span&gt; [physics.object   &lt;span style="color: rgb(152, 83, 243);"&gt;:as&lt;/span&gt; object]
            [physics.vector   &lt;span style="color: rgb(152, 83, 243);"&gt;:as&lt;/span&gt; vector]
            [physics.position &lt;span style="color: rgb(152, 83, 243);"&gt;:as&lt;/span&gt; position]))

(import-static java.awt.event.KeyEvent VK_LEFT VK_RIGHT VK_UP VK_DOWN)
&lt;/pre&gt;
&lt;h1&gt;
	Concurrency Semantics&lt;/h1&gt;
&lt;p&gt;
	The code does a good job picking which places are immutable and which can mutate and be shared between threads. Particularily the &lt;em&gt;&lt;strong&gt;world&lt;/strong&gt;&lt;/em&gt; itself is a reference type as it must be exposed to the renderer. Unfortunately Uncle Bob decided to use the STM (Refs) for this job, which is a sub-optimal choice and here's why:&lt;/p&gt;
&lt;h3&gt;
	Synchronous coordinated change: Refs&lt;/h3&gt;
&lt;p&gt;
	Refs are great for when you need coordinated change, ie. the ability to look at two things at once, coordinating their change of state. When you need coordination there's no way around refs, but when you don't you should really find another way as the STM adds quite a bit of overhead to every transaction.&lt;/p&gt;
&lt;h3&gt;
	Synchronous uncoordinated change: Atoms&lt;/h3&gt;
&lt;p&gt;
	For synchronous uncoordinated change, atoms are your best pick. They're fast, they automatically respin if need be and they enforce all of the concurrency safety switches you need to forget about race conditions. For simply exposing the world to the renderer, atoms will do just fine.&lt;/p&gt;
&lt;h3&gt;
	Unsynchronous uncoordinated change: Agents&lt;/h3&gt;
&lt;p&gt;
	When you want something to go off, into another thread and go about its business and you don't care when or how it happens and require no coordination, agents are you best friend. Changes are still atomic, however not instant from the view of the caller.&lt;/p&gt;
&lt;h3&gt;
	Rewriting for atoms&lt;/h3&gt;
&lt;p&gt;
	Atoms are only slightly different in use from the STM. They use swap! instead of alter and don't require the surrounding dosync. Lets start with Uncle Bobs code:&lt;/p&gt;
&lt;pre&gt;
(&lt;span style="color: rgb(18, 65, 222);"&gt;defn&lt;/span&gt; &lt;span style="color: rgb(255, 66, 66);"&gt;update-world&lt;/span&gt; [world controls]
  (&lt;span style="color: rgb(18, 65, 222);"&gt;dosync&lt;/span&gt;
   (&lt;span style="color: rgb(152, 83, 243);"&gt;alter&lt;/span&gt; world #(object/update-all %))))
&lt;/pre&gt;
&lt;p&gt;
	The first thing to notice, is that controls is being passed as an argument, which it doesn't need to be. I assume thats legacy code. Secondly, from the docs it's clear that alter takes a ref as its first argument and a function as its second. But what is not being leveraged in this piece of code is that you can add an arbitrary amount of parameters to that function, like:&lt;/p&gt;
&lt;pre&gt;
(&lt;span style="color: rgb(18, 65, 222);"&gt;defn&lt;/span&gt; &lt;span style="color: rgb(255, 66, 66);"&gt;update-world&lt;/span&gt; [world controls]
  (&lt;span style="color: rgb(18, 65, 222);"&gt;dosync&lt;/span&gt;
   (&lt;span style="color: rgb(152, 83, 243);"&gt;alter&lt;/span&gt; world object/update-all)))
&lt;/pre&gt;
&lt;p&gt;
	Rewriting that to atoms looks like so:&lt;/p&gt;
&lt;pre&gt;
(&lt;span style="color: rgb(18, 65, 222);"&gt;defn&lt;/span&gt; &lt;span style="color: rgb(255, 66, 66);"&gt;update-world&lt;/span&gt; [world controls]
  (&lt;span style="color: rgb(152, 83, 243);"&gt;swap!&lt;/span&gt; world object/update-all))
&lt;/pre&gt;
&lt;p&gt;
	Here's another example which makes it clear how much is gained by using the functions idiomatically&lt;/p&gt;
&lt;pre&gt;
(&lt;span style="color: rgb(18, 65, 222);"&gt;defn&lt;/span&gt; &lt;span style="color: rgb(255, 66, 66);"&gt;magnify&lt;/span&gt; [factor controls world]
  (&lt;span style="color: rgb(18, 65, 222);"&gt;dosync&lt;/span&gt;
   (&lt;span style="color: rgb(18, 65, 222);"&gt;let&lt;/span&gt; [sun-position (&lt;span style="color: rgb(152, 83, 243);"&gt;:position&lt;/span&gt; (find-sun @world))
         new-mag (&lt;span style="color: rgb(152, 83, 243);"&gt;*&lt;/span&gt; factor (&lt;span style="color: rgb(152, 83, 243);"&gt;:magnification&lt;/span&gt; @controls))]
     (&lt;span style="color: rgb(152, 83, 243);"&gt;alter&lt;/span&gt; controls #(&lt;span style="color: rgb(152, 83, 243);"&gt;assoc&lt;/span&gt; % &lt;span style="color: rgb(152, 83, 243);"&gt;:magnification&lt;/span&gt; new-mag))
     (&lt;span style="color: rgb(152, 83, 243);"&gt;alter&lt;/span&gt; controls #(&lt;span style="color: rgb(152, 83, 243);"&gt;assoc&lt;/span&gt; % &lt;span style="color: rgb(152, 83, 243);"&gt;:center&lt;/span&gt; sun-position))
     (&lt;span style="color: rgb(152, 83, 243);"&gt;alter&lt;/span&gt; controls #(&lt;span style="color: rgb(152, 83, 243);"&gt;assoc&lt;/span&gt; % &lt;span style="color: rgb(152, 83, 243);"&gt;:clear&lt;/span&gt; true)))))&lt;/pre&gt;
&lt;p&gt;
	Written idiomatically, also using atoms looks like:&lt;/p&gt;
&lt;pre&gt;
(&lt;span style="color: rgb(18, 65, 222);"&gt;defn&lt;/span&gt; &lt;span style="color: rgb(255, 66, 66);"&gt;magnify&lt;/span&gt; [factor controls world]
  (&lt;span style="color: rgb(18, 65, 222);"&gt;dosync&lt;/span&gt;
   (&lt;span style="color: rgb(18, 65, 222);"&gt;let&lt;/span&gt; [sun-position (&lt;span style="color: rgb(152, 83, 243);"&gt;:position&lt;/span&gt; (find-sun @world))
         new-mag      (&lt;span style="color: rgb(152, 83, 243);"&gt;*&lt;/span&gt; factor (&lt;span style="color: rgb(152, 83, 243);"&gt;:magnification&lt;/span&gt; @controls))]
     (&lt;span style="color: rgb(152, 83, 243);"&gt;swap!&lt;/span&gt; controls assoc
            &lt;span style="color: rgb(152, 83, 243);"&gt;:magnification&lt;/span&gt; new-mag
            &lt;span style="color: rgb(152, 83, 243);"&gt;:center&lt;/span&gt;        sun-position
            &lt;span style="color: rgb(152, 83, 243);"&gt;:clear&lt;/span&gt;         true))))&lt;/pre&gt;
&lt;p&gt;
	Looks better, performs better and is more idiomatic.&lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;h1&gt;
	Idiomatic Conditionals&lt;/h1&gt;
&lt;p&gt;
	There are 3 main ways of doing conditionals in Clojure: cond, condp and case. The Orbit Sim uses cond rather heavily and in place where condp makes alot more sense. condp is like cond, but makes the code more readable when the predicate is the same for all dispatch routes. Here's the original code:&lt;/p&gt;
&lt;pre&gt;
(&lt;span style="color: rgb(18, 65, 222);"&gt;defn&lt;/span&gt; &lt;span style="color: rgb(255, 66, 66);"&gt;color-by-mass&lt;/span&gt; [{m &lt;span style="color: rgb(152, 83, 243);"&gt;:mass&lt;/span&gt;}]
  (&lt;span style="color: rgb(18, 65, 222);"&gt;cond&lt;/span&gt;
   (&lt;span style="color: rgb(152, 83, 243);"&gt;&amp;lt;&lt;/span&gt; m 1)  Color/black
   (&lt;span style="color: rgb(152, 83, 243);"&gt;&amp;lt;&lt;/span&gt; m 2)  (Color. 210 105 30)
   (&lt;span style="color: rgb(152, 83, 243);"&gt;&amp;lt;&lt;/span&gt; m 5)  Color/red
   (&lt;span style="color: rgb(152, 83, 243);"&gt;&amp;lt;&lt;/span&gt; m 10) (Color. 107 142 35)
   (&lt;span style="color: rgb(152, 83, 243);"&gt;&amp;lt;&lt;/span&gt; m 20) Color/magenta
   (&lt;span style="color: rgb(152, 83, 243);"&gt;&amp;lt;&lt;/span&gt; m 40) Color/blue
   &lt;span style="color: rgb(152, 83, 243);"&gt;:else&lt;/span&gt; (Color. 255 215 0)))&lt;/pre&gt;
&lt;p&gt;
	Here we see, that all predicates have something to do with &lt;em&gt;&lt;strong&gt;m&lt;/strong&gt;&lt;/em&gt; being smaller than something else. In condp we have to swap the position of the arguments, but that still gives us cleaner code. Notice the implicit :else at the bottom:&lt;/p&gt;
&lt;pre&gt;
(&lt;span style="color: rgb(18, 65, 222);"&gt;defn&lt;/span&gt; &lt;span style="color: rgb(255, 66, 66);"&gt;color-by-mass&lt;/span&gt; [{m &lt;span style="color: rgb(152, 83, 243);"&gt;:mass&lt;/span&gt;}]
  (&lt;span style="color: rgb(18, 65, 222);"&gt;condp&lt;/span&gt; &amp;gt; m
    1  Color/black
    2  (Color. 210 105 30)
    5  Color/red
    10 (Color. 107 142 35)
    20 Color/magenta
    40 Color/blue
    (Color. 255 215 0)))&lt;/pre&gt;
&lt;p&gt;
	In this case, the win is decent, but in the next example it's huge:&lt;/p&gt;
&lt;pre&gt;
(&lt;span style="color: rgb(18, 65, 222);"&gt;defn-&lt;/span&gt; &lt;span style="color: rgb(255, 66, 66);"&gt;quit-key?&lt;/span&gt; [c]
  (&lt;span style="color: rgb(152, 83, 243);"&gt;=&lt;/span&gt; \q c))

(&lt;span style="color: rgb(18, 65, 222);"&gt;defn-&lt;/span&gt; &lt;span style="color: rgb(255, 66, 66);"&gt;plus-key?&lt;/span&gt; [c]
  (&lt;span style="color: rgb(18, 65, 222);"&gt;or&lt;/span&gt; (&lt;span style="color: rgb(152, 83, 243);"&gt;=&lt;/span&gt; \+ c) (&lt;span style="color: rgb(152, 83, 243);"&gt;=&lt;/span&gt; \= c)))

(&lt;span style="color: rgb(18, 65, 222);"&gt;defn-&lt;/span&gt; &lt;span style="color: rgb(255, 66, 66);"&gt;minus-key?&lt;/span&gt; [c]
  (&lt;span style="color: rgb(18, 65, 222);"&gt;or&lt;/span&gt; (&lt;span style="color: rgb(152, 83, 243);"&gt;=&lt;/span&gt; \- c) (&lt;span style="color: rgb(152, 83, 243);"&gt;=&lt;/span&gt; \_ c)))

(&lt;span style="color: rgb(18, 65, 222);"&gt;defn-&lt;/span&gt; &lt;span style="color: rgb(255, 66, 66);"&gt;space-key?&lt;/span&gt; [c]
  (&lt;span style="color: rgb(152, 83, 243);"&gt;=&lt;/span&gt; \space c))

(&lt;span style="color: rgb(18, 65, 222);"&gt;defn-&lt;/span&gt; &lt;span style="color: rgb(255, 66, 66);"&gt;trail-key?&lt;/span&gt; [c]
  (&lt;span style="color: rgb(152, 83, 243);"&gt;=&lt;/span&gt; \t c))

(&lt;span style="color: rgb(18, 65, 222);"&gt;defn&lt;/span&gt; &lt;span style="color: rgb(255, 66, 66);"&gt;handle-key&lt;/span&gt; [c world controls]
  (&lt;span style="color: rgb(18, 65, 222);"&gt;cond&lt;/span&gt;
    (quit-key? c) (System/exit 1)
    (plus-key? c) (magnify 1.1 controls world)
    (minus-key? c) (magnify 0.9 controls world)
    (space-key? c) (magnify 1.0 controls world)
    (trail-key? c) (toggle-trail controls)))
&lt;/pre&gt;
&lt;p&gt;
	Style-wise I think Uncle Bob prefers to err on the verbose size, which is good in terms of clarity - And indeed his code is very easy to follow. However in this case I think he took it took far. My rewrite would look like this:&lt;/p&gt;
&lt;pre&gt;
(&lt;span style="color: rgb(18, 65, 222);"&gt;defn&lt;/span&gt; &lt;span style="color: rgb(255, 66, 66);"&gt;handle-key&lt;/span&gt; [c world controls]
  (&lt;span style="color: rgb(18, 65, 222);"&gt;condp&lt;/span&gt; = c
    \q     (System/exit 1)
    \+     (magnify 1.1 controls world)
    \-     (magnify 0.9 controls world)
    \space (magnify 1.0 controls world)
    \t     (toggle-trail controls)))&lt;/pre&gt;
&lt;p&gt;
	That saves us about 15 lines of code and sacrifices little or no clarity. In the above example all the test-constants are literals so you could re-write this using case instead of condp and that would give you constant time dispatch. Here's the faster version which also has an implicit else value (nil), for when the user presses an unmapped key. If you dont have this, you'll see exceptions.&lt;/p&gt;
&lt;pre&gt;
(&lt;span style="color: rgb(18, 65, 222);"&gt;defn&lt;/span&gt; &lt;span style="color: rgb(255, 66, 66);"&gt;handle-key&lt;/span&gt; [c world controls]
  (case c
    \q     (System/exit 1)
    \+     (magnify 1.1 controls world)
    \-     (magnify 0.9 controls world)
    \space (magnify 1.0 controls world)
    \t     (toggle-trail controls)
    nil))&lt;/pre&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;h1&gt;
	Being a little minimalistic&lt;/h1&gt;
&lt;p&gt;
	There are two reasons that the code is so slow. The first is that fact that it allocates an insane amount of objects. For the collision test Uncle Bob allocates all possible combinations of the 500 objects on every single frame, which takes ages (1 second) - And later the GC has to come clean this up again. The second reason, is that the code is doing a gazillion lookups since everything is put in structs. For the most part, this makes a lot of sense in terms of readability, but in two cases I think it goes too far: &lt;em&gt;&lt;strong&gt;position.clj&lt;/strong&gt;&lt;/em&gt; and &lt;em&gt;&lt;strong&gt;vector.clj&lt;/strong&gt;&lt;/em&gt;. These 2 files do pretty much the same thing, which is operations on coordinates. Most of us understand [x y] and dont need {:x x, :y y} right? So if I was writing something like that, I'd keep it slim when dealing with coordinates.&lt;/p&gt;
&lt;p&gt;
	This simplifies a lot of things like:&lt;/p&gt;
&lt;pre&gt;
(&lt;span style="color: rgb(18, 65, 222);"&gt;defn&lt;/span&gt; &lt;span style="color: rgb(255, 66, 66);"&gt;origin?&lt;/span&gt; [p]
  (&lt;span style="color: rgb(18, 65, 222);"&gt;and&lt;/span&gt;
    (zero? (&lt;span style="color: rgb(152, 83, 243);"&gt;:x&lt;/span&gt; p))
    (zero? (&lt;span style="color: rgb(152, 83, 243);"&gt;:y&lt;/span&gt; p))))&lt;/pre&gt;
&lt;p&gt;
	Which then simply becomes:&lt;/p&gt;
&lt;pre&gt;
(&lt;span style="color: rgb(18, 65, 222);"&gt;defn&lt;/span&gt; &lt;span style="color: rgb(255, 66, 66);"&gt;origin?&lt;/span&gt; [p]
  (&lt;span style="color: rgb(152, 83, 243);"&gt;every?&lt;/span&gt; zero? p))&lt;/pre&gt;
&lt;p&gt;
	Or&lt;/p&gt;
&lt;pre&gt;
(&lt;span style="color: rgb(18, 65, 222);"&gt;defn&lt;/span&gt; &lt;span style="color: rgb(255, 66, 66);"&gt;add&lt;/span&gt; [p q]
  (&lt;span style="color: rgb(152, 83, 243);"&gt;struct&lt;/span&gt; position
    (&lt;span style="color: rgb(152, 83, 243);"&gt;+&lt;/span&gt; (&lt;span style="color: rgb(152, 83, 243);"&gt;:x&lt;/span&gt; p) (&lt;span style="color: rgb(152, 83, 243);"&gt;:x&lt;/span&gt; q))
    (&lt;span style="color: rgb(152, 83, 243);"&gt;+&lt;/span&gt; (&lt;span style="color: rgb(152, 83, 243);"&gt;:y&lt;/span&gt; p) (&lt;span style="color: rgb(152, 83, 243);"&gt;:y&lt;/span&gt; q))))&lt;/pre&gt;
&lt;p&gt;
	Which becomes:&lt;/p&gt;
&lt;pre&gt;
(&lt;span style="color: rgb(18, 65, 222);"&gt;defn&lt;/span&gt; &lt;span style="color: rgb(255, 66, 66);"&gt;add&lt;/span&gt; [[x1 y1] [x2 y2]]
  [(&lt;span style="color: rgb(152, 83, 243);"&gt;+&lt;/span&gt; x1 x2) (&lt;span style="color: rgb(152, 83, 243);"&gt;+&lt;/span&gt; y1 y2)])&lt;/pre&gt;
&lt;p&gt;
	And finally, some of the functions in vector are generating anonymous functions &lt;strong&gt;everytime&lt;/strong&gt; they're called, which is also quite a slow-down. So to speed things up a little change&lt;/p&gt;
&lt;pre&gt;
(&lt;span style="color: rgb(18, 65, 222);"&gt;defn&lt;/span&gt; &lt;span style="color: rgb(255, 66, 66);"&gt;distance&lt;/span&gt; [p q]
  (&lt;span style="color: rgb(18, 65, 222);"&gt;letfn&lt;/span&gt; [(square [x] (&lt;span style="color: rgb(152, 83, 243);"&gt;*&lt;/span&gt; x x))]
    (Math/sqrt
      (&lt;span style="color: rgb(152, 83, 243);"&gt;+&lt;/span&gt;
        (square (&lt;span style="color: rgb(152, 83, 243);"&gt;-&lt;/span&gt; (&lt;span style="color: rgb(152, 83, 243);"&gt;:x&lt;/span&gt; p) (&lt;span style="color: rgb(152, 83, 243);"&gt;:x&lt;/span&gt; q)))
        (square (&lt;span style="color: rgb(152, 83, 243);"&gt;-&lt;/span&gt; (&lt;span style="color: rgb(152, 83, 243);"&gt;:y&lt;/span&gt; p) (&lt;span style="color: rgb(152, 83, 243);"&gt;:y&lt;/span&gt; q)))))))&lt;/pre&gt;
&lt;p&gt;
	into&lt;/p&gt;
&lt;pre&gt;
(&lt;span style="color: rgb(18, 65, 222);"&gt;defn&lt;/span&gt; &lt;span style="color: rgb(255, 66, 66);"&gt;distance&lt;/span&gt; [[x1 y1] [x2 y2]]
  (Math/sqrt
   (&lt;span style="color: rgb(152, 83, 243);"&gt;+&lt;/span&gt;
    (Math/pow (&lt;span style="color: rgb(152, 83, 243);"&gt;-&lt;/span&gt; x1 x2) 2)
    (Math/pow (&lt;span style="color: rgb(152, 83, 243);"&gt;-&lt;/span&gt; y1 y2) 2))))&lt;/pre&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;h1&gt;
	And finally, be dynamic!&lt;/h1&gt;
&lt;p&gt;
	Whenever you're writing code in Clojure make sure you have a good interactive development setup. Coding, compiling to uberjar, running is not a good idea. Coding, compiling, restarting repl is not good. It makes sense to be able to restart the program at will, cleaning up memory, re-evaluating functions while running, never even closing the JPanel. I think Uncle Bobs code was not intended for further development, but rather presentation so I won't use it as an example, but a real time-saver is to also ensure a good interactive setup.&lt;/p&gt;
&lt;h1&gt;
	Conclusion&lt;/h1&gt;
&lt;p&gt;
	Uncle Bob - We're glad to have you aboard, I hope you have lots of fun with Clojure and that the tips provided here are appreciated. To the rest of you - I dont write the standards for Clojure development, but you'll find them here: &lt;a target="_blank" href="http://www.assembla.com/wiki/show/clojure/Clojure_Library_Coding_Standards"&gt;Guidelines&lt;/a&gt;. If I've missed any core idioms in this post, please point them out.&lt;/p&gt;
&lt;p&gt;
	Generally I will say, that in demonstrating Clojure the Orbit Simulator does a very good job. Usually what people struggle with initially is adapting to the functional paradigmes, which Uncle Bob seems to have gotten right in the first try! There may be a little too much use of loop (where reduce could be used instead), but generally Im &lt;strong&gt;very&lt;/strong&gt; impressed with the app. Hope to see more high quality demos from you in the future! You can find my modifications: &lt;a target="_blank" href="http://github.com/LauJensen/clojureOrbit"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;br /&gt;
&lt;div style="background: url(&amp;quot;/images/authorbg.png&amp;quot;) no-repeat scroll left top transparent; width: 705px; height: 175px; padding: 10px;"&gt;
  &lt;a style="float:right; margin-top: 70px; margin-right: 60px;" target="_blank" href="http://feeds.feedburner.com/bestinclass-the-blog"&gt;&lt;img src="/images/rss.png" /&gt;&lt;/a&gt;
    &lt;a style="float:right; margin-top: 70px; margin-right: 60px;" target="_blank" href="http://twitter.com/laujensen"&gt;&lt;img src="/images/twitter.png" /&gt;&lt;/a&gt;
  &lt;h1&gt;About the author:&lt;/h1&gt;
  &lt;p style="width: 400px"&gt;&lt;b&gt;Lau Jensen&lt;/b&gt; is the founder and owner of Best In Class a danish consultancy company which specializes in Clojure development. &lt;/p&gt;
  &lt;p style="width: 400px; margin-top: 1px;"&gt;&lt;b&gt;Lau&lt;/b&gt; is also one of the instructors driving the &lt;a href="http://www.conj-labs.eu"&gt;Conj Labs&lt;/a&gt; initiative. If you would like to be notified once new blogposts are published, you can follow Lau on &lt;a href="http://twitter.com/laujensen"&gt;Twitter.&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
</content>
  </entry><entry>
    <title>Best In Class: A hackers Blackberry</title>
    <link href="http://www.bestinclass.dk/index.clj/2010/10/a-hackers-blackberry.html" />
    <id>http://www.bestinclass.dk/index.clj/2010/10/a-hackers-blackberry.html</id>
    <updated>2010-10-06T07:26:06Z</updated>
    <summary type="html">
    &lt;h1 id="title"&gt;A hackers Blackberry&lt;/h1&gt;
    &lt;div id="pubdate"&gt;2010-10-06 07:26:06&lt;/div&gt;
    &lt;img id="thumb" src="http://www.bestinclass.dk/wp-content/uploads/avatars/blackberry.jpg" /&gt;
  &lt;div id="box"&gt;
	&lt;p&gt;
		So since everybody seems to be equally interested in Clojure and productivity (good!), I just wanted to share my notes on the black berry which helps speed me up.&lt;/p&gt;
	&lt;p&gt;
		 &lt;/p&gt;
&lt;/div&gt;
</summary>
    <content type="html">&lt;h1&gt;
	Preface&lt;/h1&gt;
&lt;p&gt;
	One of the things which is really important to me is my toolkit - Im committed to always working with the best, most efficient, most supportive tools for the job. Recently I purchased the renowned developers keyboard &lt;strong&gt;Das Keyboard&lt;/strong&gt;, and recently I shipped it back to the supplier. The main reasons were&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;
		It didn't make me faster/more precise&lt;/li&gt;
	&lt;li&gt;
		The sound of it is deafening&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
	But one of the tools that I have been the most happy with is my trusty Black Berry so here's a report from the outskirts of BB land.&lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;h2&gt;
	Getting the right smartphone&lt;/h2&gt;
&lt;p&gt;
	When I first opened shop I just wanted a good phone which did emails great - I chose the IPhone. After using it for a while both the phone and the company that sells them didn't sit well with me, so I shipped it back. I decided to try the android instead, which was truly a disappointment. The android OS and the quality of the HTC phones could best be described as half-baked. So onwards to Black Berry (after a short stop at Nokia).&lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;h2&gt;
	Black Berry for Hackers&lt;/h2&gt;
&lt;p&gt;
	If you're a typical corporate consumer you'll buy your Black Berry and your expensive Black Berry dataplan and you'll be happy. If you're like me, you don't want to pay for bloat. When we were setting up our German &lt;a href="http://conj-labs.eu" target="_blank"&gt;Conj Labs&lt;/a&gt; session we had found a hotel which looked really nice, had all the trimmings, fair pricing etc. But taking a closer look at the paper-work, I noticed that they wanted something like 14€  per day, per attendant for &lt;strong&gt;internet access&lt;/strong&gt;. So we emailed them asking to void that ridicously fee - they wouldn't... so we found another hotel. Its not that we couldn't afford it, its that we wont pay for sillyness - same goes with phones and subscriptions.&lt;/p&gt;
&lt;p&gt;
	&lt;strong&gt;The Black Berry dataplan gives you:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;
		Push Email&lt;/li&gt;
	&lt;li&gt;
		Blackberry messaging&lt;/li&gt;
	&lt;li&gt;
		Online surfing&lt;/li&gt;
	&lt;li&gt;
		Downloadable apps over the air&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
	But what if I told you, that you could get all of that &lt;strong&gt;without&lt;/strong&gt; a Black Berry dataplan? You can! With the possible exception of BB Messaging, I didn't look into it.&lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;h2&gt;
	Getting online&lt;/h2&gt;
&lt;p&gt;
	I contacted my phone company to get the details needed for getting the Blackberry online - They said it wasn't possible. Then I got the instructions for a Nokia phone instead and lo and behold, they worked:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;
		Go to options&lt;/li&gt;
	&lt;li&gt;
		Go to TCP/IP&lt;/li&gt;
	&lt;li&gt;
		Enable APN and set the APN: to whatever they would use for Nokia/Samsung or whatever. (in my case its 'wap')&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
	Now you're able to browse the web using EDGE, which isn't too bad, though 3G would have been nice, but 3G is impossible since BB doesn't let us configure the proxy settings and so on for the APN. This alone lets you download lots of great apps from various sites around the web.&lt;/p&gt;
&lt;p&gt;
	To get the most out of your browsing I recommend getting &lt;a href="http://www.opera.com/mobile/download/blackberry/" target="_blank"&gt;Opera Mini&lt;/a&gt;. But now for the all important.....&lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;h2&gt;
	Push Email - My Funambol&lt;/h2&gt;
&lt;p&gt;
	Having push email is an absolute must for me and since the device is capable of it, why shouldn't I have it? Where the Black Berry solution costs you some money, &lt;a href="http://my.funambol.com/" target="_blank"&gt;My Funambol&lt;/a&gt; is completely free for the first 90 days - After the 90 days are up you have to either become a active/contributing member of the community or switch to another solution. If you stay, its still free, if you change provider it might cost you money, but look through &lt;a href="http://www.funambol.com/solutions/mobilesyncservices.php" target="_blank"&gt;this list&lt;/a&gt; of Funambol customers and see what your options are.&lt;/p&gt;
&lt;p&gt;
	Setting up My Funambol is so easy it must be illegal somewhere. Once you've created your account, log in to your main screen:&lt;/p&gt;
&lt;p style="text-align: center;"&gt;
	&lt;img alt="Funambol Main Screen" src="http://bestinclass.dk/wp-content/images/funambolmain.png" style="width: 680px; height: 501px;" /&gt;&lt;/p&gt;
&lt;p&gt;
	On the far left you see my email account(s). Here you simply add your account by filling in the server/login details etc and Funambol provides you with a sync url. It also supports synchronizing pictures and events.&lt;/p&gt;
&lt;p&gt;
	On the far right, you have links which you can follow to install the client software on your phone directly from the web. Once the you install the contact synchronization, you get this screen on your phone:&lt;/p&gt;
&lt;p style="text-align: center;"&gt;
	&lt;img alt="Funambol Sync App" src="http://bestinclass.dk/wp-content/images/funambolsync.jpg" style="width: 328px; height: 544px;" /&gt;&lt;/p&gt;
&lt;p&gt;
	Simply navigate to the item you want to sync and click the mouse button - Almost instantly, your contacts, calendar appointments, notes or whatever will popup in the Web UI - Cool :)&lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;h2&gt;
	Wish List&lt;/h2&gt;
&lt;p&gt;
	There are a couple of things which My Funambol leaves me wanting, which may or may not be in the pipe&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;
		Integration with the BB notification system, blinking LED&lt;/li&gt;
	&lt;li&gt;
		Customizable notifications&lt;/li&gt;
	&lt;li&gt;
		Notifications that respect bedside mode&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
	But thats really it, other than that this free app really delivers what you'd expect!&lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;h1&gt;
	Conclusion&lt;/h1&gt;
&lt;p&gt;
	Blackberry + My Funambol lets you reap the benefits of an expensive Blackberry dataplan without paying the costs - beautiful. And the application itself is so well crafted, so easy to use that its inspirational for me as a developer. Go check it out :)  My next pet-project will likely be to put Clojure on the Blackberry!&lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;&lt;div style="background: url(&amp;quot;/images/authorbg.png&amp;quot;) no-repeat scroll left top transparent; width: 705px; height: 175px; padding: 10px;"&gt;
  &lt;a href="http://feeds.feedburner.com/bestinclass-the-blog" target="_blank" style="float:right; margin-top: 70px; margin-right: 60px;"&gt;&lt;img src="/images/rss.png" /&gt;&lt;/a&gt;
    &lt;a href="http://twitter.com/laujensen" target="_blank" style="float:right; margin-top: 70px; margin-right: 60px;"&gt;&lt;img src="/images/twitter.png" /&gt;&lt;/a&gt;
  &lt;h1&gt;About the author:&lt;/h1&gt;
  &lt;p style="width: 400px"&gt;&lt;b&gt;Lau Jensen&lt;/b&gt; is the founder and owner of Best In Class a danish consultancy company which specializes in Clojure development. &lt;/p&gt;
  &lt;p style="width: 400px; margin-top: 1px;"&gt;&lt;b&gt;Lau&lt;/b&gt; is also one of the instructors driving the &lt;a href="http://www.conj-labs.eu"&gt;Conj Labs&lt;/a&gt; initiative. If you would like to be notified once new blogposts are published, you can follow Lau on &lt;a href="http://twitter.com/laujensen"&gt;Twitter.&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
</content>
  </entry><entry>
    <title>Best In Class: Best In Class - The tour</title>
    <link href="http://www.bestinclass.dk/index.clj/2010/09/best-in-class--the-tour.html" />
    <id>http://www.bestinclass.dk/index.clj/2010/09/best-in-class--the-tour.html</id>
    <updated>2010-09-08T08:30:20Z</updated>
    <summary type="html">
    &lt;h1 id="title"&gt;Best In Class - The tour&lt;/h1&gt;
    &lt;div id="pubdate"&gt;2010-09-08 08:30:20&lt;/div&gt;
    &lt;img id="thumb" src="http://www.bestinclass.dk/wp-content/uploads/avatars/demo.png" /&gt;
  &lt;div id="box"&gt;
	&lt;p&gt;
		This blogpost/screencast walks through some of the aspects involved with baking a website like Best In Class, looking at the source code and demoing the backend.&lt;/p&gt;
	&lt;p&gt;
		 &lt;/p&gt;
&lt;/div&gt;
</summary>
    <content type="html">&lt;h1&gt;
	Preface&lt;/h1&gt;
&lt;p&gt;
	Some time ago I generally described the process of baking Best In Class and afterwards released the source code. At present I hear and see many questions relating to Web Development which could be answered by reviewing the sourcecode for Best In Class (primarily admin.clj and templates.clj). So to save you guys the trouble of having to install the entire site yourselves, I've prepared a small screencast. If you want to hang around after the screencast, there's a general talk about baking below.&lt;/p&gt;
&lt;p style="text-align: center;"&gt;
	 &lt;/p&gt;
&lt;p style="text-align: center;"&gt;
	&lt;iframe frameborder="0" height="338" src="http://player.vimeo.com/video/14779418?title=0&amp;amp;byline=0" width="600"&gt;&lt;/iframe&gt;&lt;/p&gt;
&lt;p style="text-align: center;"&gt;
	&lt;a href="http://vimeo.com/14779418"&gt;Best In Class - The tour&lt;/a&gt; from &lt;a href="http://vimeo.com/laujensen"&gt;Lau Jensen&lt;/a&gt; on &lt;a href="http://vimeo.com"&gt;Vimeo&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;h1&gt;
	Avoiding performance craters&lt;/h1&gt;
&lt;p&gt;
	The old Best In Class was PHP driven. On every request that came in PHP would look into a database and fetch content, menus, comments etc, mix it with HTML and serve it. PHP is quite fast at doing this, but it still took so much time that during traffic spikes the site would becomes unresponsive and the backend nearly unuseable. I actually received a few emails from my hosting provider asking if everything was OK, because the app was tearing up the disks. Although it should be said, that back then I used to blog twice a week pretty consistently, which obviously puts more stress on the server than the sporadic posts that I find time for nowadays.&lt;/p&gt;
&lt;p&gt;
	So talking about scaling a simple blog seems silly - Unlike an application a blog should just sit there and serve its pages without any need for special scaling initiatives right? Right! So here's how to do that:&lt;/p&gt;
&lt;h1&gt;
	Don't use two databases&lt;/h1&gt;
&lt;p&gt;
	The old site (or any Wordpress/Drupal/Typo3 based site) actually used 2 databases. First there was a MySQL backend which contained all of the information about the site in an easily accessible format (SQL). Then secondly, once that was compiled a second version existed of the fused data and HTML. Why not just leave out the first database and simply rely on the second, the filesystem?&lt;/p&gt;
&lt;h3&gt;
	Well for one - There is actually dynamic content&lt;/h3&gt;
&lt;p&gt;
	Like comments, twitter updates, etc. But if you simply update the HTML file atomically instead of adding more data to the database, that will effectively give you the same result as using a backend SQL. This works well for comments, footers, headers etc. For something like a Twitter stream, simply write some Javascript to fetch it in the browser. One example is my comment box. It needs to be dynamic but the page which fetches it doesn't. Its simply brought in via Ajax from the Moustache backend. All that Moustache needs to know is who's calling, so thats baked into each page as well:&lt;/p&gt;
&lt;pre&gt;
(defsnippet post &lt;span style="color: rgb(143, 143, 143);"&gt;"blogpost.html"&lt;/span&gt; [&lt;span style="color: rgb(152, 83, 243);"&gt;:body&lt;/span&gt; &lt;span style="color: rgb(152, 83, 243);"&gt;:&amp;gt;&lt;/span&gt; any-node]
  [{&lt;span style="color: rgb(152, 83, 243);"&gt;:keys&lt;/span&gt; [title body thumb date comments link]}]
  [&lt;span style="color: rgb(152, 83, 243);"&gt;:h1#title&lt;/span&gt;]          (&lt;span style="color: rgb(61, 61, 61);"&gt;content&lt;/span&gt; title)
  [&lt;span style="color: rgb(152, 83, 243);"&gt;:img#thumb&lt;/span&gt;]         (set-attr &lt;span style="color: rgb(152, 83, 243);"&gt;:src&lt;/span&gt; (&lt;span style="color: rgb(152, 83, 243);"&gt;str&lt;/span&gt; thumb-prefix thumb))
  [&lt;span style="color: rgb(152, 83, 243);"&gt;:div#pubdate&lt;/span&gt;]       (&lt;span style="color: rgb(61, 61, 61);"&gt;content&lt;/span&gt; date)
  [&lt;span style="color: rgb(152, 83, 243);"&gt;:a#addcomment&lt;/span&gt;]      (set-attr &lt;span style="color: rgb(152, 83, 243);"&gt;:href&lt;/span&gt; (&lt;span style="color: rgb(152, 83, 243);"&gt;str&lt;/span&gt; &lt;span style="color: rgb(143, 143, 143);"&gt;"/cmt/url="&lt;/span&gt; link))
  [&lt;span style="color: rgb(152, 83, 243);"&gt;:div#post&lt;/span&gt;]          (append (html-snippet body))
  [&lt;span style="color: rgb(152, 83, 243);"&gt;:div.comment&lt;/span&gt;]       (clone-for [{&lt;span style="color: rgb(152, 83, 243);"&gt;:keys&lt;/span&gt; [author email date comment]} comments]
                                  [&lt;span style="color: rgb(152, 83, 243);"&gt;:div.author&lt;/span&gt;]       (&lt;span style="color: rgb(61, 61, 61);"&gt;content&lt;/span&gt; author)
                                  [&lt;span style="color: rgb(152, 83, 243);"&gt;:div.date&lt;/span&gt;]         (&lt;span style="color: rgb(61, 61, 61);"&gt;content&lt;/span&gt; date)
                                  [&lt;span style="color: rgb(152, 83, 243);"&gt;:div.message&lt;/span&gt; &lt;span style="color: rgb(152, 83, 243);"&gt;:pre&lt;/span&gt;] (&lt;span style="color: rgb(61, 61, 61);"&gt;content&lt;/span&gt; comment)))&lt;/pre&gt;
&lt;p&gt;
	The line which selects [:a#addcoment] matches any links (a tags) with the id 'addcomment' just like CSS and then sets the href. Once you get used to the prefixed colons, this reads and acts exactly(!) like CSS selectors and its all performed automatically whenever I call this template.&lt;/p&gt;
&lt;h3&gt;
	Second - The filesystem is unsafe!&lt;/h3&gt;
&lt;p&gt;
	I received a certified beatdown in #clojure from a fellow who was very protective of his data, juding that simply relying on the filesystem was an incredibly dangerous way to go. My oppinion is, that all disks will eventually crash. The time of the crash is determined by the disks usage and SQL is heavier on Disk I/O than a static site. Second, usually what matters in these situations is your backup routine and your failover - Best In Class can in its entirety be backed up using &lt;strong&gt;rsync&lt;/strong&gt;, can you say the same about an SQL database? Bottomline, the filesystem is completely safe and even an SQL database needs a working filesystem beneath it. In fact I'd say by simply using the filesystem as your database, you've removed a point of failure and reduced the complexity of your application.&lt;/p&gt;
&lt;h3&gt;
	Third - It can't possibly work!&lt;/h3&gt;
&lt;p&gt;
	When I reworked Best In Class I just knew that I was unhappy with the current setup and its performance, so after evalutating my options I decided to spend a few days on reworking the site using Enlive - There has been zero regrets. It was a fast rewrite and much of the time was spent writing a conversion routine for exporting all of the old blogposts from Wordpress to the new format. I decided to put all of the source online, so that an ambitious Clojure hacker moving from any kind of blogging platform could find some useful snippets. Also, did you know that Enlive lets you completely separate presentation from code? There is zero code in the HTML and zero HTML in the code, so I could work out the entire design in HTML upfront and just inject data using the CSS selectors.&lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;h1&gt;
	Make life a little easier&lt;/h1&gt;
&lt;p&gt;
	Even if performance wasn't an issue, this would still be an optimal way to go in many cases. You can forever say goodbye to database maintenance, updates, heavy backup routines etc. The entire site is stored neatly in a folder which is ready to be tarballed or rsynced to a backup location - And the entire site can be reployed using nothing more than rsync - Truly an easier life.&lt;/p&gt;
&lt;p&gt;
	The Moustache backend is usually the part of Best In Class that I tweak the most, adding features here and there. The wonderful thing about a completely static site, is the fact that I can restart the backend at runtime without any users being affected. Only in the rare situation that a user hits the 'Add comment button' in the exact same moment that I'm restart will somebody notice and I haven't received any complaints yet.&lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;h1&gt;
	Final thoughts&lt;/h1&gt;
&lt;p&gt;
	Best In Class is faster than ever. And as a bonus - Did you notice how fast the admin panel came up? When I enter that URL all of the stats are compiled at that moment, and it takes about 1 second. The old PHP solution (which admittedly did a little more statistics, but not a lot) would take so long that sometimes my request would time out. If you want to see how it's done, the source code is still on: &lt;a href="http://github.com/LauJensen/bestinclass.dk" target="_blank"&gt;Github&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;&lt;div style="background: url(&amp;quot;/images/authorbg.png&amp;quot;) no-repeat scroll left top transparent; width: 705px; height: 175px; padding: 10px;"&gt;
  &lt;a href="http://feeds.feedburner.com/bestinclass-the-blog" target="_blank" style="float:right; margin-top: 70px; margin-right: 60px;"&gt;&lt;img src="/images/rss.png" /&gt;&lt;/a&gt;
    &lt;a href="http://twitter.com/laujensen" target="_blank" style="float:right; margin-top: 70px; margin-right: 60px;"&gt;&lt;img src="/images/twitter.png" /&gt;&lt;/a&gt;
  &lt;h1&gt;About the author:&lt;/h1&gt;
  &lt;p style="width: 400px"&gt;&lt;b&gt;Lau Jensen&lt;/b&gt; is the founder and owner of Best In Class a danish consultancy company which specializes in Clojure development. &lt;/p&gt;
  &lt;p style="width: 400px; margin-top: 1px;"&gt;&lt;b&gt;Lau&lt;/b&gt; is also one of the instructors of driving the &lt;a href="http://www.conj-labs.eu"&gt;Conj Labs&lt;/a&gt; initiative. If you would like to be notified once new blogposts are published, you can follow Lau on &lt;a href="http://twitter.com/laujensen"&gt;Twitter.&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
</content>
  </entry><entry>
    <title>Best In Class: Developer Productivity - The Red Pill</title>
    <link href="http://www.bestinclass.dk/index.clj/2010/08/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:22Z</updated>
    <summary type="html">
    &lt;h1 id="title"&gt;Developer Productivity - The Red Pill&lt;/h1&gt;
    &lt;div id="pubdate"&gt;2010-08-26 10:19:22&lt;/div&gt;
    &lt;img src="http://www.bestinclass.dk/wp-content/uploads/avatars/quality.png" id="thumb" /&gt;
  &lt;p&gt;
	Im very eager to return to blogging about Clojure, but right now I have a loose productivity end which I need to take care of. In this post you will get a few producitivity tips as well as my configs for Emacs, Awesome and Wanderlust.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;
</summary>
    <content type="html">&lt;/p&gt;
&lt;h1&gt;
	Preface&lt;/h1&gt;
&lt;p style="text-align: center;"&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;br /&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 target="_blank" href="http://conj-labs.eu"&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 target="_blank" href="http://twitter.com/laujensen"&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 target="_blank" href="http://bestinclass.dk/index.clj/2010/07/trail-blazing-innovators.html"&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 target="_blank" href="http://www.conkeror.org"&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 colleagues/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 target="_blank" href="http://conj-labs.eu"&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 target="_blank" href="http://twitter.com/cgrand"&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 target="_blank" href="http://github.com/LauJensen/Configs"&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 target="_blank" href="http://github.com/LauJensen/Configs"&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 target="_blank" href="http://conj-labs.eu"&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 target="_blank" href="http://twitter.com/cgrand"&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 target="_blank" href="http://innoq.com"&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;
</content>
  </entry><entry>
    <title>Best In Class: Trail blazing innovators</title>
    <link href="http://www.bestinclass.dk/index.clj/2010/07/trail-blazing-innovators.html" />
    <id>http://www.bestinclass.dk/index.clj/2010/07/trail-blazing-innovators.html</id>
    <updated>2010-07-07T07:17:42Z</updated>
    <summary type="html">
    &lt;h1 id="title"&gt;Trail blazing innovators&lt;/h1&gt;
    &lt;div id="pubdate"&gt;2010-07-07 07:17:42&lt;/div&gt;
    &lt;img id="thumb" src="http://www.bestinclass.dk/wp-content/uploads/avatars/fastbox.png" /&gt;
  &lt;p&gt;
	The week before last I had an opportunity to sit down with an impressive pack of developers. We were gathered to study &lt;a href="http://conj-labs.eu" target="_blank"&gt;Clojure in depth&lt;/a&gt;, but as the days passed many other interesting topics were covered. In this short post I'll recount some of the lessons and also share a productivity booster.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;br /&gt;
</summary>
    <content type="html">&lt;/p&gt;
&lt;h1&gt;
	Preface&lt;/h1&gt;
&lt;p&gt;
	The first ever ConjLabs was held the week before last in Brussels and in attendance were some of the more innovative developers of Europe. After each of them got back home, my feeling is that people really were able to step up to the &lt;a href="http://blog.higher-order.net/2010/07/04/conj-labs-clojure-lessons-part-i/" style="" target="_blank"&gt;next level of their Clojure game&lt;/a&gt; after those 3 days. One of the guys asked me "Well how do you market an event like this?" and the answer is simple: We didn't. The first Conj Labs was similar to raising a magnet which draws in natural born innovators and see who would show up.&lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;h1&gt;
	Innovators in action&lt;/h1&gt;
&lt;p&gt;
	The crowd consisted of experienced developers who were well established in a variety of languages, one of them even knew Perl. In common, they all shared a desire to improve on their current skillset in the hopes of producing better software. One guy said "My ambition is to build small beautiful programs, that are simple and easy to maintain and my hope is, that Clojure is the language which will let me do that." (thanks Walter). I think he expressed an ambition which we all shared, but during the week it occured to me that I was amongst a special brand of gentlemen. For a large part of my carreer I have worked primarily with people who have found something which lets them complete tasks, be it C, C++, Java or whatever. And once they've attained a certain level of mastery over one of these languages, they disregard the glaring problems and productivity inhibitors and push on to complete the assignment on their desk. The magnet-marketing trick had effectively brought in a different crowd.&lt;/p&gt;
&lt;p&gt;
	Another attendant related how he works on a massive code-base for a world wide corporation, where he was tag-teaming with hundreds of developers in C++ in order to add incremental changes to their product. I asked "Its not very mentally challenging is it?" and where many developers might have said yes (and felt it), he said no. He was looking to build projects in a language which would let him be work on &lt;strong&gt;the problem&lt;/strong&gt; and not the limitations/traditions/ceremonies of the language.&lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;h1&gt;
	Innovative weaponry&lt;/h1&gt;
&lt;p&gt;
	At the lab there were many different setups. We had Danish keyboards, French keyboards, Dutch keyboards and many more. Almost all of the attendants were wielding Macbooks and OSX while the &lt;a href="http://conj-labs.eu/instructors.html" style="" target="_blank"&gt;instructors&lt;/a&gt; were on Lenovos. One guy remarked "Its weird to see someone as smart as &lt;a href="http://www.conj-labs.eu/instructors.html#christophe" style="" target="_blank"&gt;Christophe&lt;/a&gt; using Windows" and I couldn't agree more. So in the name of higher education I agreed with Christophe to have him firmly planted in Emacs for the duration of the Labs. Why? Because Emacs is a black hole which eventually sucks in all productivity killers allowing you to reach &lt;strong&gt;previously impossible measures of productivity.&lt;/strong&gt; The stumbling block, is that you need to crave innovation and productivity, otherwise you might not be able to look past the old-fashioned interface and enormous help file. C-h t however, lets you hit the ground running (emacs tutorial).&lt;/p&gt;
&lt;p&gt;
	I've prepared a small screencast to demonstrate a few of the reasons why Emacs is the IDE of choice for Clojure development, as well the for many other languages. The main pull of Emacs is nothing Clojure specific, rather its the ability to unify all of your tools within the same program:&lt;/p&gt;
&lt;p style="text-align: center;"&gt;
        &lt;object height="480" width="600"&gt;&lt;param value="true" name="allowfullscreen"&gt;&lt;/param&gt;&lt;param value="always" name="allowscriptaccess"&gt;&lt;/param&gt;&lt;param value="http://vimeo.com/moogaloop.swf?clip_id=13158054&amp;amp;server=vimeo.com&amp;amp;show_title=0&amp;amp;show_byline=0&amp;amp;show_portrait=1&amp;amp;color=00adef&amp;amp;fullscreen=1" name="movie"&gt;&lt;/param&gt;&lt;embed height="480" width="600" allowscriptaccess="always" allowfullscreen="true" type="application/x-shockwave-flash" src="http://vimeo.com/moogaloop.swf?clip_id=13158054&amp;amp;server=vimeo.com&amp;amp;show_title=0&amp;amp;show_byline=0&amp;amp;show_portrait=1&amp;amp;color=00adef&amp;amp;fullscreen=1"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://vimeo.com/13158054"&gt;Emacs - IDEverything&lt;/a&gt; from &lt;a href="http://vimeo.com/laujensen"&gt;Lau Jensen&lt;/a&gt; on &lt;a href="http://vimeo.com"&gt;Vimeo&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;
	There are a few keys to obtaining über productivity which I try to live by:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;
		Stay on the keyboard and off the mouse!  (for everything)
		&lt;ul&gt;
			&lt;li&gt;
				That means use Emacs for everything and &lt;a href="http://conkeror.org/" style="" target="_blank"&gt;Conkeror&lt;/a&gt; for the rest&lt;/li&gt;
		&lt;/ul&gt;
	&lt;/li&gt;
	&lt;li&gt;
		Keep as much functionality as possible in Emacs
		&lt;ul&gt;
			&lt;li&gt;
				That gives you a very uniform interface, your fingers will know what to do&lt;/li&gt;
		&lt;/ul&gt;
	&lt;/li&gt;
	&lt;li&gt;
		Make friends with Emacs keyboard bindings
		&lt;ul&gt;
			&lt;li&gt;
				Since you can now use them for everything, it makes sense to obtain Emacs mastery&lt;/li&gt;
		&lt;/ul&gt;
	&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
	I know that there are many would disagree and claim that Mouse-driven IDEs and XML based configs are the way to move forward, but I firmly believe that such convictions stem from a lack of exposure. If you're already an Emacser, I recommend reviewing your toolbox and seeing how much you can stuff into Emacs. If you're not, I highly recommend throwing yourself off the deep end, you'll be surprised a how quickly you start swimming fast while your colleagues are still in float-mode.&lt;/p&gt;
&lt;p&gt;
	I've made the following deliberate choices:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;
		I run Arch linux because it's a slim, safe and stable distro with just around zero bloat&lt;/li&gt;
	&lt;li&gt;
		I use Awesome as my WM because it allows me to stay off the mouse entirely&lt;/li&gt;
	&lt;li&gt;
		I use Emacs as my IRC client, Email client, Addressbook manager, Dayplanner, Code editor, Revision Control interface, and much more&lt;/li&gt;
	&lt;li&gt;
		I use Tilda for fast shell access&lt;/li&gt;
	&lt;li&gt;
		I used to run Gnome-do, but I havent installed that on Arch yet since Awesome has a similar feature but with zero bloat&lt;/li&gt;
	&lt;li&gt;
		I used to run all my chat-networks through bitlbee and straight into Emacs but I havent installed that on Arch - I might though.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
	You don't have to do it like I do it as long as you get the big wins from the first list, but I'll admit Ive never seen an effective setup on neither OSX or Windows - However, if one such exists feel free to add it in the comments.&lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;h1&gt;
	Conclusion&lt;/h1&gt;
&lt;p&gt;
	The first &lt;a href="http://conj-labs.eu" style="" target="_blank"&gt;Conj Labs&lt;/a&gt; was fantastic and everybody walked away with a lot of tools/skills to get them to the next level of their Clojure game. We are already mounting the next session which will be in Germany, if you want to be notified when the details are in place either &lt;a href="http://twitter.com/LauJensen" style="" target="_blank"&gt;follow me on twitter&lt;/a&gt;, watch &lt;a href="http://conj-labs.eu" style="" target="_blank"&gt;conj-labs.eu&lt;/a&gt; or send me an &lt;a href="mailto:lau.jensen@bestinclass.dk" style=""&gt;email&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;
	If I the interest is high enough, I might do a separate blogpost demonstrating my config files :)&lt;/p&gt;
</content>
  </entry><entry>
    <title>Best In Class: Now Open Sourced</title>
    <link href="http://www.bestinclass.dk/index.clj/2010/06/best-in-class--now-open-sourced.html" />
    <id>http://www.bestinclass.dk/index.clj/2010/06/best-in-class--now-open-sourced.html</id>
    <updated>2010-06-04T00:26:34Z</updated>
    <summary type="html">
    &lt;h1 id="title"&gt;Best In Class - Now Open Sourced&lt;/h1&gt;
    &lt;div id="pubdate"&gt;2010-06-04 12:26:34&lt;/div&gt;
    &lt;img id="thumb" src="http://www.bestinclass.dk/wp-content/uploads/avatars/web20.png" /&gt;
  &lt;p&gt;
	Spring cleaning is complete and the driving code behind bestinclass.dk is now being released as opensource. With it you can generate a static site, import a wordpress blog, emit feeds (atom) and much much more.&lt;/p&gt;
&lt;p&gt;
</summary>
    <content type="html">&lt;/p&gt;
&lt;h1&gt;
	Preface&lt;/h1&gt;
&lt;p&gt;
	Last month I did a remake of BestInClass.dk and afterwards I was very tied up preparing for the &lt;a href="http://conj-labs.eu"&gt;Conj Labs&lt;/a&gt; session here in June. But now that we're catching up, I figured I would clean the code-base and release it.&lt;/p&gt;
&lt;p&gt;
	One big win to this approach is that you can fiddle with the backend all you want and once you're ready to update, just rsync the code to the server and call restart on the jetty script. The only downtime your users will experience is between the closing of the socket and until Jetty is up again, and &lt;strong&gt;only users&lt;/strong&gt; who are clicking the comment button at that exact time will notice!&lt;/p&gt;
&lt;h1&gt;
	Caveat&lt;/h1&gt;
&lt;p&gt;
	One of the things which can come in handy when you're rapidly testing web-handlers, is &lt;a href="http://github.com/cgrand/moustache" target="_blank"&gt;Moustache&lt;/a&gt;. I used it heavily during the first days of development and I've left the &lt;strong&gt;webview.clj&lt;/strong&gt; file in the repo, as a reminder to others not to let your prototyping grow out of hand. If you want to do some prototyping which mimics what I did, then feel free to use it otherwise just remove it.&lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;h1&gt;
	Security&lt;/h1&gt;
&lt;p&gt;
	You might be wondering how the backend is secured, since there's no standard auth lib available for ring/moustache. The backend opens an interface which only answers to calls from 127.0.0.1, meaning the webserver it self. To reach it you have to get through a reverse proxy pass, which filters the reponses based on certain criteria, which amount to this: If you're not me, you're not getting proxied. So almost all security is at the webserver level.&lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;h1&gt;
	Points of Interest&lt;/h1&gt;
&lt;p&gt;
	The primary &lt;strong&gt;bestinclass.clj&lt;/strong&gt; file was used by me when I deployed bestinclass.dk for the first time. Its a one off event since it goes through all of the :WP:POST entries in the Wordpress backup file and generates the html version of those posts. Afterwards, the static pages "&lt;a href="http://bestinclass.dk/index.html" style=""&gt;Forside&lt;/a&gt;", "&lt;a href="http://bestinclass.dk/services.html"&gt;Services&lt;/a&gt;" etc are generated and finally the atom feed is generated. All of these emissions of html/xml call templates or snippets found in the &lt;strong&gt;templates.clj&lt;/strong&gt; file. The file should more approriately be used to start the admin interface now, but adjust it to your needs.&lt;/p&gt;
&lt;p&gt;
	While the generation of the site shows of Enlive better half namely "&lt;em&gt;&lt;strong&gt;templates&lt;/strong&gt;&lt;/em&gt;" then the Wordpress import module shows of "&lt;em&gt;&lt;strong&gt;selections&lt;/strong&gt;&lt;/em&gt;" or scraping. Some of the selectors are a little complex and I must admit I've consulted with both &lt;a href="http://clj-me.cgrand.net" target="_blank"&gt;Christophe&lt;/a&gt; and &lt;a href="http://github.com/swannodette/enlive-tutorial/" target="_blank"&gt;David Nolen&lt;/a&gt; to arrive at the result. However it stands as a very good demo of just how powerful &lt;a href="http://github.com/cgrand/enlive" target="_blank"&gt;Enlive&lt;/a&gt; is.&lt;/p&gt;
&lt;h1&gt;
	Backend features&lt;/h1&gt;
&lt;p&gt;
	The backend features as not-so minimalistic &lt;a href="http://ckeditor.com/" target="_blank"&gt;editor&lt;/a&gt;:&lt;/p&gt;
&lt;p style="text-align: center;"&gt;
	&lt;a href="http://bestinclass.dk/wp-content/posts/opensourced/editor.jpg"&gt;&lt;img alt="Editor" src="http://bestinclass.dk/wp-content/posts/opensourced/editor.jpg" style="width: 450px; height: 400px;" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;
	There's also some statistics and an interface for comment moderation. Since I added the custom captcha I have not received one single spam comment - &lt;strong&gt;not one!&lt;/strong&gt; If you want to test the comment interface yourself without running the frontend through a webserver, you can post like this:&lt;/p&gt;
&lt;p&gt;
	&lt;code&gt;$ curl -d "url=someurl&amp;amp;name=Lau&amp;amp;email=mymail&amp;amp;captcha=10&amp;amp;cid=0&amp;amp;comment=hi" http://127.0.0.1:8080/cmt/&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;
	The url is only used to determine which file to write the comment in, and it poses a potential security hole as you could manually post to /../../../some-config and then really make my life miserable. So it checks if you're doing any such thing and if its determined that you're trying to crack my server, the dogs are dispatched immediately. If you need to test with something that has spaces and linebreaks just run that string through java.net.URLEncoder/encode and paste it to curl.&lt;/p&gt;
&lt;p&gt;
	If the comment comes through with the correct captcha answer and the URL isn't malformed/manipulated, then the server sends me an email (&lt;strong&gt;please change &lt;span style="color: rgb(255, 0, 0);"&gt;the recipient&lt;/span&gt; on your local installation&lt;/strong&gt;). It does so via a postfix server running on "localhost" - any smtp server will do. See &lt;strong&gt;email.clj &lt;/strong&gt;for more details.&lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;h1&gt;
	TODO&lt;/h1&gt;
&lt;p&gt;
	There's still work to be done. Name the load-times on the admin interface needs to be improved (its not hard) and the editor should be integrated in the admin interface. As it is I go to /editor and once I've completed the entire post I browse to the /admin interface (waiting once again for the stats) and publish.&lt;/p&gt;
&lt;p&gt;
	 &lt;/p&gt;
&lt;h1&gt;
	In closing&lt;/h1&gt;
&lt;p&gt;
	I'll let the code speak for itself. If you like this approach to webapplications, please feel free to use the code, you can find it here: &lt;a href="http://github.com/LauJensen/bestinclass.dk" target="_blank"&gt;Github&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;
	If you would like to get an update when I post on this website, either subscribe to the &lt;a href="http://feeds.feedburner.com/bestinclass-the-blog"&gt;RSS&lt;/a&gt; feed or follow me on &lt;a href="http://twitter.com/LauJensen"&gt;Twitter&lt;/a&gt;.&lt;/p&gt;
</content>
  </entry>

</feed>
