<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-4851261502438710182</id><updated>2011-10-23T13:25:26.718-07:00</updated><category term='Carte'/><category term='Deview'/><category term='JMX'/><category term='SICP'/><category term='Sandbar'/><category term='On Lisp'/><category term='Ring'/><category term='Clojure'/><category term='Compojure'/><category term='Macros'/><category term='Unit Testing'/><category term='Concurrency'/><category term='JConsole'/><title type='text'>Form plus Logic</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://formpluslogic.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4851261502438710182/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://formpluslogic.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Brenton Ashworth</name><uri>http://www.blogger.com/profile/13919036386288728360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_nymZllDZetA/Sl5xXNc89zI/AAAAAAAAA28/27f1wAZ9KWo/S220/me.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>26</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-4851261502438710182.post-4589054344377890515</id><published>2010-09-22T23:41:00.000-07:00</published><updated>2010-09-24T09:38:00.038-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Sandbar'/><category scheme='http://www.blogger.com/atom/ns#' term='Clojure'/><title type='text'>Adding jQuery to Sandbar Forms</title><content type='html'>The &lt;a href="http://formpluslogic.blogspot.com/2010/09/taming-html-forms-with-clojure.html"&gt;previous post&lt;/a&gt;, which introduced &lt;code&gt;sandbar.forms&lt;/code&gt;, covered the basics of creating server-side forms. This post will focus on the client and how one may easily integrate these forms with a client-side JavaScript library like &lt;a href="http://jquery.com/"&gt;jQuery&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The starting point will be a simple form for entering information about programmers. It will have text fields for the programmer's name, hire date and favorite programming language. The form will work as in the previous example; each field will be validated on the server after the form is submitted. &lt;br /&gt;&lt;br /&gt;This form will be modified to have a datepicker, an autocomplete field for the programming language and will be validated while it is being filled in. To make it even more interesting, the autocomplete field will be populated with programming languages scraped from GitHub using enlive.&lt;br /&gt;&lt;br /&gt;The &lt;a href="http://github.com/brentonashworth/sandbar-examples/blob/master/forms/src/sandbar/examples/fancy_form_before.clj"&gt;starting point&lt;/a&gt; is shown below and is available in the &lt;a href="http://github.com/brentonashworth/sandbar-examples"&gt;Sandbar Examples&lt;/a&gt; project.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(ns sandbar.examples.fancy-form-before&lt;br /&gt;  "A form which will be made fancy by the addition of jQuery."&lt;br /&gt;  (:use [ring.adapter.jetty :only [run-jetty]]&lt;br /&gt;        [ring.middleware.file :only [wrap-file]]&lt;br /&gt;        [hiccup.core :only [html]]&lt;br /&gt;        [hiccup.page-helpers :only [doctype link-to]]&lt;br /&gt;        [compojure.core :only [defroutes GET]]&lt;br /&gt;        [sandbar.core :only [icon stylesheet javascript]]&lt;br /&gt;        [sandbar.stateful-session :only [wrap-stateful-session&lt;br /&gt;                                         set-flash-value!&lt;br /&gt;                                         get-flash-value]]&lt;br /&gt;        [sandbar.validation :only [add-validation-error&lt;br /&gt;                                   build-validator&lt;br /&gt;                                   non-empty-string]])&lt;br /&gt;  (:require [compojure.route :as route]&lt;br /&gt;            [sandbar.forms :as forms]&lt;br /&gt;            [sandbar.examples.database :as db]))&lt;br /&gt;&lt;br /&gt;(defn layout&lt;br /&gt;  ([content] (layout content []))&lt;br /&gt;  ([content javascripts]&lt;br /&gt;     (html&lt;br /&gt;      (doctype :html5)&lt;br /&gt;      [:html&lt;br /&gt;       [:head&lt;br /&gt;        (stylesheet "sandbar.css")&lt;br /&gt;        (stylesheet "sandbar-forms.css")&lt;br /&gt;        (icon "icon.png")]&lt;br /&gt;       [:body&lt;br /&gt;        (if-let [m (get-flash-value :user-message)] [:div {:class "message"} m])&lt;br /&gt;        [:h2 "Sandbar Form Example"]&lt;br /&gt;        content]])))&lt;br /&gt;&lt;br /&gt;(defn home []&lt;br /&gt;  (layout&lt;br /&gt;   [:div&lt;br /&gt;    (link-to "/developer/edit" "Add Developer")&lt;br /&gt;    [:table&lt;br /&gt;     [:tr&lt;br /&gt;      [:th "Name"] [:th "Hire Date"] [:th "Favorite Language"] [:th ""]]&lt;br /&gt;     (map #(let [{:keys [id name hire-date language]} %]&lt;br /&gt;             [:tr&lt;br /&gt;              [:td name] [:td hire-date] [:td language]&lt;br /&gt;              [:td (link-to (str "/developer/edit/" id) "Edit")]])&lt;br /&gt;          (db/all-users))]]))&lt;br /&gt;&lt;br /&gt;(def properties {:name "Name"&lt;br /&gt;                 :hire-date "Hire Date"&lt;br /&gt;                 :language "Language"})&lt;br /&gt;&lt;br /&gt;(forms/defform fancy-form "/developer/edit"&lt;br /&gt;  :fields [(forms/hidden :id)&lt;br /&gt;           (forms/textfield :name)&lt;br /&gt;           (forms/textfield :hire-date {:size 10})&lt;br /&gt;           (forms/textfield :language)]&lt;br /&gt;  :load #(db/find-user %)&lt;br /&gt;  :on-cancel "/"&lt;br /&gt;  :on-success #(do&lt;br /&gt;                 (db/store-user %)&lt;br /&gt;                 (set-flash-value! :user-message "Developer has been saved.")&lt;br /&gt;                 "/")&lt;br /&gt;  :validator #(non-empty-string % :name :hire-date :language properties)&lt;br /&gt;  :properties properties)&lt;br /&gt;&lt;br /&gt;(defroutes routes&lt;br /&gt;  (fancy-form (fn [request form]&lt;br /&gt;                (layout form)))&lt;br /&gt;  (GET "/" [] (home))&lt;br /&gt;  (route/not-found "Not Found"))&lt;br /&gt;&lt;br /&gt;(def application-routes (-&amp;gt; routes&lt;br /&gt;                            wrap-stateful-session&lt;br /&gt;                            (wrap-file "public")))&lt;br /&gt;&lt;br /&gt;(defn run []&lt;br /&gt;  (run-jetty (var application-routes) {:join? false :port 8080}))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;The home page will display a table of programmers and will have links to add and edit them. The form is shown below.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_nymZllDZetA/TJuREB4uTnI/AAAAAAAAA8E/oftS0Zp2RfI/s1600/form1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_nymZllDZetA/TJuREB4uTnI/AAAAAAAAA8E/oftS0Zp2RfI/s1600/form1.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;If the form is submitted without filling in the data, the error messages shown below will be displayed.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_nymZllDZetA/TJuRnSwmMsI/AAAAAAAAA8M/HcD154f7jv8/s1600/form2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_nymZllDZetA/TJuRnSwmMsI/AAAAAAAAA8M/HcD154f7jv8/s1600/form2.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;With this, we have a pure server-side form. It will now be enhanced by the addition of JavaScript.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Add jQuery&lt;/h3&gt;&lt;br /&gt;The first step in improving this form will be to add jQuery. The requirements include jQuery itself, the UI library containing the datepicker and autocomplete, and the CSS for the theme of choice. In this example, the ui-lightness theme is used.&lt;br /&gt;&lt;br /&gt;To bring these new resources into the project, the layout function is updated to include the additional style sheet and JavaScripts.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(defn layout&lt;br /&gt;  ([content] (layout content []))&lt;br /&gt;  ([content javascripts]&lt;br /&gt;     (html&lt;br /&gt;      (doctype :html5)&lt;br /&gt;      [:html&lt;br /&gt;       [:head&lt;br /&gt;        (stylesheet "sandbar.css")&lt;br /&gt;        (stylesheet "sandbar-forms.css")&lt;br /&gt;        (stylesheet "ui-lightness/jquery-ui-1.8.4.custom.css")&lt;br /&gt;        (icon "icon.png")]&lt;br /&gt;       [:body&lt;br /&gt;        (if-let [m (get-flash-value :user-message)] [:div {:class "message"} m])&lt;br /&gt;        [:h2 "Sandbar Form Example"]&lt;br /&gt;        content&lt;br /&gt;        (map javascript&lt;br /&gt;             (concat ["jquery-1.4.2.min.js" "jquery-ui-1.8.4.custom.min.js"]&lt;br /&gt;                     javascripts))]])))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Notice that this function has been implemented to allow additional JavaScript files to be passed as arguments. The functions &lt;code&gt;stylesheet&lt;/code&gt; and &lt;code&gt;javascript&lt;/code&gt; are part of Sandbar and assume that files are located in &lt;code&gt;public/css&lt;/code&gt; and &lt;code&gt;public/js&lt;/code&gt; respectively.&lt;br /&gt;&lt;br /&gt;This form will also require some custom JavaScript which will be put into a file named &lt;code&gt;fancy-form.js&lt;/code&gt;. It should only be included on the form page so it will be passed as a parameter to the form layout as shown below.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(fancy-form (fn [request form]&lt;br /&gt;                (layout form ["fancy-form.js"])))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;h3&gt;Add a Datepicker&lt;/h3&gt;&lt;br /&gt;In order to work with the form elements from JavaScript, an id must be set for each of them. This may be done by passing a map of attributes to each field, as shown below.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;:fields [(forms/hidden :id)&lt;br /&gt;         (forms/textfield :name {:id :name})&lt;br /&gt;         (forms/textfield :hire-date {:id :hire-date :size 10})&lt;br /&gt;         (forms/textfield :language {:id :language})]&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;In this step, only the id for &lt;code&gt;:hire-date&lt;/code&gt; needs to be added; but it is just as easy to add them all.&lt;br /&gt;&lt;br /&gt;Adding a datepicker to a text field is simple with jQuery requiring only a single line of code other than the "document ready" function.&lt;br /&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/594073.js"&gt;&lt;/script&gt;&lt;br /&gt;The resulting form with activated datepicker is shown below.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_nymZllDZetA/TJuZlX7fuGI/AAAAAAAAA8U/quME7M-JY-0/s1600/form3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_nymZllDZetA/TJuZlX7fuGI/AAAAAAAAA8U/quME7M-JY-0/s1600/form3.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;h3&gt;Add Autocomplete&lt;/h3&gt;&lt;br /&gt;The next improvement will be to make the language field an autocomplete field. The list of languages that will populate the autocomplete suggestions will be scraped from the Languages page on GitHub.&lt;br /&gt;&lt;br /&gt;Enlive makes this simple, but first it will be included in the require section of the namespace form.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;[net.cgrand.enlive-html :as enlive]&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Create a function to scrape the language names, memoize it for performance and then create a function to get all names starting with a specific string.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(defn langs-from-github []&lt;br /&gt;  (let [page (-&amp;gt; "http://github.com/languages/"&lt;br /&gt;                 java.net.URL.&lt;br /&gt;                 enlive/html-resource)&lt;br /&gt;        hits (enlive/select page [:div#languages :li :a])]&lt;br /&gt;    (mapcat #(:content %) hits)))&lt;br /&gt;&lt;br /&gt;(def langs (memoize langs-from-github))&lt;br /&gt;&lt;br /&gt;(defn langs-starting-with [s]&lt;br /&gt;  (let [pattern (re-pattern (str "^" s ".*"))]&lt;br /&gt;    (filter #(re-find pattern %) (langs))))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Each jQuery UI element has many features and options. This example will be simple, providing only the relative URI which will return a JSON formatted array of languages. jQuery will add a request parameter named "term" to the request which will need to be passed to &lt;code&gt;langs-starting-with&lt;/code&gt; in order to filter the list. Since JSON is required, support for JSON will be added to the require section of the namespace form.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;[clojure.contrib.json :as json]&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;A function is required that will get the "term" from the request and then return the JSON formatted array of filtered languages.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(defn langs-autocomplete [{params :params}]&lt;br /&gt;  (let [term (get params "term")]&lt;br /&gt;    (json/json-str (map #(hash-map :value %) (langs-starting-with term)))))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Up to this point, nothing has been done which requires support form &lt;code&gt;sandbar.forms&lt;/code&gt;. In fact, no support is required to get this to work. All that is required is a route that will call the &lt;code&gt;langs-autocomplete&lt;/code&gt; function and pass it the request. As a convenience, &lt;code&gt;defform&lt;/code&gt; does provide some help here in the form of the &lt;code&gt;:ajax&lt;/code&gt; option. This option is passed a sequence of function symbols for which it will create routes.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;:ajax [langs-autocomplete]&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;This will actually create two routes: &lt;code&gt;"/developer/edit/langs-autocomplete"&lt;/code&gt; and &lt;code&gt;"/developer/langs-autocomplete"&lt;/code&gt; which will allow a single line addition to &lt;code&gt;fancy-form.js&lt;/code&gt; to enable autocomplete on both the add and edit forms.&lt;br /&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/594305.js"&gt;&lt;/script&gt;&lt;br /&gt;With these change in place, the language field will now provide suggestions as users type.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_nymZllDZetA/TJu6niwnHpI/AAAAAAAAA8c/FQOOMnSTU2s/s1600/form4.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_nymZllDZetA/TJu6niwnHpI/AAAAAAAAA8c/FQOOMnSTU2s/s1600/form4.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;h3&gt;Add Live Validation&lt;/h3&gt;&lt;br /&gt;In the original code, a validator was added to the form which will ensure that values are entered in each field and display an error message if the values are missing. The validator is shown below.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;#(non-empty-string % :name :hire-date :language properties)&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;It is always good to validate on the server, even if client-side validation is performed with JavaScript. It would not be good if the validation code had to be repeated on both the client and the server; especially when that validation code is complex. &lt;code&gt;defform&lt;/code&gt; will allow the client to use the server-side validator via AJAX. To enable this, use the &lt;code&gt;:ajax-validate-at&lt;/code&gt; option which is set to a name that will be used to create a route for accessing the validator.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;:ajax-validation-at "validate"&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;This will create two routes following the same pattern as the &lt;code&gt;:ajax&lt;/code&gt; option; allowing the client to use the relative path "validate" from both the add and edit form. &lt;br /&gt;&lt;br /&gt;The desired behavior is that any time the user moves from one field to the next, the previous field will be validated. This may be implemented as shown below in the final version of &lt;code&gt;fancy-form.js&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/594373.js"&gt;&lt;/script&gt;&lt;br /&gt;What does this do? The &lt;code&gt;validateField&lt;/code&gt; function is called to validate a specific field, passing it the field's id. The value for the field is retrieved and sent via AJAX using the relative URI with parameters "validate?y=x" for some id y and value x. This URI was configured above with &lt;code&gt;:ajax-validation-at&lt;/code&gt;. The response that comes back from this request will have two keys: &lt;code&gt;status&lt;/code&gt; and &lt;code&gt;errors&lt;/code&gt;. If the status is "fail" and there is an error for the field being validated, that error will be displayed. It could be displayed in any way, but in this example it is displayed in the previously hidden div for that field. The error div will have an id that starts with the field's id and ends with "-error". More than one field could be validated at a time by simply passing additional parameters in the validate request.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;CSS Formatting&lt;/h3&gt;&lt;br /&gt;At this point there is one annoying behavior which occurs when the name field does not pass validation. The error message causes all the fields to move down after the datepicker has been displayed. For interactive validation it would be better if the error messages did not cause the fields to move. This can be done by adding the following CSS to this project.&lt;br /&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/594362.js"&gt;&lt;/script&gt;&lt;br /&gt;With this change, the error messages will be placed next the field label and aligned to the right.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_nymZllDZetA/TJvB4NzXkwI/AAAAAAAAA8k/29RR74jB8ik/s1600/form5.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_nymZllDZetA/TJvB4NzXkwI/AAAAAAAAA8k/29RR74jB8ik/s1600/form5.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;The goal has been reached. The form now provides a datepicker, autocomplete and will be validated as the user enters data.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_nymZllDZetA/TJvC86Nu4TI/AAAAAAAAA8s/jGRwVc8jPPg/s1600/form6.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_nymZllDZetA/TJvC86Nu4TI/AAAAAAAAA8s/jGRwVc8jPPg/s1600/form6.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;h3&gt;Conclusion&lt;/h3&gt;&lt;br /&gt;&lt;code&gt;sandbar.forms&lt;/code&gt; does not favor any particular JavaScript library. The only help that it provided here was in allowing easy access through AJAX to the validator function as well as any arbitrary function. I don't plan to take this library too far beyond that or to integrate more tightly with JavaScript. There are too many options for what can be done on the client with JavaScript. When a library starts to help you here, it usually only limits what you can do.&lt;br /&gt;&lt;br /&gt;The &lt;a href="http://github.com/brentonashworth/sandbar-examples/blob/master/forms/src/sandbar/examples/fancy_form.clj"&gt;complete code&lt;/a&gt; for this example is located in the &lt;a href="http://github.com/brentonashworth/sandbar-examples"&gt;Sandbar Examples&lt;/a&gt; project.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4851261502438710182-4589054344377890515?l=formpluslogic.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://formpluslogic.blogspot.com/feeds/4589054344377890515/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://formpluslogic.blogspot.com/2010/09/sandbar-forms-with-jquery.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4851261502438710182/posts/default/4589054344377890515'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4851261502438710182/posts/default/4589054344377890515'/><link rel='alternate' type='text/html' href='http://formpluslogic.blogspot.com/2010/09/sandbar-forms-with-jquery.html' title='Adding jQuery to Sandbar Forms'/><author><name>Brenton Ashworth</name><uri>http://www.blogger.com/profile/13919036386288728360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_nymZllDZetA/Sl5xXNc89zI/AAAAAAAAA28/27f1wAZ9KWo/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_nymZllDZetA/TJuREB4uTnI/AAAAAAAAA8E/oftS0Zp2RfI/s72-c/form1.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4851261502438710182.post-9043165923807504026</id><published>2010-09-19T16:18:00.000-07:00</published><updated>2010-09-19T16:18:15.718-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Sandbar'/><category scheme='http://www.blogger.com/atom/ns#' term='Macros'/><category scheme='http://www.blogger.com/atom/ns#' term='Clojure'/><title type='text'>Taming HTML Forms with Clojure</title><content type='html'>HTML Forms may not be interesting but they are tedious. This post attempts to show you how to turn this tedious problem into an insignificant one. &lt;br /&gt;&lt;br /&gt;The main thing that I hate about creating forms is that you usually have to do five things before you have a working form. I like it when I only have to do one thing to get something working; I like to see what I am working on and then iterate.&lt;br /&gt;&lt;br /&gt;As of version 0.3.0, Sandbar provides support for forms, form layout and form validation. This post will show you how it works.&lt;br /&gt;&lt;br /&gt;Imagine that we have the following code as a starting point. All of the namespaces and functions that we will use are listed here so you don't get confused later on.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(ns sandbar.examples.user-form&lt;br /&gt;  (:use [ring.adapter.jetty :only [run-jetty]]&lt;br /&gt;        [ring.middleware.file :only [wrap-file]]&lt;br /&gt;        [compojure.core :only [defroutes GET]]&lt;br /&gt;        [sandbar.core :only [get-param]]&lt;br /&gt;        [sandbar.stateful-session :only [wrap-stateful-session&lt;br /&gt;                                         set-flash-value!]]&lt;br /&gt;        [sandbar.validation :only [build-validator&lt;br /&gt;                                   non-empty-string&lt;br /&gt;                                   add-validation-error]])&lt;br /&gt;  (:require [compojure.route :as route]&lt;br /&gt;            [sandbar.forms :as forms]&lt;br /&gt;            [sandbar.examples.database :as db]&lt;br /&gt;            [sandbar.examples.views :as views]))&lt;br /&gt;&lt;br /&gt;(defroutes routes&lt;br /&gt;  (GET "/" [] (views/home))&lt;br /&gt;  (route/not-found "Not Found"))&lt;br /&gt;&lt;br /&gt;(def application-routes (-&amp;gt; routes&lt;br /&gt;                            wrap-stateful-session&lt;br /&gt;                            (wrap-file "public")))&lt;br /&gt;&lt;br /&gt;(defn run []&lt;br /&gt;  (run-jetty (var application-routes) {:join? false :port 8080}))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;The objective of this post is to create a form which may be used to manage users for an application. The main view of said application displays a table of users and has a link to "/user/edit" which should open a form for creating a new user. For each user in the table, a link to "/user/edit/:id" should open a form where one may edit an existing user with this id. For example, "/user/edit/7" would display a form to edit the user with id = 7.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Creating a simple form&lt;/h3&gt;&lt;br /&gt;Sandbar supports an iterative approach to building forms. For the first iteration a form is defined with a hidden &lt;code&gt;:id&lt;/code&gt; field and a textfield for the &lt;code&gt;:username&lt;/code&gt;. This definition is created using the &lt;code&gt;defform&lt;/code&gt; macro. With each iteration, new options will be added to this definition.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(forms/defform user-form "/user/edit"&lt;br /&gt;  :fields [(forms/hidden :id)&lt;br /&gt;           (forms/textfield "Username" :username)])&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;code&gt;defform&lt;/code&gt; creates a route-generating function. Below, this function is used to produce the routes that are needed for the user-form.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(defroutes routes&lt;br /&gt;  (user-form (fn [request form] (views/layout form)))&lt;br /&gt;  (GET "/" [] (views/home))&lt;br /&gt;  (route/not-found "Not Found"))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;The route-generating function that is created by &lt;code&gt;defform&lt;/code&gt; takes a layout function as a parameter. Here we use our layout to layout the form page. After reloading the application, a click on the link to "/user/edit" will reveal the form shown below.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_nymZllDZetA/TJUjBy0Ax7I/AAAAAAAAA6s/jUQyQCofQzA/s1600/form1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_nymZllDZetA/TJUjBy0Ax7I/AAAAAAAAA6s/jUQyQCofQzA/s1600/form1.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;That's not bad for four lines of code. But this form doesn't really do anything. If we click on the buttons, nothing happens. To make it do something useful, &lt;code&gt;defform&lt;/code&gt; will need a little more information.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;:on-cancel "/"&lt;br /&gt;:on-success #(do&lt;br /&gt;               (db/store-user %)&lt;br /&gt;               (set-flash-value! :user-message "User has been saved.")&lt;br /&gt;               "/")&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;The current form has two buttons: Submit and Cancel. The &lt;code&gt;:on-cancel&lt;/code&gt; option takes a URL where the user will be redirected when this button is pressed. The &lt;code&gt;:on-success&lt;/code&gt; option takes a function of the form data which will return the URL to be redirected to when when this button is pressed. &lt;br /&gt;&lt;br /&gt;In the function for &lt;code&gt;:on-success&lt;/code&gt;, the data is saved and a message is stored in the Flash before returning this URL. This function will only be called after the form data has been validated. Notice that we could catch errors that may occur at a lower level and then decide where to redirect. &lt;br /&gt;&lt;br /&gt;That takes care of form submission and cancellation, but what happens when we attempt to edit a user? The form behaves as if we adding a new user. There is one more option to add to make the form fully operational.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;:load #(db/find-user %)&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;The &lt;code&gt;:load&lt;/code&gt; option takes a function of the id. Remember that the id is passed in the link to the edit form ("/user/edit/:id") and can be anything which may be used to lookup the user to edit.&lt;br /&gt;&lt;br /&gt;This simple form will now allow our users to add and edit information.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Adding more fields&lt;/h3&gt;&lt;br /&gt;The form works, but it doesn't collect all of the information that is required. It will be used to enter a password, first and last name and email address for each user as well as select the roles that each user is assigned. As a step forward, additional text fields will be added.&lt;br /&gt;&lt;br /&gt;The new list of fields is shown below...&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;[(forms/hidden :id)&lt;br /&gt; (forms/textfield "Username" :username)&lt;br /&gt; (forms/password "Password" :password)&lt;br /&gt; (forms/textfield "First Name" :first-name)&lt;br /&gt; (forms/textfield "Last Name" :last-name)&lt;br /&gt; (forms/textfield "Email" :email)]&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;...resulting in this form.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_nymZllDZetA/TJUnI0_uTCI/AAAAAAAAA60/648emppVMio/s1600/form2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_nymZllDZetA/TJUnI0_uTCI/AAAAAAAAA60/648emppVMio/s1600/form2.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;It is easy to use strings as labels as has been done above. However, it is better to keep all of this information in one place so that it may be easily changed and perhaps internationalized in the future.&lt;br /&gt;&lt;br /&gt;To extract all of the labels, create a map named 'labels'...&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(def labels&lt;br /&gt;     {:username "Username"&lt;br /&gt;      :password "Password"&lt;br /&gt;      :first-name "First Name"&lt;br /&gt;      :last-name "Last Name"&lt;br /&gt;      :email "Email Address"})&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;..and add it to the form definition using the &lt;code&gt;:properties&lt;/code&gt; option.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;:properties labels&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;The field list may now be written in a much more concise format.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;[(forms/hidden :id)&lt;br /&gt; (forms/textfield :username)&lt;br /&gt; (forms/password :password)&lt;br /&gt; (forms/textfield :first-name :last-name :email)]&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;To select roles, a more complex field in required. A &lt;code&gt;multi-checkbox&lt;/code&gt; is a set of checkboxes that allow the user to make multiple selections for a single form field. Creating these can be a lot of work, but with Sandbar it is one line of code. The following line is added to the end of the field list.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(forms/multi-checkbox :roles (db/all-roles) identity)&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Here we are creating a form element named &lt;code&gt;:roles&lt;/code&gt; using the sequence that we get back from calling &lt;code&gt;(db/all-roles)&lt;/code&gt;. The final argument is a function that will return the value that will be selected. &lt;code&gt;(db/all-roles)&lt;/code&gt; will return a set of keywords &lt;code&gt;#{:user :admin}&lt;/code&gt; so the &lt;code&gt;identity&lt;/code&gt; function is used to simply return the keyword. If the data returned from &lt;code&gt;(db/all-roles)&lt;/code&gt; were more complex, an arbitrary function could be used to generate a value from each element. The result of making the above change, and adding entries to the &lt;code&gt;labels&lt;/code&gt; map for &lt;code&gt;:roles&lt;/code&gt;, &lt;code&gt;:user&lt;/code&gt; and &lt;code&gt;:admin&lt;/code&gt;, is shown below.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_nymZllDZetA/TJUsAw4QHxI/AAAAAAAAA68/xvQPXCEp6TY/s1600/form3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_nymZllDZetA/TJUsAw4QHxI/AAAAAAAAA68/xvQPXCEp6TY/s1600/form3.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;This form doesn't just display the checkboxes, it actually works. The code required to marshal the data from the request parameters is automatically generated based on the field types and the data that is passed to each field's constructor. Sandbar also provides support for normal checkboxes, textareas, selects and multi-selects. Custom form elements may also be created.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Adding form validation&lt;/h3&gt;&lt;br /&gt;The form should have two required fields: username and password. Furthermore, the password should have at least 10 characters.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(defn password-strength [m]&lt;br /&gt;  (if (&amp;lt; (count (:password m)) 10)&lt;br /&gt;    (add-validation-error m :password "Passwords must have &amp;gt; 10 characters.")&lt;br /&gt;    m))&lt;br /&gt;&lt;br /&gt;(def user-form-validator&lt;br /&gt;     (build-validator&lt;br /&gt;      (non-empty-string :username :password labels)&lt;br /&gt;      :ensure&lt;br /&gt;      password-strength))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Two functions have been created: &lt;code&gt;password-strength&lt;/code&gt; will look at the value of the password and make sure that it has more than 10 characters, &lt;code&gt;user-form-validator&lt;/code&gt; is a compound validator. The &lt;code&gt;build-validator&lt;/code&gt; macro creates validator functions from other validator functions. The &lt;code&gt;:ensure&lt;/code&gt; keyword is used to indicate that we would like all of the previous validations to pass before attempting to do the third validation. The third validation is dependent on the other two. To learn more about form validation, see the &lt;a href="http://github.com/brentonashworth/sandbar/wiki/Form-Validation"&gt;Form Validation&lt;/a&gt; page in the &lt;a href="http://github.com/brentonashworth/sandbar/wiki"&gt;Sandbar Wiki&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;To use this validator, add it to the form definition as shown below.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;:validator user-form-validator&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;After making the above changes, the form below is produced.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_nymZllDZetA/TJUy9zsq-EI/AAAAAAAAA7E/XMalroadDB8/s1600/form4.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_nymZllDZetA/TJUy9zsq-EI/AAAAAAAAA7E/XMalroadDB8/s1600/form4.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Notice that there is an asterisk indicating which fields are required. Trying to submit an empty form will generate the following error messages.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_nymZllDZetA/TJUzl3vbFGI/AAAAAAAAA7M/60TX2_CRjRk/s1600/form5.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_nymZllDZetA/TJUzl3vbFGI/AAAAAAAAA7M/60TX2_CRjRk/s1600/form5.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Entering a username and then a password with less than 10 characters will generate this error message.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_nymZllDZetA/TJU0U4oxwwI/AAAAAAAAA7U/26RKLfFnB2g/s1600/form6.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;br /&gt;&lt;/a&gt;&lt;a href="http://2.bp.blogspot.com/_nymZllDZetA/TJaYeJjRUrI/AAAAAAAAA78/g8NrPT067CA/s1600/form1a.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_nymZllDZetA/TJaYeJjRUrI/AAAAAAAAA78/g8NrPT067CA/s1600/form1a.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;h3&gt;Layout and Style&lt;/h3&gt;&lt;br /&gt;Having all of the fields in a single column is not ideal. It would be nice if the first and last name fields were side-by-side. To accomplish this, add a layout vector to the form definition.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;:field-layout [1 1 2]&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;The meaning of this vector is that there should be one field in the first row, one in the second and two in the third. Any missing rows will have one element by default so they may be omitted here.&lt;br /&gt;&lt;br /&gt;I also like my forms to have a particular style, with a header and footer. This style is built-in and named :over-under. It may be added like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;:style :over-under&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;The form is coming along.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_nymZllDZetA/TJVFFdvaALI/AAAAAAAAA7s/yNxvzGbVQ_k/s1600/form7.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_nymZllDZetA/TJVFFdvaALI/AAAAAAAAA7s/yNxvzGbVQ_k/s1600/form7.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;It would be better for the submit button title to read "Save" and for there to a "Save and New" button so that new users may be added quickly. It would also be nice to have a better title. To make these changes add the following two options to the form definition.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;:title #(case % :add "Add New User" "Edit User")&lt;br /&gt;:buttons [[:save] [:save-and-new "Save and New"] [:cancel]]&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;The final version of the form is shown below.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_nymZllDZetA/TJVFLnqBu1I/AAAAAAAAA70/fdCQ2zy6498/s1600/form8.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_nymZllDZetA/TJVFLnqBu1I/AAAAAAAAA70/fdCQ2zy6498/s1600/form8.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;And here is the form definition with all of the changes that were made above.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(forms/defform user-form "/user/edit"&lt;br /&gt;  :fields [(forms/hidden :id)&lt;br /&gt;           (forms/textfield :username)&lt;br /&gt;           (forms/password :password)&lt;br /&gt;           (forms/textfield :first-name :last-name :email)&lt;br /&gt;           (forms/multi-checkbox :roles (db/all-roles) identity)]&lt;br /&gt;  :load #(db/find-user %)&lt;br /&gt;  :on-cancel "/"&lt;br /&gt;  :on-success #(do&lt;br /&gt;                 (db/store-user %)&lt;br /&gt;                 (set-flash-value! :user-message "User has been saved.")&lt;br /&gt;                 "/")&lt;br /&gt;  :properties labels&lt;br /&gt;  :validator user-form-validator&lt;br /&gt;  :field-layout [1 1 2]&lt;br /&gt;  :style :over-under&lt;br /&gt;  :title #(case % :add "Add New User" "Edit User")&lt;br /&gt;  :buttons [[:save] [:save-and-new "Save and New"] [:cancel]])&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;h3&gt;Extending a form&lt;/h3&gt;&lt;br /&gt;In some circumstances a form may need its behavior to change at runtime. For example, showing an additional field when the current user is an administrator. Sandbar allows us to do this by extending a form. As a quick example, the form above may be extended so that an additional field is displayed and validated only when a user is being edited.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(forms/extend-form user-form :with edit-form&lt;br /&gt;    :when (fn [action request form-data]&lt;br /&gt;            (or (= action :edit)&lt;br /&gt;                (get-param (-&amp;gt; request :params) :notes)))&lt;br /&gt;    :fields [(forms/textarea :notes {:rows 5 :cols 70})]&lt;br /&gt;    :validator #(non-empty-string % :notes labels))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;The function under the &lt;code&gt;:when&lt;/code&gt; key is a predicate which will determine when these changes should be applied to the form.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Other options&lt;/h3&gt;&lt;br /&gt;Arbitrary HTML attributes may be set on any of the form elements by passing a map of attributes as shown above when creating the &lt;code&gt;:notes&lt;/code&gt; textarea.&lt;br /&gt;&lt;br /&gt;There are two other options to &lt;code&gt;defform&lt;/code&gt; that were not covered here: &lt;code&gt;:default&lt;/code&gt; and &lt;code&gt;:marshal&lt;/code&gt;. These two options allow for setting default values for the form and wrapping the marshal function in order to gain fine control of how data is collected from the request parameters.&lt;br /&gt;&lt;br /&gt;For other and more detailed information, see the documentation in the &lt;a href="http://github.com/brentonashworth/sandbar/wiki/Forms"&gt;Sandbar Wiki&lt;/a&gt; and also take a look at the &lt;a href="http://github.com/brentonashworth/sandbar/tree/master/src/sandbar/example/forms/"&gt;example form code&lt;/a&gt;. The &lt;a href="http://github.com/brentonashworth/sandbar-examples/blob/master/forms/src/sandbar/examples/user_form.clj"&gt;complete source code&lt;/a&gt; for this example is located in the &lt;a href="http://github.com/brentonashworth/sandbar-examples"&gt;Sandbar Examples&lt;/a&gt; project.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Conclusion&lt;/h3&gt;&lt;br /&gt;This feature of Sandbar may not be what you need all of the time but when it does work for you, it can be a big help. It can be a huge timesaver when creating prototypes and for building administrator interfaces. There is a lot that can be done to make this even better. For example, it would be nice if there were more form styles available and more options for field layouts. Given some time, it will have this and much more.&lt;br /&gt;&lt;br /&gt;I think this shows the potential of Clojure as a great web programming language. It is an example of how macros may be used to encapsulate a pattern that would normally be repeated over and over.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4851261502438710182-9043165923807504026?l=formpluslogic.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://formpluslogic.blogspot.com/feeds/9043165923807504026/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://formpluslogic.blogspot.com/2010/09/taming-html-forms-with-clojure.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4851261502438710182/posts/default/9043165923807504026'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4851261502438710182/posts/default/9043165923807504026'/><link rel='alternate' type='text/html' href='http://formpluslogic.blogspot.com/2010/09/taming-html-forms-with-clojure.html' title='Taming HTML Forms with Clojure'/><author><name>Brenton Ashworth</name><uri>http://www.blogger.com/profile/13919036386288728360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_nymZllDZetA/Sl5xXNc89zI/AAAAAAAAA28/27f1wAZ9KWo/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_nymZllDZetA/TJUjBy0Ax7I/AAAAAAAAA6s/jUQyQCofQzA/s72-c/form1.png' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4851261502438710182.post-5545562259451614697</id><published>2010-08-23T06:39:00.000-07:00</published><updated>2010-08-23T08:44:54.952-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Sandbar'/><category scheme='http://www.blogger.com/atom/ns#' term='Clojure'/><title type='text'>Securing Clojure Web Applications with Sandbar - Part 2</title><content type='html'>In &lt;a href="http://formpluslogic.blogspot.com/2010/08/securing-web-applications-with-sandbar.html"&gt;part 1&lt;/a&gt; of this series, a simple authorization scheme was added to a &lt;a href="http://github.com/brentonashworth/sandbar-examples/blob/master/security/src/sandbar/examples/part_one/complete.clj"&gt;small Clojure web application&lt;/a&gt;. Continuing with this example, this post will demonstrate how features of &lt;code&gt;sandbar.auth&lt;/code&gt; may be used to add form-based authentication and channel security.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Form-based authentication and channel security&lt;/h3&gt;&lt;br /&gt;If you would like to follow along:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;$ git clone git://github.com/brentonashworth/sandbar-examples.git&lt;br /&gt;$ cd sandbar-examples/security&lt;br /&gt;$ open src/sandbar/examples/part_two/start.clj&lt;br /&gt;$ lein deps&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;This code is a bit different from what we ended with last time. A stylesheet has been added and the layout has been improved. The complete source for our starting point is shown below. Make sure you understand this code before moving on.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(ns sandbar.examples.part-two.start&lt;br /&gt;  (:use (ring.adapter jetty)&lt;br /&gt;        (ring.middleware file)&lt;br /&gt;        (compojure core)&lt;br /&gt;        (hiccup core page-helpers)&lt;br /&gt;        (sandbar core stateful-session auth)))&lt;br /&gt;&lt;br /&gt;(defn query [type]&lt;br /&gt;  (ensure-any-role-if (= type :top-secret) #{:admin}&lt;br /&gt;                      (= type :members-only) #{:member}&lt;br /&gt;                      (str (name type) " data")))&lt;br /&gt;&lt;br /&gt;(defn layout [content]&lt;br /&gt;  (html&lt;br /&gt;   (doctype :html4)&lt;br /&gt;   [:html&lt;br /&gt;    [:head&lt;br /&gt;     (stylesheet "sandbar.css")&lt;br /&gt;     (icon "icon.png")]&lt;br /&gt;    [:body&lt;br /&gt;     [:h2 "Sandbar Security Example"]&lt;br /&gt;     content&lt;br /&gt;     [:br]&lt;br /&gt;     [:div (if-let [username (current-username)]&lt;br /&gt;             [:div&lt;br /&gt;              (str "You are logged in as " username ". ")&lt;br /&gt;              (link-to "logout" "Logout")])]]]))&lt;br /&gt;&lt;br /&gt;(defn data-view [title data &amp; links]&lt;br /&gt;  [:div&lt;br /&gt;   [:h3 title]&lt;br /&gt;   [:p data]&lt;br /&gt;   (if (seq links) links [:div (link-to "home" "Home")])])&lt;br /&gt;&lt;br /&gt;(defn home-view []&lt;br /&gt;  (data-view "Home"&lt;br /&gt;             (query :public)&lt;br /&gt;             [:div (link-to "member" "Member Data")]&lt;br /&gt;             [:div (link-to "admin" "Admin Data")]&lt;br /&gt;             [:br]&lt;br /&gt;             [:div (cond (any-role-granted? :admin)&lt;br /&gt;                         "Hello administrator!"&lt;br /&gt;                         (any-role-granted? :member)&lt;br /&gt;                         "Hello member!"&lt;br /&gt;                         :else "Click on one of the links above to log in.")]))&lt;br /&gt;&lt;br /&gt;(defn member-view []&lt;br /&gt;  (data-view "Member Page"&lt;br /&gt;             (query :members-only)))&lt;br /&gt;&lt;br /&gt;(defn admin-view []&lt;br /&gt;  (data-view "Admin Page"&lt;br /&gt;             (query :top-secret)))&lt;br /&gt;&lt;br /&gt;(defn permission-denied-view []&lt;br /&gt; [:div&lt;br /&gt;  [:h3 "Permission Denied"]&lt;br /&gt;  [:div (link-to "home" "Home")]])&lt;br /&gt;&lt;br /&gt;(defroutes my-routes&lt;br /&gt;  (GET "/home*" [] (layout (home-view)))&lt;br /&gt;  (GET "/member*" [] (layout (member-view)))&lt;br /&gt;  (GET "/admin*" [] (layout (admin-view)))&lt;br /&gt;  (GET "/logout*" [] (logout! {}))&lt;br /&gt;  (GET "/permission-denied*" [] (layout (permission-denied-view)))&lt;br /&gt;  (ANY "*" [] (layout (home-view))))&lt;br /&gt;&lt;br /&gt;(defn authenticate [request]&lt;br /&gt;  (let [uri (:uri request)]&lt;br /&gt;    (cond (= uri "/member") {:name "joe" :roles #{:member}}&lt;br /&gt;          (= uri "/admin") {:name "sue" :roles #{:admin}})))&lt;br /&gt;&lt;br /&gt;(def app (-&gt; my-routes&lt;br /&gt;             (with-security authenticate)&lt;br /&gt;             wrap-stateful-session&lt;br /&gt;             (wrap-file "public")))&lt;br /&gt;&lt;br /&gt;(defn run []&lt;br /&gt;  (run-jetty (var app) {:join? false :port 8080}))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;h3&gt;Encryption&lt;/h3&gt;&lt;br /&gt;Our application must ensure that passwords are not sent across the network in plain text. In a production environment, one would enable SSL support on the web server and purchase a legitimate SSL certificate from a valid authority for use with the site's domain. For development, it is good enough to create a self-signed certificate and turn on Jetty's SSL support.&lt;br /&gt;&lt;br /&gt;Use Java's &lt;code&gt;keytool&lt;/code&gt; to create a self-signed certificate.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;$ keytool -genkey -alias sandbar -keyalg RSA -keystore my.keystore -keypass foobar&lt;br /&gt;Enter keystore password:  &lt;br /&gt;Re-enter new password: &lt;br /&gt;What is your first and last name?&lt;br /&gt;[Unknown]:  localhost&lt;br /&gt;What is the name of your organizational unit?&lt;br /&gt;[Unknown]:  dev&lt;br /&gt;What is the name of your organization?&lt;br /&gt;[Unknown]:  clojure&lt;br /&gt;What is the name of your City or Locality?&lt;br /&gt;[Unknown]:  New York     &lt;br /&gt;What is the name of your State or Province?&lt;br /&gt;[Unknown]:  New York&lt;br /&gt;What is the two-letter country code for this unit?&lt;br /&gt;[Unknown]:  US&lt;br /&gt;Is CN=localhost, OU=dev, O=clojure, L=New York, ST=New York, C=US correct?&lt;br /&gt;[no]:  y&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;For this example, the password "foobar" was entered. &lt;code&gt;keytool&lt;/code&gt; has created a keystore in the file named &lt;code&gt;my.keystore&lt;/code&gt;. Make sure this file is located in the root directory of the security module (at the same level as the public directory).&lt;br /&gt;&lt;br /&gt;To make use of this keystore, update the &lt;code&gt;run&lt;/code&gt; function so that it matches the version shown below.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(defn run []&lt;br /&gt;  (run-jetty (var app) {:join? false :ssl? true :port 8080 :ssl-port 8443&lt;br /&gt;                        :keystore "my.keystore"&lt;br /&gt;                        :key-password "foobar"}))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Setting &lt;code&gt;:join?&lt;/code&gt; to false will cause the call to &lt;code&gt;run-jetty&lt;/code&gt; to return so that the REPL may still be used.  The &lt;code&gt;:ssl-port&lt;/code&gt; defaults to 443; here we set it here to 8443. Everything else is straight forward. If you are following along, now would be a great time to start a REPL and test that everything is working as expected.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;$ lein repl&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;user=&gt; (use 'sandbar.examples.part-two.start)&lt;br /&gt;user=&gt; (run)&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Navigating to &lt;code&gt;https://localhost:8443/&lt;/code&gt; and &lt;code&gt;http://localhost:8080/&lt;/code&gt; confirms that the application may be used over SSL or standard http and that everything works the same as it did before.&lt;br /&gt;&lt;br /&gt;Note: You will get a warning message because the certificate that we are using is not legitimate. This is fine for development; do what you need to do to add an exception for this certificate. &lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Adding form-based authentication&lt;/h3&gt;&lt;br /&gt;In the last post, the &lt;code&gt;with-security&lt;/code&gt; middleware was added and configured to use our &lt;code&gt;authenticate&lt;/code&gt; function. In this section, the &lt;code&gt;authenticate&lt;/code&gt; function will be replaced with an authentication function from &lt;code&gt;sandbar.form-authentication&lt;/code&gt; and a pre-built login form will be added. &lt;br /&gt;&lt;br /&gt;Start by adding the required namespaces &lt;code&gt;sandbar.form-authentication&lt;/code&gt; and &lt;code&gt;sandbar.validation&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;Delete the &lt;code&gt;authenticate&lt;/code&gt; function and replace &lt;code&gt;authenticate&lt;/code&gt; with &lt;code&gt;form-authentication&lt;/code&gt; in our &lt;code&gt;with-security&lt;/code&gt; middleware. &lt;code&gt;form-authentication&lt;/code&gt; will redirect a user to a login form when that user is not authenticated.&lt;br /&gt;&lt;br /&gt;To implement the login form, add &lt;code&gt;form-authentication-routes&lt;/code&gt; to the list of routes.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(form-authentication-routes (fn [_ c] (layout c))&lt;br /&gt;                            (form-authentication-adapter))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;The parameters to &lt;code&gt;form-authentication-routes&lt;/code&gt; are: a layout function and something that satisfies the protocol &lt;code&gt;FormAuthAdapter&lt;/code&gt;. The layout function must take two parameters: the request and the content to layout. The &lt;code&gt;FormAuthAdapter&lt;/code&gt; protocol specifies two functions which allow us to adapt this component to our system. The functions are &lt;code&gt;load-user&lt;/code&gt; and &lt;code&gt;validate-password&lt;/code&gt;. &lt;code&gt;load-user&lt;/code&gt; takes a username and password and returns a user map. A user map must at least have the keys &lt;code&gt;:username&lt;/code&gt; and &lt;code&gt;:roles&lt;/code&gt;. &lt;code&gt;validate-password&lt;/code&gt; returns a function that can validate the user map created by &lt;code&gt;load-user&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(defrecord DemoAdapter []&lt;br /&gt;  FormAuthAdapter&lt;br /&gt;  (load-user&lt;br /&gt;   [this username password]&lt;br /&gt;   (let [login {:username username :password password}]&lt;br /&gt;     (cond (= username "member")&lt;br /&gt;           (merge login {:roles #{:member}})&lt;br /&gt;           (= username "admin")&lt;br /&gt;           (merge login {:roles #{:admin}})&lt;br /&gt;           :else login)))&lt;br /&gt;  (validate-password&lt;br /&gt;   [this]&lt;br /&gt;   (fn [m]&lt;br /&gt;     (if (= (:password m) (:username m))&lt;br /&gt;       m&lt;br /&gt;       (add-validation-error m "Username and password do not match!")))))&lt;br /&gt;&lt;br /&gt;(defn form-authentication-adapter []&lt;br /&gt;  (DemoAdapter.))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;This implementation of &lt;code&gt;load-user&lt;/code&gt; will simply look at the username to determine if the user is a member or admin. The &lt;code&gt;validate-password&lt;/code&gt; implementation will ensure that the username and password are the same. &lt;code&gt;add-validation-error&lt;/code&gt; is a function from &lt;code&gt;sandbar.validation&lt;/code&gt; which is being used here to display an error message. &lt;br /&gt;&lt;br /&gt;(For more information about validators, see the post &lt;a href="http://formpluslogic.blogspot.com/2010/04/clojure-macros-make-me-happy.html"&gt;Clojure Macros Make Me Happy&lt;/a&gt;. I will not go into any more detail here.)&lt;br /&gt;&lt;br /&gt;After making these changes, saving them and reloading the namespace, &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;user=&gt; (use :reload-all 'sandbar.examples.part-two.start)&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;we can return to our application where we should now have an operational login form. Try submitting the form while it is empty. Try entering a username and password that do not match. The form does the right thing in each situation.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Form Customization&lt;/h3&gt;&lt;br /&gt;At this point you may want to customize the field names on the form as well as the error messages that are displayed. While we are at it, let's make a custom logout landing page. Create a map with keys that correspond to the fields and errors that we would like to update as well as the key &lt;code&gt;:logout-page&lt;/code&gt; that indicates where to go after we logout.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(def properties&lt;br /&gt;     {:username "Username"&lt;br /&gt;      :password "Password"&lt;br /&gt;      :username-validation-error "Enter either admin or member"&lt;br /&gt;      :password-validation-error "Enter a password!"&lt;br /&gt;      :logout-page "/after-logout"})&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Update the &lt;code&gt;form-authentication-adapter&lt;/code&gt; constructor to merge these properties into our &lt;code&gt;DemoAdapter&lt;/code&gt;. Because Clojure's records implement the persistent map interface, the form-authentication module uses the &lt;code&gt;FormAuthAdapter&lt;/code&gt; as a map to look up field names and error messages for the login form. &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(defn basic-auth-adapter []&lt;br /&gt;  (merge (DemoAdapter.) properties))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;After making this change, we will see our own field names and error messages displayed on the login form.&lt;br /&gt;&lt;br /&gt;Next, create the logout landing page by replacing the empty map that was passed to &lt;code&gt;logout!&lt;/code&gt; with &lt;code&gt;properties&lt;/code&gt; and then creating a route&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(GET "/after-logout" [] (layout (after-logout-view)))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;and view.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(defn after-logout-view []&lt;br /&gt; [:div&lt;br /&gt;  [:h3 "Logout"]&lt;br /&gt;  [:p "You are no longer logged in!"]&lt;br /&gt;  [:div (link-to "home" "Home")]])&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;In all the changes that have been made so far, a pattern is emerging; add components in the form of middleware or parametrized routes then adapt it to our project. This same pattern will be used in the next section to add channel security.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Channel security&lt;/h3&gt;&lt;br /&gt;One thing that you may have noticed is that even though SSL is enabled, there is no way to control when it is used and when not. The goal in this application is to secure passwords sent from the client to the server and, because of the additional delay, to use SSL on as few pages as possible. This may be done by adding the &lt;code&gt;with-secure-channel&lt;/code&gt; middleware which takes four parameters: the routes to be wrapped, a security configuration, the port and the SSL port. After adding this middleware, the &lt;code&gt;app&lt;/code&gt; var definition now looks like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(def app (-&gt; my-routes&lt;br /&gt;            (with-security basic-auth)&lt;br /&gt;            wrap-stateful-session&lt;br /&gt;            (wrap-file "public")&lt;br /&gt;            (with-secure-channel security-config 8080 8443)))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;The security configuration &lt;code&gt;security-config&lt;/code&gt; is a vector of pairs. Each pair is a regular expression literal followed by a configuration. We use a vector here instead of a map because each entry is checked against the current URI in order with the first match being selected.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(def security-config&lt;br /&gt;     [#"/login.*" :ssl&lt;br /&gt;      #".*.css|.*.png" :any-channel&lt;br /&gt;      #".*" :nossl])&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Three keywords are used to represent the three kinds of channel security: &lt;code&gt;:ssl&lt;/code&gt;, &lt;code&gt;:nossl&lt;/code&gt; and &lt;code&gt;:any-channel&lt;/code&gt;. The above configuration causes the login screen to always be accessed through SSL, images and stylesheets to go over any channel and everything else to go through standard http.&lt;br /&gt;&lt;br /&gt;A future post will show how this same vector may be used to authorized access based on URI patterns.&lt;br /&gt;&lt;br /&gt;If you did not follow along, you may want to take a look at the &lt;a href="http://github.com/brentonashworth/sandbar-examples/blob/master/security/src/sandbar/examples/part_two/complete.clj"&gt;final version of the source for this exmaple&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Conclusion&lt;/h3&gt;&lt;br /&gt;Progress has been made, but this app is still not secure. Passwords should not be hard coded into an application like this. The application may be improved by having a way to easily assign different passwords to each user and store them securely. There will be at least two more posts in this series; one them will cover some of the new features of Sandbar which can help make this easy for the most common cases. The other will demonstrate how to authorize access to resources based on URI patterns.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4851261502438710182-5545562259451614697?l=formpluslogic.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://formpluslogic.blogspot.com/feeds/5545562259451614697/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://formpluslogic.blogspot.com/2010/08/securing-clojure-web-applications-with.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4851261502438710182/posts/default/5545562259451614697'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4851261502438710182/posts/default/5545562259451614697'/><link rel='alternate' type='text/html' href='http://formpluslogic.blogspot.com/2010/08/securing-clojure-web-applications-with.html' title='Securing Clojure Web Applications with Sandbar - Part 2'/><author><name>Brenton Ashworth</name><uri>http://www.blogger.com/profile/13919036386288728360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_nymZllDZetA/Sl5xXNc89zI/AAAAAAAAA28/27f1wAZ9KWo/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4851261502438710182.post-6821902643847965515</id><published>2010-08-12T21:25:00.000-07:00</published><updated>2010-08-16T09:30:55.385-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Clojure'/><title type='text'>Clojure Protocols and the Expression Problem</title><content type='html'>The official release of Clojure 1.2 is just around the corner. One of the most significant changes in this release is the addition of &lt;a href="http://clojure.org/protocols"&gt;protocols&lt;/a&gt; and &lt;a href="http://clojure.org/datatypes"&gt;datatypes&lt;/a&gt;. Below, we will explore one way that these features may be used to improve your Clojure programs. Specifically, we will look at how protocols may be used to avoid the Expression Problem.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://en.wikipedia.org/wiki/Expression_Problem"&gt;According to Wikipedia&lt;/a&gt;, the term "Expression Problem" was coined by &lt;a href="http://en.wikipedia.org/wiki/Philip_Wadler"&gt;Philip Wadler&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;“The Expression Problem is a new name for an old problem. The goal is to define a datatype by cases, where one can add new cases to the datatype and new functions over the datatype, without recompiling existing code, and while retaining static type safety (e.g., no casts).”&lt;br /&gt;&lt;br /&gt;We experience this problem when we want to add functionally to library code that is outside of our control. In the Java world, wrappers are commonly used to adapt a class to an interface. The problem with this approach is that the identity of the thing has changed and now our system has to deal with two types for the same thing. In the Ruby world, with its open classes, monkey patching may be used to add functions to a class. Let's face it, anything with the word monkey in it can’t be good. Monkey patching changes the class for everyone and can cause unforeseen problems. Both of these approaches add incidental complexity to our code which is the exact thing that we are trying to avoid by using Clojure.&lt;br /&gt;&lt;br /&gt;In this post we will go over some working code that is intended to simulate a real life situation where we may use protocols to avoid the Expression Problem. The code is located in the &lt;a href="http://github.com/brentonashworth/protocol-examples"&gt;protocol-examples&lt;/a&gt; project in the module named &lt;a href="http://github.com/brentonashworth/protocol-examples/tree/master/expression-problem/"&gt;expresssion-problem&lt;/a&gt;. If you would like to follow along:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;$ git clone git://github.com/brentonashworth/protocol-examples.git&lt;br /&gt;$ cd protocol-examples/expression-problem&lt;br /&gt;$ lein deps &amp;&amp; lein javac &amp;&amp; lein test com.corp.employee-test&lt;br /&gt;$ open src/clj/com/corp/employee.clj&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;h3&gt;Simulating an integration problem&lt;/h3&gt;&lt;br /&gt;Imagine that we are creating a system to work with employees. We have created a library, shown below, which performs various payroll and benefit calculations on employee data. As is the custom of Clojure people, employees are represented as maps so that they gain all of the benefits of being &lt;a href="http://clojure.org/datatypes"&gt;"generically manipulable"&lt;/a&gt;.&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(ns com.corp.employee)&lt;br /&gt;&lt;br /&gt;(defn- bonus [years performance]&lt;br /&gt;  (* (+ (* years 500)&lt;br /&gt;        1000)&lt;br /&gt;     (/ performance 10)))&lt;br /&gt;&lt;br /&gt;(defn- earned-vacation [years]&lt;br /&gt;  (+ 10 (* years 2)))&lt;br /&gt;&lt;br /&gt;(defn- vacation-value [rate years]&lt;br /&gt;  (* rate (* 8 (earned-vacation years))))&lt;br /&gt;&lt;br /&gt;(defn payroll [employee hours]&lt;br /&gt;  (* hours&lt;br /&gt;     (:rate employee)))&lt;br /&gt;&lt;br /&gt;(defn total-payroll&lt;br /&gt;  [coll hours-map]&lt;br /&gt;  (reduce (fn [total next]&lt;br /&gt;            (let [[{rate :rate} hours] (val next)]&lt;br /&gt;              (+ total (* rate hours))))&lt;br /&gt;          0&lt;br /&gt;          (merge-with conj (group-by :name coll) hours-map)))&lt;br /&gt;&lt;br /&gt;(defn employee-bonus [e]&lt;br /&gt;  (apply bonus ((juxt :years :perf) e)))&lt;br /&gt;&lt;br /&gt;(defn employee-vacation-value [e]&lt;br /&gt;  (apply vacation-value ((juxt :rate :years) e)))&lt;br /&gt;&lt;br /&gt;(defn total-emp-benefits [employee]&lt;br /&gt;  (+ (employee-vacation-value employee)&lt;br /&gt;     (employee-bonus employee)))&lt;br /&gt;&lt;br /&gt;(defn total-benefits [coll]&lt;br /&gt;  (reduce + (map total-emp-benefits coll)))&lt;br /&gt;&lt;br /&gt;(defn make-employee&lt;br /&gt;  [name years perf rate]&lt;br /&gt;  {:name name :years years :perf perf :rate rate})&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;h3&gt;The problem&lt;/h3&gt;&lt;br /&gt;Now imagine that we have a new requirement. The existing payroll system will need to be able to use our new library to calculate benefits. They happen to be using Clojure as well but the payroll system is written in Java and cannot be changed. Their system has a Java class named &lt;code&gt;com.company.Employee&lt;/code&gt; which contains the information that we need but does not conform to our interface. Specifically, they will need to be able to call &lt;code&gt;total-emp-benefits&lt;/code&gt; and &lt;code&gt;total-benefits&lt;/code&gt; passing instances of &lt;code&gt;com.company.Employee&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;We may start to solve this problem by creating some tests that demonstrate what we would like our system to do (if you are following along, these tests are already included in &lt;code&gt;com.corp.integration-test&lt;/code&gt;).&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(ns com.corp.integration-test&lt;br /&gt;  (use (clojure test)&lt;br /&gt;       (com.corp employee))&lt;br /&gt;  (import com.company.Employee))&lt;br /&gt;&lt;br /&gt;(def e1 (make-employee "jim" 2 8 20))&lt;br /&gt;(def e2 {:name "sue" :years 15 :perf 6 :rate 60})&lt;br /&gt;(def e3 (Employee. "james" 2 8 30M))&lt;br /&gt;(def employees [e1 e2 e3])&lt;br /&gt;&lt;br /&gt;(deftest test-employee&lt;br /&gt;  (is (= (.calculatePayroll e3 40)&lt;br /&gt;         1200M)))&lt;br /&gt;&lt;br /&gt;(deftest test-total-emp-benefits&lt;br /&gt;  (is (= (total-emp-benefits e3)&lt;br /&gt;         4960M)))&lt;br /&gt;&lt;br /&gt;(deftest test-total-benefits&lt;br /&gt;  (is (= (total-benefits employees)&lt;br /&gt;         33100M)))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;In these tests we create two employee maps and one employee using the closed &lt;code&gt;Employee&lt;/code&gt; class from the payroll system. Our first test is a sanity check; calling one of the methods that exists in &lt;code&gt;Employee&lt;/code&gt;. The other two tests pass instances of &lt;code&gt;Employee&lt;/code&gt; to functions in our system. The last two tests will not pass because our current implementation expects plain Clojure maps.&lt;br /&gt;&lt;br /&gt;Whatever our solution is, we want to ensure that we do not change the caller's contract. There is a lot of code in production that is using our library and we don't want to force our callers to have to change their code. &lt;br /&gt;&lt;br /&gt;What is our contract? We have six reporting functions that are designed to work with maps of employee data. We also have a constructor function that provides a more compact way to creating these maps. Our callers may or may not be using this constructor. The tests that we have in place are testing the caller's contract so if we can get all of the tests working without making any changes to them then we have been successful.&lt;br /&gt;&lt;br /&gt;Clojure provides two solutions to this problem: multimethods and protocols. Multimethods dispatch on a function of their arguments, protocol functions dispatch on the type of their first argument. As long as we are happy with the form of dispatch, protocols provide the additional benefits of interface organization and faster dispatch. We will choose to use protocols for our solution.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Adding a protocol&lt;/h3&gt;&lt;br /&gt;We start by defining the Benefits protocol. We choose the functions from our current system that calculate benefits and take an employee as the first argument.&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(defprotocol Benefits&lt;br /&gt; (employee-bonus [this])&lt;br /&gt; (employee-vacation-value [this]))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;Because these functions are defined in our protocol, we can no longer use them as standalone functions. We must implement them for each datatype that we would like them to support. To start with, we want to ensure that Clojure maps continue to work. We use &lt;code&gt;extend-protocol&lt;/code&gt; to implement the functions for maps using our existing implementations. If you are following along, add the following form and &lt;b&gt;remove the functions &lt;code&gt;employee-bonus&lt;/code&gt; and &lt;code&gt;employee-vacation-value&lt;/code&gt;&lt;/b&gt;.&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(extend-protocol Benefits&lt;br /&gt;  clojure.lang.IPersistentMap&lt;br /&gt;  (employee-bonus [this]&lt;br /&gt;                  (apply bonus ((juxt :years :perf) this)))&lt;br /&gt;  (employee-vacation-value [this]&lt;br /&gt;                           (apply vacation-value ((juxt :rate :years) this))))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;After making these changes our original tests should still work.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;$ lein test com.corp.employee-test&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Next, we solve the problem that we set out to solve by extending the type &lt;code&gt;com.company.Employee&lt;/code&gt; with the Benefits protocol. The final &lt;code&gt;extend-protocol&lt;/code&gt; form is shown below.&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(extend-protocol Benefits&lt;br /&gt;  &lt;br /&gt;  clojure.lang.IPersistentMap&lt;br /&gt;  (employee-bonus [this] (bonus (:years this)&lt;br /&gt;                                (:perf this)))&lt;br /&gt;  (employee-vacation-value [this] (vacation-value (:rate this)&lt;br /&gt;                                                  (:years this)))&lt;br /&gt;&lt;br /&gt;  com.company.Employee&lt;br /&gt;  (employee-bonus [this] (bonus (.getYearsWithCompany this)&lt;br /&gt;                                (.getCurrentPerformanceRating this)))&lt;br /&gt;  (employee-vacation-value [this] (vacation-value (.getHourlyRate this)&lt;br /&gt;                                                  (.getYearsWithCompany this))))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Now we may run all of our tests and... Congratulations! Everything works. From the callers perspective, we have added the functions &lt;code&gt;employee-bonus&lt;/code&gt; and &lt;code&gt;employee-vacation-value&lt;/code&gt; to the &lt;code&gt;Employee&lt;/code&gt; class. Notice that we have not globally changed this class, these functions are only available within the context of the &lt;code&gt;com.corp.employee&lt;/code&gt; namespace.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Improving performance&lt;/h3&gt;&lt;br /&gt;Because we have chosen to use protocols, we can make one final improvement to our library. We can create a record based on our protocol and then update the &lt;code&gt;make-employee&lt;/code&gt; function to create instances of this record instead of creating maps. This will increase application performance. First we create the new record.&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(defrecord StandardBenefits [name years perf rate]&lt;br /&gt;  Benefits&lt;br /&gt;  (employee-bonus [this] (bonus years perf))&lt;br /&gt;  (employee-vacation-value [this] (vacation-value rate years)))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;Next, update the &lt;code&gt;make-employee&lt;/code&gt; function to create an instance of StandardBenefits instead of a map.&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(defn make-employee [name years perf rate]&lt;br /&gt; (StandardBenefits. name years perf rate))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Run all the tests to confirm that everything works.&lt;br /&gt;&lt;br /&gt;Notice that even the functions &lt;code&gt;payroll&lt;/code&gt; and &lt;code&gt;total-payroll&lt;/code&gt; continue to work when they are passed instances of StandardBenefits even thought they are not part of our protocol and are expecting plain Clojure maps. They work because &lt;code&gt;defrecord&lt;/code&gt; provides a complete implementation of a persistent map which is the main advantage of using it over &lt;code&gt;deftype&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;If you were not following along then you may want to have a look at the &lt;a href="http://github.com/brentonashworth/protocol-examples/blob/master/expression-problem/src/clj/com/corp/finished.clj"&gt;finished version&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Conclusion&lt;/h3&gt;&lt;br /&gt;The most important thing about what we have done here is what we didn't do. We made no change to &lt;code&gt;com.company.Employee&lt;/code&gt;, we didn't change our reporting functions or even the functions &lt;code&gt;payroll&lt;/code&gt; and &lt;code&gt;total-payroll&lt;/code&gt; which depend on the persistent map abstraction, and we made no change to the caller's contract.&lt;br /&gt;&lt;br /&gt;For more information about Clojure's protocols see the &lt;a href="http://clojure.org/datatypes"&gt;datatypes&lt;/a&gt; and &lt;a href="http://clojure.org/protocols"&gt;protocols&lt;/a&gt; pages on the Clojure web site. There is also a very informative presentation, &lt;a href="http://vimeo.com/11236603"&gt;"Clojure 1.2 Protocols"&lt;/a&gt;, by Stuart Halloway.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4851261502438710182-6821902643847965515?l=formpluslogic.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://formpluslogic.blogspot.com/feeds/6821902643847965515/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://formpluslogic.blogspot.com/2010/08/clojure-protocols-and-expression.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4851261502438710182/posts/default/6821902643847965515'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4851261502438710182/posts/default/6821902643847965515'/><link rel='alternate' type='text/html' href='http://formpluslogic.blogspot.com/2010/08/clojure-protocols-and-expression.html' title='Clojure Protocols and the Expression Problem'/><author><name>Brenton Ashworth</name><uri>http://www.blogger.com/profile/13919036386288728360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_nymZllDZetA/Sl5xXNc89zI/AAAAAAAAA28/27f1wAZ9KWo/S220/me.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4851261502438710182.post-930774636183307218</id><published>2010-08-10T09:01:00.000-07:00</published><updated>2010-08-16T21:28:07.387-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Sandbar'/><category scheme='http://www.blogger.com/atom/ns#' term='Clojure'/><title type='text'>Securing Clojure Web Applications with Sandbar - Part 1</title><content type='html'>&lt;h3&gt;Authorization in the model&lt;/h3&gt;&lt;br /&gt;This is the first in a series of posts that will show how to use &lt;a href="http://github.com/brentonashworth/sandbar"&gt;Sandbar&lt;/a&gt; to secure web applications. Sandbar is a web application library which adds high level abstractions to &lt;a href="http://github.com/weavejester/compojure"&gt;Compojure&lt;/a&gt; and &lt;a href="http://github.com/mmcgrana/ring"&gt;Ring&lt;/a&gt;. The &lt;code&gt;sandbar.auth&lt;/code&gt; namespace provides code to make role-based security simple.&lt;br /&gt;&lt;br /&gt;Security can be divided into two essential parts: authentication and authorization. In this post we will only explore authorization and are therefore getting only part of the security story. In part two we will add encryption, channel security and form based authentication. In part three we will authorize based on URI patterns. Finally, in the fourth installment, we will use Sandbar to create a user administration tool.&lt;br /&gt;&lt;br /&gt;The complete code for this example is located in the &lt;a href="http://github.com/brentonashworth/sandbar-examples"&gt;sandbar-examples repository&lt;/a&gt; under &lt;a href="http://github.com/brentonashworth/sandbar-examples/tree/master/security/"&gt;security&lt;/a&gt;. If you would like to follow along then clone that repository, &lt;a href="http://github.com/technomancy/leiningen"&gt;get the dependencies&lt;/a&gt;, &lt;a href="http://github.com/technomancy/leiningen"&gt;start a REPL&lt;/a&gt; and open the &lt;code&gt;sandbar.examples.part-one.start&lt;/code&gt; namespace &lt;a href="http://www.assembla.com/wiki/show/clojure/Getting_Started"&gt;in your favorite editor&lt;/a&gt;.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;$ git clone git://github.com/brentonashworth/sandbar-examples.git&lt;br /&gt;$ cd sandbar-examples/security&lt;br /&gt;$ open src/sandbar/examples/part_one/start.clj&lt;br /&gt;$ lein deps&lt;br /&gt;$ lein repl&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;user=&amp;gt; (use ‘sandbar.examples.part-one.start)&lt;br /&gt;user=&amp;gt; (run)&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;We will start with a small Compojure application and, throughout this series, add features to it. The complete source for our starting point is shown below.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(ns sandbar.examples.part-one.start&lt;br /&gt; (:use (ring.adapter jetty)&lt;br /&gt;       (compojure core)&lt;br /&gt;       (hiccup core page-helpers)))&lt;br /&gt;&lt;br /&gt;(defn query [type]&lt;br /&gt; (str (name type) " data"))&lt;br /&gt;&lt;br /&gt;(defn layout [content]&lt;br /&gt; (html&lt;br /&gt;  [:html&lt;br /&gt;    [:body&lt;br /&gt;    [:h2 "Sandbar Authorization Example"]&lt;br /&gt;    content]]))&lt;br /&gt;&lt;br /&gt;(defn data-view [title data &amp;amp; links]&lt;br /&gt; [:div&lt;br /&gt;  [:h3 title]&lt;br /&gt;  [:p data]&lt;br /&gt;  (if (seq links) links [:div (link-to "home" "Home")])])&lt;br /&gt;&lt;br /&gt;(defn home-view []&lt;br /&gt; (data-view "Home"&lt;br /&gt;            (query :public)&lt;br /&gt;            [:div (link-to "member" "Member Data")]&lt;br /&gt;            [:div (link-to "admin" "Admin Data")]))&lt;br /&gt;&lt;br /&gt;(defn member-view []&lt;br /&gt; (data-view "Member Page"&lt;br /&gt;            (query :members-only)))&lt;br /&gt;&lt;br /&gt;(defn admin-view []&lt;br /&gt; (data-view "Admin Page"&lt;br /&gt;            (query :top-secret)))&lt;br /&gt;&lt;br /&gt;(defroutes my-routes&lt;br /&gt; (GET "/home*" [] (layout (home-view)))&lt;br /&gt; (GET "/member*" [] (layout (member-view)))&lt;br /&gt; (GET "/admin*" [] (layout (admin-view)))&lt;br /&gt; (ANY "*" [] (layout (home-view))))&lt;br /&gt;&lt;br /&gt;(def app my-routes)&lt;br /&gt;&lt;br /&gt;(defn run []&lt;br /&gt; (run-jetty (var app) {:join? false :port 8080}))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;(The &lt;code&gt;app&lt;/code&gt; var is not required here but having it allows us to load this code once and then make all of the changes below without having to restart our REPL.)&lt;br /&gt;&lt;br /&gt;This is a complete application which will show three views: the home page will show public data, the member page will show members-only data and the admin page will show top-secret data. The query function retrieves the data that is displayed.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Add sandbar.auth, middleware and create an authentication function&lt;/h3&gt;&lt;br /&gt;We would like to have two roles: administrators and members. Only administrators may see top-secret data and only members may see members-only data. We would also like our application to have different behavior based on a user's role.&lt;br /&gt;&lt;br /&gt;Before we may add any of Sandbar's functionality, we need to first add Sandbar to our namespace declaration.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(:use (ring.adapter jetty)&lt;br /&gt;       (compojure core)&lt;br /&gt;       (hiccup core page-helpers)&lt;br /&gt;       (sandbar stateful-session auth))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Here we have added the &lt;code&gt;sandbar.stateful-session&lt;/code&gt; and &lt;code&gt;sandbar.auth&lt;/code&gt; namespaces.&lt;br /&gt;&lt;br /&gt;Next, we add some middleware.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(def app&lt;br /&gt;    (-&amp;gt; my-routes&lt;br /&gt;        (with-security authenticate)&lt;br /&gt;        wrap-stateful-session))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Our routes have been wrapped with the &lt;code&gt;with-security&lt;/code&gt; and &lt;code&gt;wrap-stateful-session&lt;/code&gt; middleware. &lt;code&gt;with-security&lt;/code&gt; does all of the hard work. Here it has one argument, an authentication function, which we have not written. The &lt;code&gt;wrap-stateful-session&lt;/code&gt; middleware is used by &lt;code&gt;with-security&lt;/code&gt; to store user information. &lt;br /&gt;&lt;br /&gt;&lt;code&gt;authenticate&lt;/code&gt; is where you would do whatever you need to do to figure out who the current user is based on the information in the request. This function is very simple, it takes the request map as an argument and returns a single user map or nil. The user map has two keys: &lt;code&gt;:name&lt;/code&gt;, which is a string, and &lt;code&gt;:roles&lt;/code&gt;, which is a set of role keywords. For this example, we will use the function below.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(defn authenticate [request]&lt;br /&gt; (let [uri (:uri request)]&lt;br /&gt;   (cond (= uri "/member") {:name "joe" :roles #{:member}}&lt;br /&gt;         (= uri "/admin") {:name "sue" :roles #{:admin}})))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;This function will not secure our application but it does demonstrate how simple it is to add your own authentication scheme. For our example, we simply authenticate the user based on the first URI that is accessed. This function will only be called if the current user is not authenticated.&lt;br /&gt;&lt;br /&gt;After making these changes we should still have a working application. Reload the namespace in the REPL and try it out.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;user=&amp;gt; (use :reload-all ‘sandbar.examples.part-one.start)&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;There is a lot of new code running, but the functionality has not changed. At least we know we haven't broken anything.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Protecting data in the model&lt;/h3&gt;&lt;br /&gt;All of our data is still out in the open. To protect it, we could use the &lt;code&gt;ensure-any-role&lt;/code&gt; macro. It takes two arguments: a set of roles and a form that is being protected. The protected form will only be executed if the user is authenticated and has one of the roles in the set.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(defn query [type]&lt;br /&gt; (ensure-any-role #{:member :admin}&lt;br /&gt;                  (str (name type) " data")))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;This isn't really what we are looking for. A simple visit to the home page will result in a &lt;code&gt;java.lang.StackOverflowError&lt;/code&gt;. Understanding why will help us understand what is going on behind the scenes. &lt;code&gt;ensure-any-role&lt;/code&gt; will throw an exception when the current user is not authenticated. The &lt;code&gt;with-security&lt;/code&gt; middleware will catch the exception and then call &lt;code&gt;authenticate&lt;/code&gt; to authenticate this user. Our authentication function will not authenticate the user becuase it only authenticates visitors to the admin and member pages. Finally, &lt;code&gt;with-security&lt;/code&gt; will redirect the user to the home page and the cycle continues.&lt;br /&gt;&lt;br /&gt;This is probably a bug which needs fixing, but it does indicate that we have a problem. There is no way for an unauthenticated user to view the public data on the home page. We could start using conditionals but that will get ugly. Instead, there is a better macro to use in this situation named &lt;code&gt;ensure-any-role-if&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(defn query [type]&lt;br /&gt; (ensure-any-role-if (= type :top-secret) #{:admin}&lt;br /&gt;                     (= type :members-only) #{:member}&lt;br /&gt;                     (str (name type) " data")))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;This macro takes an odd number of arguments. The final argument is the form that you are protecting. The other arguments are pairs of predicates and sets of roles. If the predicate is true then the user must be a member of one of the roles in the corresponding set. If none of the predicates are true then the protected code will be run without authentication.&lt;br /&gt;&lt;br /&gt;We can safely try it now. If you first click on the "Member Page" link you will see the members-only data. If you then try to click on the "Admin Page" link, nothing will happen. Our data has been protected.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Logout and permission denied&lt;/h3&gt;&lt;br /&gt;When &lt;code&gt;ensure-any-role&lt;/code&gt; or &lt;code&gt;ensure-any-role-if&lt;/code&gt; notice that the current user is authenticated but does not have the correct role, it will redirect the user to "/permission-denied". It would be nice if we could see a better permission denied page. Add the following route and implementation of the &lt;code&gt;permission-denied-view&lt;/code&gt; function.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(GET "/permission-denied*" [] (layout (permission-denied-view)))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(defn permission-denied-view []&lt;br /&gt; [:div&lt;br /&gt;  [:h3 "Permission Denied"]&lt;br /&gt;  [:div (link-to "home" "Home")]])&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;We may also want to logout so that we can easily try out the different roles. &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(GET "/logout*" [] (logout! {}))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;The logout route will use a function named &lt;code&gt;logout!&lt;/code&gt; from &lt;code&gt;sandbar.auth&lt;/code&gt; to clear the current user from the session. The parameter to &lt;code&gt;logout!&lt;/code&gt; is a map which may contain the key &lt;code&gt;:logout-page&lt;/code&gt;. If this key is not found then the user will be redirected to “/” after logout.&lt;br /&gt;&lt;br /&gt;The user will need some kind of link to allow them to logout easily. Add the following div to the end of the body section of the layout.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;[:div (if-let [username (current-username)]&lt;br /&gt;        [:div&lt;br /&gt;          (str "You are logged in as " username ". ")&lt;br /&gt;          (link-to "logout" "Logout")])]&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;The &lt;code&gt;current-username&lt;/code&gt; function is another function from &lt;code&gt;sandbar-auth&lt;/code&gt;. It will get the current user's username from the session or return &lt;code&gt;nil&lt;/code&gt; if one does not exist. After reloading in the REPL, we now see the username at the bottom of the page, we may logout and we have a proper permissions denied page.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Checking the role&lt;/h3&gt;&lt;br /&gt;As a final flourish for this example we will add the following div to our layout underneath the content and above the logout code that we added above.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;[:div (cond (any-role-granted? :admin)&lt;br /&gt;            "Hello administrator!"&lt;br /&gt;            (any-role-granted? :member)&lt;br /&gt;            "Hello member!"&lt;br /&gt;            :else "Click on one of the links above to log in.")]&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;This shows how to use the &lt;code&gt;any-role-granted?&lt;/code&gt; predicate. Here we show a different message based on the role of the current user. &lt;code&gt;any-role-granted?&lt;/code&gt; may be passed a single role or a set of roles. It will return true if the user is a member of one of those roles.&lt;br /&gt;&lt;br /&gt;The complete source code for the new authorized version is located in the namespace &lt;code&gt;sandbar.examples.part-one.complete&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Conclusion&lt;/h3&gt;&lt;br /&gt;We haven’t actually secured anything in this example. But hopefully you can see how that would be done by creating a different implementation of &lt;code&gt;authenticate&lt;/code&gt;. In the next installment, we will look at one way to do this and add form based authentication to this example project as well as encryption and channel security.&lt;br /&gt;&lt;br /&gt;For more information on Sandbar, see the &lt;a href="http://wiki.github.com/brentonashworth/sandbar/"&gt;wiki&lt;/a&gt; and check out the source code. The source for &lt;code&gt;sandbar.auth&lt;/code&gt; is only 245 lines. Sandbar is still quite new and needs a lot of work. I hope this series will draw more attention to it and help to make it better.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4851261502438710182-930774636183307218?l=formpluslogic.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://formpluslogic.blogspot.com/feeds/930774636183307218/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://formpluslogic.blogspot.com/2010/08/securing-web-applications-with-sandbar.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4851261502438710182/posts/default/930774636183307218'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4851261502438710182/posts/default/930774636183307218'/><link rel='alternate' type='text/html' href='http://formpluslogic.blogspot.com/2010/08/securing-web-applications-with-sandbar.html' title='Securing Clojure Web Applications with Sandbar - Part 1'/><author><name>Brenton Ashworth</name><uri>http://www.blogger.com/profile/13919036386288728360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_nymZllDZetA/Sl5xXNc89zI/AAAAAAAAA28/27f1wAZ9KWo/S220/me.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4851261502438710182.post-5301825410534604651</id><published>2010-07-16T08:09:00.000-07:00</published><updated>2010-07-16T09:26:51.602-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Unit Testing'/><category scheme='http://www.blogger.com/atom/ns#' term='Clojure'/><category scheme='http://www.blogger.com/atom/ns#' term='Deview'/><title type='text'>Better Clojure Test Results on the Command Line</title><content type='html'>After letting folks know about &lt;a href="http://github.com/brentonashworth/deview"&gt;Deview&lt;/a&gt; earlier this week, some people thought that a command line tool that improved test results would be a better fit for them. Deview has some features that you can't have in a command line tool, and more are planned for the future. However, I can see the value in having a simple tool that does one thing well. Even though I plan to use and continue to improve Deview, I took a day off and created lein-difftest.  &lt;br /&gt;&lt;br /&gt;&lt;a href="http://github.com/brentonashworth/lein-difftest"&gt;lein-difftest&lt;/a&gt; is a completely new project that does not depend on Deview. It depends on many of the same libraries as Deview but is much simpler. It may be used as a Leiningen plugin or from the REPL.&lt;br /&gt;&lt;br /&gt;To use it from Leiningen you simply add &lt;code&gt;lein-difftest&lt;/code&gt; as a dev-dependency. See &lt;a href="http://github.com/brentonashworth/lein-difftest"&gt;lein-difftest&lt;/a&gt; for more information. Once you have this new library in place, run &lt;code&gt;lein test&lt;/code&gt; and you will see the new and improved results. The example below shows two test runs. One without lein-difftest and the other with.&lt;br /&gt;&lt;br /&gt;&lt;img border="0" src="https://s3.amazonaws.com/formpluslogic-public/images/lein-difftest/lein-difftest.png" /&gt;&lt;br /&gt;&lt;br /&gt;To use it from the REPL there is a helper function named &lt;code&gt;test-ns&lt;/code&gt; with takes care of reloading the target namespace and turning off color.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;user&amp;gt; (use 'difftest.core)&lt;br /&gt;user&amp;gt; (test-ns 'some.test.namespace)&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;h3&gt;Robert Hooke&lt;/h3&gt;&lt;br /&gt;This project is also a great example of using Robert Hooke to extend Leiningen. Before using Hooke, I had to copy the entire leiningen.test/test function into my plugin code so that I could modify one of its function calls. With Hooke, I simple intercept the call to said function and ensure that it has the correct arguments.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4851261502438710182-5301825410534604651?l=formpluslogic.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://formpluslogic.blogspot.com/feeds/5301825410534604651/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://formpluslogic.blogspot.com/2010/07/better-clojure-test-results-on-command.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4851261502438710182/posts/default/5301825410534604651'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4851261502438710182/posts/default/5301825410534604651'/><link rel='alternate' type='text/html' href='http://formpluslogic.blogspot.com/2010/07/better-clojure-test-results-on-command.html' title='Better Clojure Test Results on the Command Line'/><author><name>Brenton Ashworth</name><uri>http://www.blogger.com/profile/13919036386288728360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_nymZllDZetA/Sl5xXNc89zI/AAAAAAAAA28/27f1wAZ9KWo/S220/me.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4851261502438710182.post-8284718563428320409</id><published>2010-07-13T12:16:00.000-07:00</published><updated>2010-07-13T12:16:39.257-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Unit Testing'/><category scheme='http://www.blogger.com/atom/ns#' term='Clojure'/><category scheme='http://www.blogger.com/atom/ns#' term='Deview'/><title type='text'>Better Clojure Test Results with Deview</title><content type='html'>Over the past couple of months I have been doing a lot of Clojure development. During this time there were two things that have stood out as workflow killers.&lt;br /&gt;&lt;br /&gt;The first is caused by a great feature of Clojure. Because Clojure has a solid notion of equality, you may easily test arbitrarily large Clojure data structures for equality. The problem comes when they are not equal and you need to find out what is different. Like many of you, I use clojure.test. When a test fails, the actual and expected forms are printed. Finding the difference in two large forms can be a nightmare. To feel this pain, try to find the difference in the forms below.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;actual: (not (= {:remote-addr "0:0:0:0:0:0:0:1%0", :scheme :http, :query-params {}, :session {:sandbar.stateful-session/session {:project {:host "localhost", :name "deview/deview-server", :port 9000, :_id 1, :_v 1, :_type :projects}}}, :form-params {}, :request-method :get, :query-string nil, :route-params {"*" "/deview/deview-server"}, :content-type nil, :cookies {"ring-session" {:value "0bcoa4e4-a852-4976-b2e9-a697a48f1ed6"}}, :server-name "localhost", :params {"*" "/deview/deview-server"}} {:remote-addr "0:0:0:0:0:0:0:1%0", :scheme :http, :query-params {}, :session {:sandbar.stateful-session/session {:project {:host "localhost", :name "deview/deview-server", :port 9000, :_id 1, :_v 1, :_type :projects}}}, :form-params {}, :request-method :get, :query-string nil, :route-params {"*" "/deview/deview-server"}, :content-type nil, :cookies {"ring-session" {:value "0bcca4e4-a852-4976-b2e9-a697a48f1ed6"}}, :uri "/stats/deview/deview-server", :server-name "localhost", :params {"*" "/deview/deview-server"}}))&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;On several occasions I spent so much time looking for differences that I forgot what I was doing before encountering the problem.&lt;br /&gt;&lt;br /&gt;Another related issue is encountered when an exception is thrown during compile time or while running a test. Usually several screens of stacktrace are output; I usually only need to see the first line. It takes up a lot of time to switch focus to the terminal window and then scroll up to find that one line that I care about. If I have encountered exceptions on the last few test runs then I also have to be careful not to scroll too far and view the results from a previous test.&lt;br /&gt;&lt;br /&gt;These two tasks take up much more than just time. It is frustrating when you are working to solve one problem and in the process need to stop and solve a different problem. Some call this yak shaving. They also have something in common; for both of them, I am trying to manually find something that the computer should be able to find for me. &lt;br /&gt;&lt;br /&gt;I decided to solve this problem before moving forward on any of my current projects.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Building Blocks&lt;/h3&gt;&lt;br /&gt;Smart people have already been working on these problems. &lt;br /&gt;&lt;br /&gt;At the June Bay Area Clojure Meetup, George Jahad presented a small library he had created to solve the first problem. The library is named &lt;a href="http://github.com/GeorgeJahad/difform"&gt;difform&lt;/a&gt;. It has two useful functions &lt;code&gt;difform&lt;/code&gt; and &lt;code&gt;sort-form&lt;/code&gt;: when &lt;code&gt;difform&lt;/code&gt; is passed two forms it will display the diff, &lt;code&gt;sort-form&lt;/code&gt; will sort a Clojure form so that it can be diffed. This is good but I want to see that diff in my test results without having to copy and paste. When a test fails, I want to immediately see what the problem is without interrupting my train of thought.&lt;br /&gt;&lt;br /&gt;Mark McGranaghan’s &lt;a href="http://github.com/mmcgrana/clj-stacktrace"&gt;clj-stacktrace&lt;/a&gt; makes stacktraces much better. Using the stacktrace middleware provided with Ring is a big timesaver when working on Ring web applications. It would be great if I could use this on my test result stacktraces for all my projects.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Deview&lt;/h3&gt;&lt;br /&gt;&lt;a href="http://github.com/brentonashworth/deview"&gt;Deview&lt;/a&gt; is what I came up with. It makes use of the above two libraries as well as some great features of clojure.test which make it easy to capture reporting information while tests are running.&lt;br /&gt;&lt;br /&gt;Deview runs yours tests and reports test failures and successes. If an exception is thrown, clj-stacktrace is used to clean up the stacktrace. Deview will then filter it down to show relevant (according to me) trace elements. For example:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;a href="https://s3.amazonaws.com/formpluslogic-public/images/deview/test_stacktrace.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="https://s3.amazonaws.com/formpluslogic-public/images/deview/test_stacktrace.png" /&gt;&lt;/a&gt;&lt;/div&gt;When a test fails, the difference between the expected and actual results are displayed. The diff below shows the changes in the two forms at the beginning of this post.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;a href="https://s3.amazonaws.com/formpluslogic-public/images/deview/deview.png" imageanchor="2" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="598" src="https://s3.amazonaws.com/formpluslogic-public/images/deview/deview.png" width="498" /&gt;&lt;/a&gt;&lt;/div&gt;I have been using this for a couple of weeks and have found it to be a huge time saver.&lt;br /&gt;&lt;br /&gt;For complete instructions on installing and using deview, see the project &lt;a href="http://github.com/brentonashworth/deview"&gt;README&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Deview needs to be able to run your tests, so it has to run with your project’s classpath which contains all of your project’s dependencies. Current features of deview as well as some that are planned for the future, require deview to have quite a few dependencies of its own. In order to mitigate dependency conflicts, I decided on a client/server architecture where the server is small with few dependencies and the client can have any number of dependencies.&lt;br /&gt;&lt;br /&gt;Deview also stores information about your projects. All of this information is stored with the client so as not to corrupt your project directory.&lt;br /&gt;&lt;br /&gt;The server is the part that you add to your project. It only depends on Clojure and clj-stacktrace. The server will run in its own process with your project’s classpath. It will run your tests, read your project.clj file and read source files. It will not in any way modify anything in your project.&lt;br /&gt;&lt;br /&gt;The client is a Compojure web application. It can be cloned from GitHub and run from the REPL.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Features&lt;/h3&gt;&lt;br /&gt;The current focus is on testing. Once you are up and running you will be able to see a list of all of your test namespaces. You may choose to run tests for an individual namespace or for all of them.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;a href="https://s3.amazonaws.com/formpluslogic-public/images/deview/test_screen.png" imageanchor="3" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="https://s3.amazonaws.com/formpluslogic-public/images/deview/test_screen.png" /&gt;&lt;/a&gt;&lt;/div&gt;While tests are running, your view will be updated once per second showing the current running namespace and test.&lt;br /&gt;&lt;a href="https://s3.amazonaws.com/formpluslogic-public/images/deview/test_running.png" imageanchor="4" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="https://s3.amazonaws.com/formpluslogic-public/images/deview/test_running.png" /&gt;&lt;/a&gt;&lt;br /&gt;If exceptions or failures occur, you will see a short stack trace or a diff as shown in a previous section.&lt;br /&gt;&lt;br /&gt;If you choose to run all tests and experience failures in one namespace you may easily click on that namespace to re-run its tests.&lt;br /&gt;&lt;br /&gt;To re-run the last set of tests you simply refresh the page. This allows you to easily re-run tests with a couple of keystrokes (Command-TAB, Command-R on a mac).&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;The Future&lt;/h3&gt;&lt;br /&gt;There are many ways that deview can be improved in the future. Some of them are listed here.&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Set up a time interval so that tests are automatically run every now and again&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Group tests&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Run groups in parallel&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Add some useful metrics other than lines of code&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Browse and search sources&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Add links to source in test error messages&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Create test configurations where bindings can be applied, for example: set a flag to not run the tests that hit the database&lt;br /&gt;&lt;/li&gt;&lt;li&gt;When tests are running automatically; when a test fails in a namespace, only run the tests for that namespace until the issue is fixed then go back to running all tests.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Find all usages of a function in one or more projects&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Interface with a good code coverage tool once one emerges&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;I have more ideas than I have time. If you find deview useful and would like to help make it better then I would love the help. For more information about deview see the project &lt;a href="http://github.com/brentonashworth/deview"&gt;README&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4851261502438710182-8284718563428320409?l=formpluslogic.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://formpluslogic.blogspot.com/feeds/8284718563428320409/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://formpluslogic.blogspot.com/2010/07/better-clojure-test-results-with-deview.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4851261502438710182/posts/default/8284718563428320409'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4851261502438710182/posts/default/8284718563428320409'/><link rel='alternate' type='text/html' href='http://formpluslogic.blogspot.com/2010/07/better-clojure-test-results-with-deview.html' title='Better Clojure Test Results with Deview'/><author><name>Brenton Ashworth</name><uri>http://www.blogger.com/profile/13919036386288728360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_nymZllDZetA/Sl5xXNc89zI/AAAAAAAAA28/27f1wAZ9KWo/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4851261502438710182.post-2732700033154261970</id><published>2010-06-14T09:19:00.000-07:00</published><updated>2010-06-14T09:19:34.106-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Clojure'/><category scheme='http://www.blogger.com/atom/ns#' term='Carte'/><title type='text'>Relational Mapping for Clojure</title><content type='html'>In a recent project, I found myself writing a lot of code to manage associations in a relational database. Much of the code was not specific to that particular project so it was moved into its own project. &lt;a href="http://github.com/brentonashworth/carte"&gt;Carte&lt;/a&gt; was born.&lt;br /&gt;&lt;br /&gt;Carte is an attempt to bring simple relational mapping to Clojure. It is also an attempt to do relational mapping in a way that complements Clojure.&lt;br /&gt;&lt;br /&gt;Carte maps tables and associations in a database to nested immutable data structures in Clojure. Query results are nested data structures which, after being modified, may be saved with a single API call.&lt;br /&gt;&lt;br /&gt;Imagine that we have the following database structure:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://s3.amazonaws.com/formpluslogic-public/images/carte/sample-schema.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="260" src="https://s3.amazonaws.com/formpluslogic-public/images/carte/sample-schema.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Using Carte's &lt;code&gt;model&lt;/code&gt; macro, we can describe this with the following expression.&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(model&lt;br /&gt;  (genre [:id :name])&lt;br /&gt;  (track [:id :name]&lt;br /&gt;         (belongs-to :album))&lt;br /&gt;  (album [:id :title]&lt;br /&gt;         (many-to-many :artist)&lt;br /&gt;         (many-to-one :genre))&lt;br /&gt;  (artist [:id :name]))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;For the examples below &lt;code&gt;db&lt;/code&gt; is a map which contains the database configuration and the model created above.&lt;br /&gt;&lt;br /&gt;Carte provides a &lt;code&gt;fetch&lt;/code&gt; function to pull data from the database.&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;user&amp;gt; (fetch db :album :with :artists)&lt;br /&gt;[{:artists&lt;br /&gt;   [{:name "Patrick Carney", :id 24} {:name "Dan Auerbach", :id 26}],&lt;br /&gt;  :title "Magic Potion",&lt;br /&gt;  :id 16}&lt;br /&gt; {:artists&lt;br /&gt;   [{:name "Jack White", :id 22}&lt;br /&gt;    {:name "Patrick Keeler", :id 23}&lt;br /&gt;    {:name "Brenden Benson", :id 25}&lt;br /&gt;    {:name "Jack Lawrence", :id 28}],&lt;br /&gt;  :title "Broken Boy Soldiers",&lt;br /&gt;  :id 17}&lt;br /&gt; {:artists [{:name "Jack White", :id 22} {:name "Meg White", :id 27}],&lt;br /&gt;  :title "Elephant",&lt;br /&gt;  :id 18}&lt;br /&gt; {:artists [], :title "White Blood Cells", :id 19}&lt;br /&gt; {:artists&lt;br /&gt;   [{:name "Patrick Carney", :id 24} {:name "Dan Auerbach", :id 26}],&lt;br /&gt;  :title "Thickfreakness",&lt;br /&gt;  :id 20}]&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;More complex queries may be performed. All of the queries below retrieve data in a single query using multiple left joins.&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(fetch db :album :with :artists :tracks :genre)&lt;br /&gt;(fetch db :album :with [:artist {:name "Jack*"}] :tracks)&lt;br /&gt;(fetch db :artist :order-by :name :with [:album :with [:track {:name "Call*"}]])&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;The &lt;code&gt;query&lt;/code&gt; function may be used to create pre-compiled queries and to compose queries. This makes it very easy to create template queries that may be modified and used at a later time.&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;user&amp;gt; (def &amp;amp; (partial query db))&lt;br /&gt;user&amp;gt; (def album-query (&amp;amp; :album :with :artists :tracks :genre))&lt;br /&gt;user&amp;gt; (def ordered-artist-query (&amp;amp; album-query (&amp;amp; :artist :order-by :name)))&lt;br /&gt;user&amp;gt; (fetch db (&amp;amp; ordered-artist-query (&amp;amp; :genre {:name "Rock"})))&lt;br /&gt;[{:id 118,&lt;br /&gt;  :title "Broken Boy Soldiers",&lt;br /&gt;  :artists&lt;br /&gt;  [{:id 158, :name "Brenden Benson"}&lt;br /&gt;   {:id 161, :name "Jack Lawrence"}&lt;br /&gt;   {:id 155, :name "Jack White"}&lt;br /&gt;   {:id 156, :name "Patrick Keeler"}],&lt;br /&gt;  :tracks&lt;br /&gt;  [{:id 272, :name "Hands"}&lt;br /&gt;   {:id 273, :name "Level"}&lt;br /&gt;   {:id 274, :name "Steady As She Goes"}&lt;br /&gt;   {:id 275, :name "Call It a Day"}&lt;br /&gt;   {:id 276, :name "Together"}],&lt;br /&gt;  :genre {:name "Rock", :id 45}}&lt;br /&gt; {:id 119,&lt;br /&gt;  :title "Elephant",&lt;br /&gt;  :artists&lt;br /&gt;  [{:id 155, :name "Jack White"} {:id 160, :name "Meg White"}],&lt;br /&gt;  :tracks&lt;br /&gt;  [{:id 269, :name "Seven Nation Army"}&lt;br /&gt;   {:id 270, :name "Black Math"}&lt;br /&gt;   {:id 271, :name "Girl, You Have No Faith In Medicine"}],&lt;br /&gt;  :genre {:name "Rock", :id 45}}]&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;When a fetch is performed, each map in the data structure has associated metadata to indicate the table that it came from and the original values in the map.  This allows Carte to figure out which records need to be updated or deleted. For example, the following sequence of expressions will remove all artists from an album. This will cause records in the album_artist table to be deleted.&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(def r (-&amp;gt; (fetch-one db :album {:title "Magic Potion"} :with :artists)&lt;br /&gt;           (assoc :artists [])))&lt;br /&gt;(save-or-update db r)&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;If we were to delete the album, all associated tracks would also be deleted.&lt;br /&gt;&lt;br /&gt;This is just a little taste of what Carte can do. This post is an abridged version of the &lt;a href="http://github.com/brentonashworth/carte"&gt;README for Carte on GitHub&lt;/a&gt;. For more detailed information, please see that document. If you have MySQL installed, you should be able to easily follow along with the examples.&lt;br /&gt;&lt;br /&gt;In the future, I will add support for Derby, PostgreSQL and SQL Server.&lt;br /&gt;&lt;br /&gt;If you do take the time to look closely at Carte, please let me know what you think. I would love some constructive criticism.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4851261502438710182-2732700033154261970?l=formpluslogic.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://formpluslogic.blogspot.com/feeds/2732700033154261970/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://formpluslogic.blogspot.com/2010/06/relational-mapping-for-clojure.html#comment-form' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4851261502438710182/posts/default/2732700033154261970'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4851261502438710182/posts/default/2732700033154261970'/><link rel='alternate' type='text/html' href='http://formpluslogic.blogspot.com/2010/06/relational-mapping-for-clojure.html' title='Relational Mapping for Clojure'/><author><name>Brenton Ashworth</name><uri>http://www.blogger.com/profile/13919036386288728360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_nymZllDZetA/Sl5xXNc89zI/AAAAAAAAA28/27f1wAZ9KWo/S220/me.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4851261502438710182.post-9068975838595686791</id><published>2010-05-03T15:45:00.000-07:00</published><updated>2010-05-03T15:45:39.235-07:00</updated><title type='text'>Binding Saves the Hour</title><content type='html'>Clojure's &lt;code&gt;binding&lt;/code&gt; form is one part of Clojure that I just didn't get at first. The description in the API docs is clear, but reading it with my background was like telling a blind man that something is red. Since I had never had a feature like this available in a language, I had no experience with how one might actually use it.&lt;br /&gt;&lt;br /&gt;If you look at some of my &lt;a href="http://formpluslogic.blogspot.com/2009/09/clojure-unit-testing-part-2.html"&gt;earlier blog posts about unit testing&lt;/a&gt; you will see that at that time I was still in the dark about &lt;code&gt;binding&lt;/code&gt;. I was struggling to find a way to mock services and was creating functions with &lt;code&gt;def&lt;/code&gt; calls, a big Clojure no-no.&lt;br /&gt;&lt;br /&gt;I have since changed my ways and now use &lt;code&gt;binding&lt;/code&gt; as it should be used when testing to create environments with alternative implementations of functions.&lt;br /&gt;&lt;br /&gt;This post is not about that. It is about how &lt;code&gt;binding&lt;/code&gt; saved me some yak shaving one day last week.&lt;br /&gt;&lt;br /&gt;I started a new web project last week, and was excited to build something new on top of my &lt;a href="http://github.com/brentonashworth/sandbar"&gt;sandbar&lt;/a&gt; library. The project needed to have a secure area where administrators could edit content on the site. This means that I will need to have a way to edit users, passwords, roles etc. The development module of sandbar has some code that creates a user interface for doing just this. It also has some code for creating the tables that I will need to back it in MySQL. If all goes well, I should be able to save myself many hours of work.&lt;br /&gt;&lt;br /&gt;During the previous week, I completed getting a stable version of the library into Clojars. I added sandbar to my dependencies and ran &lt;code&gt;lein deps&lt;/code&gt;. The first step was to create the tables that I needed in MySQL. Here is the function that does that:&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(defn create-tables&lt;br /&gt;  ([] (create-tables nil))&lt;br /&gt;  ([drop]&lt;br /&gt;     (let [db (get-connection)&lt;br /&gt;           drop-fn (partial database/db-drop-table db)&lt;br /&gt;           insert-fn (partial database/db-insert db)&lt;br /&gt;           create-table-fn (partial database/db-do-commands db)] &lt;br /&gt;       (do&lt;br /&gt;         (if drop&lt;br /&gt;           (do (drop-fn :user_role)&lt;br /&gt;               (drop-fn :role)&lt;br /&gt;               (drop-fn :app_user)))&lt;br /&gt;         (create-user-table create-table-fn)&lt;br /&gt;         (create-role-table create-table-fn)&lt;br /&gt;         (create-role-user-table create-table-fn)&lt;br /&gt;         (insert-role-records insert-fn)&lt;br /&gt;         (insert-user-records insert-fn)&lt;br /&gt;         (assoc-users-with-roles insert-fn)))))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;There is a lot of stuff here but the part that curbed my enthusiasm was &lt;code&gt;(get-connection)&lt;/code&gt;. I had hard-coded the database configuration. That's why this code is in the development module, I thought. I started to think about all the ways I could get around this problem. Copy the code into my project and make the changes, fix the problem in the library and re-deploy, etc.&lt;br /&gt;&lt;br /&gt;But then I remembered &lt;code&gt;binding&lt;/code&gt;. &lt;code&gt;get-connection&lt;/code&gt; is a function that returns a map with a database configuration. All I need to do is use &lt;code&gt;binding&lt;/code&gt; to create a new binding for the var &lt;code&gt;get-connection&lt;/code&gt; to a function that returns the correct configuration.&lt;br /&gt;&lt;br /&gt;So I fired up the REPL and...&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(binding [get-connection &lt;br /&gt;            (fn [] {:connection&lt;br /&gt;                     {:classname "com.mysql.jdbc.Driver"&lt;br /&gt;                      :subprotocol "mysql"&lt;br /&gt;                      :subname "//localhost/the_db"&lt;br /&gt;                      :user "the_user"&lt;br /&gt;                      :password "123456789"}})]&lt;br /&gt; (create-tables))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;Nice job Clojure!&lt;br /&gt;&lt;br /&gt;This would have been easy for me to fix because I am in control of both projects. But what if you wanted to use this function right now in your project? I haven't yet fixed the problem. &lt;code&gt;binding&lt;/code&gt; provides the workaround.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;binding&lt;/code&gt; could definitely be used to win a 'most unreadable code ever' contest. It is a powerful feature and can be abused. Part of the difficulty in learning to use &lt;code&gt;binding&lt;/code&gt; properly is knowing when not to use it. But I'm glad it's there. In my opinion, it is one more reason to love (or at least like) Clojure.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4851261502438710182-9068975838595686791?l=formpluslogic.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://formpluslogic.blogspot.com/feeds/9068975838595686791/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://formpluslogic.blogspot.com/2010/05/binding-saves-hour.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4851261502438710182/posts/default/9068975838595686791'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4851261502438710182/posts/default/9068975838595686791'/><link rel='alternate' type='text/html' href='http://formpluslogic.blogspot.com/2010/05/binding-saves-hour.html' title='Binding Saves the Hour'/><author><name>Brenton Ashworth</name><uri>http://www.blogger.com/profile/13919036386288728360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_nymZllDZetA/Sl5xXNc89zI/AAAAAAAAA28/27f1wAZ9KWo/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4851261502438710182.post-7464319443300598341</id><published>2010-04-15T08:52:00.000-07:00</published><updated>2011-05-23T18:00:30.509-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Sandbar'/><category scheme='http://www.blogger.com/atom/ns#' term='Macros'/><category scheme='http://www.blogger.com/atom/ns#' term='Clojure'/><title type='text'>Clojure Macros Make Me Happy</title><content type='html'>Demonstrating the power of macros with an example.&lt;br /&gt;&lt;br /&gt;I have been working a bit on validation recently. The goal is to come up with a sane way of organizing validation code, composing validations and reporting errors. This is another one of those solved problems that I am trying to find a better Clojure solution for. While doing this I had a chance to write a couple of Clojure macros that made me happy. This is the story of one of those macros.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Validator theory&lt;/h3&gt;&lt;br /&gt;The design is simple. A validator is a function of a map which is being validated. The function returns the map unaltered if it passes validation. If there are errors, error messages will be put in the map under a special key. This allows validators to be easily composed.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Validation helpers&lt;/h3&gt;&lt;br /&gt;The only difference between a validator and validation helper is that a validation helper may have more arguments than just the map to be validated.&lt;br /&gt;&lt;br /&gt;For example, a validation helper which will ensure that a value is a non-empty string would have a signature like this.&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(defn non-empty-string [m &amp;amp; k] ...)&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;/pre&gt;I can turn this into a validator by wrapping it in a function of a map.&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(defn validate-my-key [m]&lt;br /&gt;  (non-empty-string m :my-key))&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;/pre&gt;&lt;h3&gt;Compound validators&lt;/h3&gt;&lt;br /&gt;Most data are complex and will need to have multiple fields validated or multiple validations performed on the same field. Below is an example of creating a validator for a user login form. As a first step, we create a validator function which will ensure that a user has actually entered a username and password. The &lt;code&gt;non-empty-string&lt;/code&gt; function will look up the error message that it needs to display in the properties map.&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(defn login-validator [properties]&lt;br /&gt;  (fn [m]&lt;br /&gt;    (non-empty-string m :username :password properties)))&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;/pre&gt;There is one more thing that we would need to check before we allow this user to login. We need to ensure that the password that was entered is actually correct. For this we create a &lt;code&gt;password-validator&lt;/code&gt; function which is not shown here. We cannot simply add this validation. There is some logic here. It depends on the previous validation passing. We don't need to bother checking the password if the user did not enter one. This leads of a solution like the one shown below.&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(defn login-validator [properties]&lt;br /&gt; (fn [m]&lt;br /&gt;   (let [v (non-empty-string m :username :password properties)]&lt;br /&gt;     (if (= m v)&lt;br /&gt;       (password-validator m)&lt;br /&gt;       v))))&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;/pre&gt;This works, but it is messy. We store the map returned from the first validation and then compare it with the original map. If they are the same then we continue and check the password. If they are different then we know that the previous validation did not pass and we just return the map. What if we had further validations that depended on all three of these validations passing?&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(defn login-validator [properties]&lt;br /&gt; (fn [m]&lt;br /&gt;   (let [v (non-empty-string m :username :password properties)]&lt;br /&gt;     (if (= m v)&lt;br /&gt;       (let [x (password-validator m)]&lt;br /&gt;         (if (= m x)&lt;br /&gt;           (-&amp;gt; m&lt;br /&gt;               final-validation-1&lt;br /&gt;               final-validation-2)&lt;br /&gt;           x))&lt;br /&gt;       v))))&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;/pre&gt;This is starting to get nasty.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Macros to the rescue&lt;/h3&gt;&lt;br /&gt;In many other languages we would be stuck with the above "pattern" of combining validators. Or we would need to create some kind of validation DSL with varying degrees of ease. Since Clojure is a Lisp we may easily create a new control structure.&lt;br /&gt;&lt;br /&gt;The &lt;code&gt;build-validator&lt;/code&gt; macro allows us to write the above complex validator in the following way.&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(defn login-validator [properies]&lt;br /&gt;  (build-validator (non-empty-string :username :password properties)&lt;br /&gt;                   :ensure&lt;br /&gt;                   password-validator&lt;br /&gt;                   :ensure&lt;br /&gt;                   final-validation-1&lt;br /&gt;                   final-validation-2))&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;/pre&gt;It has the same semantics as the threading macro (&lt;code&gt;-&amp;gt;&lt;/code&gt;) in the Clojure. It is a significant reduction in lines of code and a huge improvement in clarity. Simply list each validation helper and insert an &lt;code&gt;:ensure&lt;/code&gt; keyword at any point where you must ensure that the previous validations have passed before continuing. The function that is produced will take a map as an argument and return the map with any error messages for failing validations.&lt;br /&gt;&lt;br /&gt;The actual macro implementation is not shown here, only its effect. If  you would like to see it you may go to &lt;a href="http://github.com/brentonashworth/sandbar/blob/master/src/sandbar/validation.clj"&gt;validation.clj&lt;/a&gt;  and check it out.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Conclusion&lt;/h3&gt;&lt;br /&gt;This example shows just one of many great features of Clojure. As amazing as this is, it is not even close to being the best feature of the language. Spend some time with Clojure, it may seem strange, it may frustrate you at first, but in the end it will make you happy to.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4851261502438710182-7464319443300598341?l=formpluslogic.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://formpluslogic.blogspot.com/feeds/7464319443300598341/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://formpluslogic.blogspot.com/2010/04/clojure-macros-make-me-happy.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4851261502438710182/posts/default/7464319443300598341'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4851261502438710182/posts/default/7464319443300598341'/><link rel='alternate' type='text/html' href='http://formpluslogic.blogspot.com/2010/04/clojure-macros-make-me-happy.html' title='Clojure Macros Make Me Happy'/><author><name>Brenton Ashworth</name><uri>http://www.blogger.com/profile/13919036386288728360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_nymZllDZetA/Sl5xXNc89zI/AAAAAAAAA28/27f1wAZ9KWo/S220/me.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4851261502438710182.post-8941849310631237505</id><published>2010-04-07T13:23:00.000-07:00</published><updated>2010-04-15T10:22:26.530-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Sandbar'/><category scheme='http://www.blogger.com/atom/ns#' term='Compojure'/><category scheme='http://www.blogger.com/atom/ns#' term='Ring'/><category scheme='http://www.blogger.com/atom/ns#' term='Clojure'/><title type='text'>Sandbar 0.2.1 is Released</title><content type='html'>&lt;h3&gt;The problem&lt;/h3&gt;&lt;br /&gt;There are a lot of great web frameworks out there: Ruby on Rails, Django, Spring MVC etc. Using these frameworks can make one very productive. They are mature, have huge communities, and offer great value.&lt;br /&gt;&lt;br /&gt;Why then am I so cold toward them? With all of these benefits, shouldn't I be happy with all of the work I'm getting done?&lt;br /&gt;&lt;br /&gt;Imagine that you are an artist and you want to create a work of art. What if I handed you a canvas that had all of the lines already drawn and you just had to pick the colors and paint within the lines. It would still take some skill to be able to pick the correct colors and apply them in the right proportions. Artists with different levels of skill would still end up with vastly different results. You would finish faster since you don't have to go through all of the trouble of thinking of a subject for your painting. But much of the joy would be removed because so many decisions have already been made for you.&lt;br /&gt;&lt;br /&gt;This is how I feel when using a framework. In order to be more productive, I sell out and spend my time learning how someone else thinks web applications should be made instead of thinking about how they should be made.&lt;br /&gt;&lt;br /&gt;To further see my point, let's take this to the extreme. What if I created a framework where all you had to do to create an application is start up a program and fill in some blanks? It would ask you a bunch of questions, you would answer them and then it would spit out a working application. This would be great for productivity. I would start looking for something else to work on.&lt;br /&gt;&lt;br /&gt;I am not criticizing those who use them or even saying that I'll avoid them unreasonably. I am just explaining how I feel when using them.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;The solution&lt;/h3&gt;&lt;br /&gt;I want libraries, not frameworks. A library does something for you. It doesn't tell you how to work. It says "Use me if you want, replace me if you find something better." When you start a new project you start with an empty directory.&lt;br /&gt;&lt;br /&gt;Enter Clojure, Ring and Compojure. Clojure is an amazing language. One of only two that I care about right now, the other being Erlang. Ring and Compojure are LIBRARIES to help you build web applications. When you start a new web application using these libraries you start with an empty directory. If you try this, please take a moment and enjoy looking at your blank canvas.&lt;br /&gt;&lt;br /&gt;When I write an application using Ring and Compojure I don't feel like I am being told how to work. I feel like I can be creative again.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;What is Sandbar?&lt;/h3&gt;&lt;br /&gt;So now that I am excited once again about web development using a non-framework, I have started working on a project named Sandbar. It is a set of libraries for web applications built with &lt;a href="http://github.com/mmcgrana/ring"&gt;Ring&lt;/a&gt; and/or &lt;a href="http://github.com/weavejester/compojure"&gt;Compojure&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The first release contains code to make it easier to work with session data for projects that do a lot of that. It also contains some code to help with authentication and authorization. These are humble beginnings and I hope to add many more features.&lt;br /&gt;&lt;br /&gt;The project also includes sample code which shows how to use each feature in the library. It also includes a working reference application that uses all of the features.&lt;br /&gt;&lt;br /&gt;If you would like to know more about this project, please see the project on &lt;a href="http://github.com/brentonashworth/sandbar"&gt;GitHub&lt;/a&gt; and take a look at the &lt;a href="http://wiki.github.com/brentonashworth/sandbar/"&gt;Sandbar Wiki&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;If you would like to start using it, you can either fork it from &lt;a href="http://github.com/brentonashworth/sandbar"&gt;GitHub&lt;/a&gt; and build it yourself or get the 0.2.1 release from &lt;a href="http://clojars.org/sandbar"&gt;Clojars&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Final note&lt;/h3&gt;&lt;br /&gt;I am releasing this early because I want to get feedback from others. My motivation for releasing now came from this blog post by Bradford Cross:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://measuringmeasures.blogspot.com/2010/01/you-release-late-and-infrequently.html"&gt;http://measuringmeasures.blogspot.com/2010/01/you-release-late-and-infrequently.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I especially like this part:&lt;br /&gt;&lt;br /&gt;"So what's the right attitude? Humility. It doesn't matter how smart and successful and qualified you are, you simply don't know what you're doing. The good news is that nobody else does either, though some are foolish enough to think that they do (and that's why you can beat them)."&lt;br /&gt;&lt;br /&gt;It is still early days for software development. We don't yet know the right way to do things. Let's keep exploring and being creative.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4851261502438710182-8941849310631237505?l=formpluslogic.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://formpluslogic.blogspot.com/feeds/8941849310631237505/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://formpluslogic.blogspot.com/2010/04/sandbar-021-is-released.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4851261502438710182/posts/default/8941849310631237505'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4851261502438710182/posts/default/8941849310631237505'/><link rel='alternate' type='text/html' href='http://formpluslogic.blogspot.com/2010/04/sandbar-021-is-released.html' title='Sandbar 0.2.1 is Released'/><author><name>Brenton Ashworth</name><uri>http://www.blogger.com/profile/13919036386288728360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_nymZllDZetA/Sl5xXNc89zI/AAAAAAAAA28/27f1wAZ9KWo/S220/me.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4851261502438710182.post-4449650691367062573</id><published>2010-04-01T11:58:00.000-07:00</published><updated>2010-04-07T13:04:09.814-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Compojure'/><category scheme='http://www.blogger.com/atom/ns#' term='Ring'/><category scheme='http://www.blogger.com/atom/ns#' term='Clojure'/><title type='text'>Migrating from Compojure 0.3.2 to 0.4.0 and Ring 0.2.0</title><content type='html'>I recently migrated a non-trivial application from Compojure 0.3.2 to 0.4.0 and Ring 0.2.0. These are some of my notes. This is not an authoritative migration guide or even a complete one. The list is in no particular order. Please also note that 0.4.0 has not been released yet. Some of this may change. Keep your eye on the &lt;a href="http://groups.google.com/group/compojure/browse_thread/thread/4da66a70254671a3"&gt;Compojure Google Group&lt;/a&gt; and the &lt;a href="http://wiki.github.com/weavejester/compojure/"&gt;Compojure Wiki&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Please correct me if any of this information is incorrect. I am trying to help people here, not lead them astray.&lt;br /&gt;&lt;br /&gt;There isn't much left of Compojure. Just under 170 lines of code. Everything else has either been moved to Hiccup, Clout and Ring or has been dropped in favor of Ring.&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;My new list of Leiningen dependencies for Compojure looks like this:&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;  [compojure "0.4.0-SNAPSHOT"]&lt;br /&gt;  [hiccup "0.2.1"]&lt;br /&gt;  [ring/ring-devel "0.2.0-RC2"]&lt;br /&gt;  [ring/ring-httpcore-adapter "0.2.0-RC2"]&lt;br /&gt;  [ring/ring-jetty-adapter "0.2.0-RC2"]&lt;br /&gt;  [ring/ring-servlet "0.2.0-RC2"]&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;/pre&gt;Check for the latest versions as I think that Ring 0.2.0 has been released.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;redirect-to&lt;/code&gt; is now just &lt;code&gt;redirect&lt;/code&gt; and located in &lt;code&gt;ring.util.response&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;compojure.core&lt;/code&gt; now contains all the route goodness from Compojure 0.3.2. i.e. &lt;code&gt;routes, defroutes, GET, POST etc.&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;Ring does not create a session key until you actually put something in the session. This will cause problems if you are only using the key but not actually storing things.&lt;/li&gt;&lt;li&gt;Ring uses strings for parameter names instead of keywords.&lt;/li&gt;&lt;li&gt;When defining Compojure routes, you no longer get &lt;code&gt;request&lt;/code&gt;, &lt;code&gt;params&lt;/code&gt; etc. for free. You need to put a binding form after the route string.&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(GET “*” (handler request)) -&gt; (GET “*” request (handler request))&lt;br /&gt;(GET “*” (handler params)) -&gt; (GET “*” {params :params} (handler params))&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;/pre&gt;The binding form is applied to the request so you can pull out whatever you need.&lt;/li&gt;&lt;li&gt;&lt;code&gt;capitalize&lt;/code&gt; is gone. You can use the one in the new Clojure string library &lt;code&gt;clojure.contrib.str-utils2&lt;/code&gt; or &lt;code&gt;clojure.contrib.string&lt;/code&gt; depending on which version of Clojure you are using. The latter is in the most recent version of Clojure Contrib.&lt;/li&gt;&lt;li&gt;&lt;code&gt;compojure.control.decorate&lt;/code&gt; is gone. Use ring style:&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(def app&lt;br /&gt;   (-&gt; my-routes&lt;br /&gt;        with-session&lt;br /&gt;        (wrap-file “public”)&lt;br /&gt;        wrap-file-info)&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;/pre&gt;UPDATE: &lt;a href="http://github.com/weavejester/compojure/blob/master/src/compojure/core.clj"&gt;Compojure now includes a wrap! macro&lt;/a&gt;.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Use the Ring jetty adapter to run your app.&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;(run-jetty (var app) {:ssl? true :port 8080 :ssl-port 8443&lt;br /&gt;                      :keystore "my.keystore"&lt;br /&gt;                      :key-password "foobar"})&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Note the &lt;code&gt;(var app)&lt;/code&gt; which will allow interactive development.&lt;br /&gt;&lt;br /&gt;I haven’t figured out how to run the app with a context path or how to create a servlet. I am assuming both are possible and not too difficult.&lt;/li&gt;&lt;li&gt;&lt;code&gt;serve-file&lt;/code&gt; is gone. &lt;br /&gt;&lt;br /&gt;Where you once had a route like this&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(GET "/public/*" (or (serve-file (params :*)) :next))&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;/pre&gt;you can remove it and add &lt;code&gt;wrap-file&lt;/code&gt; as shown in the example above.&lt;/li&gt;&lt;li&gt;The HTML stuff from Compojure is now in Hiccup. All of the functions have the same names so you just swap this in and everything works. Depending on what you need, you will have to use &lt;code&gt;hiccup.core&lt;/code&gt;, &lt;code&gt;hiccup.page_helpers&lt;/code&gt; or &lt;code&gt;hiccup.form_helpers&lt;/code&gt;. These correspond to the similarly named files in 0.3.2&lt;/li&gt;&lt;li&gt;If you use &lt;code&gt;(wrap-file “public”)&lt;/code&gt;, you do not have to include the string &lt;code&gt;“public”&lt;/code&gt; in the path i.e. &lt;code&gt;(link-to “/css/my.css”)&lt;/code&gt; will work.&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;If you are still reading and would like more help then you can check out the application &lt;a href="http://github.com/brentonashworth/sandbar/blob/master/src/sandbar/example/ideadb/app.clj"&gt;here&lt;/a&gt;. This blog post refers to the 0.1.0 tag for this repository.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4851261502438710182-4449650691367062573?l=formpluslogic.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://formpluslogic.blogspot.com/feeds/4449650691367062573/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://formpluslogic.blogspot.com/2010/04/migrating-from-compojure-032-to-040-and_01.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4851261502438710182/posts/default/4449650691367062573'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4851261502438710182/posts/default/4449650691367062573'/><link rel='alternate' type='text/html' href='http://formpluslogic.blogspot.com/2010/04/migrating-from-compojure-032-to-040-and_01.html' title='Migrating from Compojure 0.3.2 to 0.4.0 and Ring 0.2.0'/><author><name>Brenton Ashworth</name><uri>http://www.blogger.com/profile/13919036386288728360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_nymZllDZetA/Sl5xXNc89zI/AAAAAAAAA28/27f1wAZ9KWo/S220/me.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4851261502438710182.post-1618273096603093265</id><published>2009-12-14T15:55:00.000-08:00</published><updated>2010-04-07T13:03:22.815-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Clojure'/><title type='text'>Contribute to Clojure</title><content type='html'>Would you like to contribute to Clojure? You can. &lt;a href="http://clojure.org/funding"&gt;Donate&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4851261502438710182-1618273096603093265?l=formpluslogic.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://formpluslogic.blogspot.com/feeds/1618273096603093265/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://formpluslogic.blogspot.com/2009/12/contribute-to-clojure.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4851261502438710182/posts/default/1618273096603093265'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4851261502438710182/posts/default/1618273096603093265'/><link rel='alternate' type='text/html' href='http://formpluslogic.blogspot.com/2009/12/contribute-to-clojure.html' title='Contribute to Clojure'/><author><name>Brenton Ashworth</name><uri>http://www.blogger.com/profile/13919036386288728360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_nymZllDZetA/Sl5xXNc89zI/AAAAAAAAA28/27f1wAZ9KWo/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4851261502438710182.post-8322425066526368922</id><published>2009-12-14T13:59:00.000-08:00</published><updated>2009-12-14T14:49:33.211-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JConsole'/><category scheme='http://www.blogger.com/atom/ns#' term='JMX'/><category scheme='http://www.blogger.com/atom/ns#' term='Clojure'/><title type='text'>The Clojure REPL, JMX and JConsole</title><content type='html'>In &lt;a href="http://formpluslogic.blogspot.com/2009/12/clojure-and-jmx.html"&gt;my last post&lt;/a&gt; I pointed out how you can use jconsole (Java Monitoring &amp; Management Console) to watch the JVM while your Clojure program (or any Java program) is running. I needed this last week to solve a memory problem.&lt;br /&gt;&lt;br /&gt;An even better use of jconsole is to fire it up while you are developing. Just add the &lt;code&gt;-Dcom.sun.management.jmxremote&lt;/code&gt; option to the Java command that you use to start the REPL and then run jconsole. The REPL is interactive. Having the REPL and jconsole at the same time is interactive^2. Imagine, you write some code, then you go to the REPL to give it a try and as soon as you execute it you can see how much memory you are using, how many threads are running, how much CPU is being used, the number of classes that have been loaded, the type of memory that is being used, and much more. You can even force a garbage collection just in case you don't believe that you are using all of that memory. Just to wet your appitiite, here is an example.&lt;br /&gt;&lt;br /&gt;&lt;big&gt;Example&lt;/big&gt;&lt;br /&gt;&lt;br /&gt;Today I was writing some code that &lt;a href="http://www.bestinclass.dk/index.php/2009/12/clojure-vs-ruby-scala-transient-newsgroups/comment-page-1/#comment-1217"&gt;extracted word counts from newsgroup text files&lt;/a&gt;. I had the code working but wanted to improve the performance. Below are three of the four windows that you see on the Overview page of jconsole.&lt;br /&gt;&lt;br /&gt;In the example below, you can see the memory usage as I ran a function four different times in the REPL.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_nymZllDZetA/Sya9SsOAv8I/AAAAAAAAA4o/V06XWFRphqQ/s1600-h/wordcounts-memory.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 223px;" src="http://3.bp.blogspot.com/_nymZllDZetA/Sya9SsOAv8I/AAAAAAAAA4o/V06XWFRphqQ/s400/wordcounts-memory.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5415223730764824514" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Here you can see number of threads that are being used for each run. The second two runs used pmap instead of map, therefore, more threads.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_nymZllDZetA/Sya9rgonsgI/AAAAAAAAA4w/TU_AioIQ4mo/s1600-h/wordcounts-threads.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 221px;" src="http://2.bp.blogspot.com/_nymZllDZetA/Sya9rgonsgI/AAAAAAAAA4w/TU_AioIQ4mo/s400/wordcounts-threads.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5415224157151932930" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Here is the CPU usage for each run. Notice that in the second two runs, more of the CPU is being used and execution takes less time.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_nymZllDZetA/Sya-BdhM2rI/AAAAAAAAA44/_wbdR6zgdz0/s1600-h/wordcounts-cpu.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 220px;" src="http://2.bp.blogspot.com/_nymZllDZetA/Sya-BdhM2rI/AAAAAAAAA44/_wbdR6zgdz0/s400/wordcounts-cpu.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5415224534272629426" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Each of these runs lasted a while. Normally I would be sitting there waiting to see the result. Now I have something to do.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4851261502438710182-8322425066526368922?l=formpluslogic.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://formpluslogic.blogspot.com/feeds/8322425066526368922/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://formpluslogic.blogspot.com/2009/12/clojure-repl-jmx-and-jconsole.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4851261502438710182/posts/default/8322425066526368922'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4851261502438710182/posts/default/8322425066526368922'/><link rel='alternate' type='text/html' href='http://formpluslogic.blogspot.com/2009/12/clojure-repl-jmx-and-jconsole.html' title='The Clojure REPL, JMX and JConsole'/><author><name>Brenton Ashworth</name><uri>http://www.blogger.com/profile/13919036386288728360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_nymZllDZetA/Sl5xXNc89zI/AAAAAAAAA28/27f1wAZ9KWo/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_nymZllDZetA/Sya9SsOAv8I/AAAAAAAAA4o/V06XWFRphqQ/s72-c/wordcounts-memory.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4851261502438710182.post-4690517778291731309</id><published>2009-12-11T12:47:00.000-08:00</published><updated>2009-12-14T14:49:33.211-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JConsole'/><category scheme='http://www.blogger.com/atom/ns#' term='JMX'/><category scheme='http://www.blogger.com/atom/ns#' term='Clojure'/><title type='text'>Clojure and JMX</title><content type='html'>There are some folks out there that are using Clojure and only know what they have to about Java. This post is for you.&lt;br /&gt;&lt;br /&gt;Last night I was working on a little fun Clojure project that involved reading very large files. While reading and processing a 700MB file, my application crashed complaining that it had run out of memory. I had given it 500MB of RAM. What else does it need? Have you ever been in this situation where you are having Java memory issues and need to know exactly what’s going on? When this happens, your best friend is JMX and &lt;code&gt;jconsole&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;jconsole&lt;/code&gt; comes with the JDK so you already have it. To use these two together, you first need to start Clojure with the Java option &lt;code&gt;-Dcom.sun.management.jmxremote&lt;/code&gt;. Once the app is running you can run &lt;code&gt;jconsole&lt;/code&gt; which can be found in the &lt;code&gt;bin&lt;/code&gt; directory of the JDK. This will open a window which will allow you to select the Java process to monitor. Once you select a process, you will see something like this:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_nymZllDZetA/SyKwRr8VNtI/AAAAAAAAA4g/QFmUPDWtfEU/s1600-h/jconsole.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 334px;" src="http://4.bp.blogspot.com/_nymZllDZetA/SyKwRr8VNtI/AAAAAAAAA4g/QFmUPDWtfEU/s400/jconsole.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5414083519952795346" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This allows you to see the internals of the JVM as it is running. Armed with this information you should be able to figure out what is going on. After that, I'm sure you will go back to being mad at Java.&lt;br /&gt;&lt;br /&gt;This is easy but I needed to make it a little easier. I updated my &lt;a href="http://gist.github.com/247899"&gt;&lt;code&gt;clj&lt;/code&gt;&lt;/a&gt; script to add the option above to Java when I pass it the &lt;code&gt;-Xjmx&lt;/code&gt; option.&lt;br /&gt;&lt;br /&gt;You can do a lot more with JMX and Clojure. If you wish to get into it in more detail, check out the &lt;a href="http://richhickey.github.com/clojure-contrib/jmx-api.html"&gt;jmx&lt;/a&gt; library in &lt;a href="http://richhickey.github.com/clojure-contrib/index.html"&gt;clojure.contrib&lt;/a&gt; by Stuart Halloway.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4851261502438710182-4690517778291731309?l=formpluslogic.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://formpluslogic.blogspot.com/feeds/4690517778291731309/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://formpluslogic.blogspot.com/2009/12/clojure-and-jmx.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4851261502438710182/posts/default/4690517778291731309'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4851261502438710182/posts/default/4690517778291731309'/><link rel='alternate' type='text/html' href='http://formpluslogic.blogspot.com/2009/12/clojure-and-jmx.html' title='Clojure and JMX'/><author><name>Brenton Ashworth</name><uri>http://www.blogger.com/profile/13919036386288728360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_nymZllDZetA/Sl5xXNc89zI/AAAAAAAAA28/27f1wAZ9KWo/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_nymZllDZetA/SyKwRr8VNtI/AAAAAAAAA4g/QFmUPDWtfEU/s72-c/jconsole.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4851261502438710182.post-4122172565810364549</id><published>2009-12-09T13:48:00.000-08:00</published><updated>2009-12-09T15:04:52.935-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SICP'/><category scheme='http://www.blogger.com/atom/ns#' term='Clojure'/><title type='text'>First-Class Functions and Sequences</title><content type='html'>In &lt;a href="http://formpluslogic.blogspot.com/2009/12/power-of-first-class-functions.html"&gt;yesterday's post&lt;/a&gt; I wrote about the power of first-class functions and gave an example of how their correct use can lead to more reusable and understandable code.&lt;br /&gt;&lt;br /&gt;As I continue to review the book &lt;a href="http://mitpress.mit.edu/sicp/"&gt;Structure and Interpretation of Computer Programs&lt;/a&gt; I came across another great example of the point that I was trying to make. This example comes from section &lt;a href="http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-15.html#%_sec_2.2.3"&gt;2.2.3 Sequences as Conventional Interfaces&lt;/a&gt;. All code has once again been translated to Clojure.&lt;br /&gt;&lt;br /&gt;&lt;big&gt;Prelude&lt;/big&gt;&lt;br /&gt;&lt;br /&gt;Below are some helper functions that we will use:&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(defn empty-list? [x]&lt;br /&gt;  (and (list? x) (empty? x)))&lt;br /&gt;&lt;br /&gt;(defn fib [x]&lt;br /&gt;  (nth (fibs) x))&lt;br /&gt;&lt;br /&gt;(defn square [x]&lt;br /&gt;  (* x x))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;I also use the functions &lt;code&gt;fibs&lt;/code&gt;, and &lt;code&gt;flatten&lt;/code&gt; below which come from &lt;code&gt;clojure.contrib.lazy-seqs&lt;/code&gt; and &lt;code&gt;clojure.contrib.seq-utils&lt;/code&gt; respectively.&lt;br /&gt;&lt;br /&gt;&lt;big&gt;What We Could Do&lt;/big&gt;&lt;br /&gt;&lt;br /&gt;Imagine that we have a tree that we have constructed as shown below.&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(def a-tree (cons (list 1 2) (list 3 4)))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;What if we wanted to create a function that will calculate the sum of the squares of the odd numbers in the tree? We could write something like this.&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(defn sum-odd-squares [tree]&lt;br /&gt;  (cond (empty-list? tree) 0&lt;br /&gt;        (not (seq? tree)) (if (odd? tree) (square tree) 0)&lt;br /&gt;        :else (+ (sum-odd-squares (first tree))&lt;br /&gt;                 (sum-odd-squares (rest tree)))))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;This works for small trees. It is a Clojure version of the Scheme example in SICP. Don't do this. It won't work for large trees. But let's assume that this is a good working implementation.&lt;br /&gt;&lt;br /&gt;Now imagine that later on we need a function that will take an integer &lt;code&gt;n&lt;/code&gt; and returns a list of all the even Fibonacci numbers &lt;code&gt;Fib(k)&lt;/code&gt;, where &lt;code&gt;k&lt;/code&gt; is less than or equal to a given integer &lt;code&gt;n&lt;/code&gt;:&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(defn even-fibs [n]&lt;br /&gt;  (loop [k 0&lt;br /&gt;         result []]&lt;br /&gt;    (if (&gt; k n)&lt;br /&gt;        (reverse result)&lt;br /&gt;        (let [f (fib k)]&lt;br /&gt;          (if (even? f)&lt;br /&gt;              (recur (+ k 1) (cons f result))&lt;br /&gt;              (recur (+ k 1) result))))))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;On the surface these look like two very different functions. Looking at the functions, it is not obvious how we could extract any common functionality. Reading this code is difficult.&lt;br /&gt;&lt;br /&gt;How could we improve this? This is like the situation where you ask someone for directions and they tell you that if they were going there, they wouldn't start here.&lt;br /&gt;&lt;br /&gt;&lt;big&gt;What We Should Do - Thinking in Sequences&lt;/big&gt;&lt;br /&gt;&lt;br /&gt;What if we had started by solving each of these problems as a series of sequence transformations? If we did this then we would realize that these two problems have a lot in common and that Clojure already has all of the abstractions that we need to write very simple and readable versions of these functions.&lt;br /&gt;&lt;br /&gt;Here is what our new version of &lt;code&gt;sum-odd-squares&lt;/code&gt; looks like:&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(defn sum-odd-squares [tree]&lt;br /&gt;  (reduce + &lt;br /&gt;          (map square &lt;br /&gt;               (filter odd? &lt;br /&gt;                       (flatten tree)))))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;And here is how we would write &lt;code&gt;even-fibs&lt;/code&gt;:&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(defn even-fibs [n]&lt;br /&gt;  (filter even? &lt;br /&gt;          (map fib &lt;br /&gt;               (range n))))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Notice all that these two functions now have in common. We create an initial sequence. We transform that sequence using &lt;code&gt;map&lt;/code&gt;. We &lt;code&gt;filter&lt;/code&gt; the sequence. Also notice how little we are actually doing here. There is very little that can go wrong. It feels like it would be a waist of time to actually write a test for this.&lt;br /&gt;&lt;br /&gt;It is nothing less than amazing how many problems can be solved using filter, map and reduce while thinking of your data as a sequence. Clojure encourages you to think in sequences, and if you do, it will pay off in a lot less code.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4851261502438710182-4122172565810364549?l=formpluslogic.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://formpluslogic.blogspot.com/feeds/4122172565810364549/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://formpluslogic.blogspot.com/2009/12/first-class-functions-and-sequences.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4851261502438710182/posts/default/4122172565810364549'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4851261502438710182/posts/default/4122172565810364549'/><link rel='alternate' type='text/html' href='http://formpluslogic.blogspot.com/2009/12/first-class-functions-and-sequences.html' title='First-Class Functions and Sequences'/><author><name>Brenton Ashworth</name><uri>http://www.blogger.com/profile/13919036386288728360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_nymZllDZetA/Sl5xXNc89zI/AAAAAAAAA28/27f1wAZ9KWo/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4851261502438710182.post-8147601456729676366</id><published>2009-12-08T14:56:00.000-08:00</published><updated>2009-12-09T15:06:21.615-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SICP'/><category scheme='http://www.blogger.com/atom/ns#' term='Clojure'/><title type='text'>The Power of First-Class Functions</title><content type='html'>Many languages now have support for first-class functions, some fully embrace them. Those that embrace them are the functional languages. That's why their called functional. There is great power when first-class functions are truly first-class.&lt;br /&gt;&lt;br /&gt;As with any power that we are given, it is one thing to know it's there, it is another thing to understand it and yet another to use it effectively in your programs without abusing it. In this post I would like to go through a great example of this power and its correct use. &lt;br /&gt;&lt;br /&gt;&lt;big&gt;Prelude&lt;/big&gt;&lt;br /&gt;&lt;br /&gt;The example is taken from the book &lt;a href="http://mitpress.mit.edu/sicp/"&gt;Structure and Interpretation of Computer Programs&lt;/a&gt; (SICP) section &lt;a href="http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-12.html#%_sec_1.3.3"&gt;1.3.3 Procedures as General Methods&lt;/a&gt;. The example code is written in Clojure instead of Scheme. All of my example code is a Clojure version of the examples in that section of the book so that you will be able to compare implementations. This whole exercise is not meant to be practical but illustrative. I am not trying to write the most efficient and robust code. The main point of this post is to show a style of programming that is enabled by the skilled use of first-class functions which allows the developer to work at the correct level of abstraction and create the maximum amount of reusable code.&lt;br /&gt;&lt;br /&gt;Before we dive in, we will need a few helper functions to simplify the code below.&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(def tolerance 0.001)&lt;br /&gt;&lt;br /&gt;(defn sin [x]&lt;br /&gt;  (Math/sin x))&lt;br /&gt;&lt;br /&gt;(defn cos [x]&lt;br /&gt;  (Math/cos x))&lt;br /&gt;&lt;br /&gt;(defn square [x]&lt;br /&gt;  (* x x))&lt;br /&gt;&lt;br /&gt;(defn cube [x]&lt;br /&gt;  (* x x x))&lt;br /&gt;&lt;br /&gt;(defn average [x y]&lt;br /&gt;  (/ (+ x y) 2.0))&lt;br /&gt;&lt;br /&gt;(defn abs [x]&lt;br /&gt;  (if (&lt; x 0) (- x) x))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;big&gt;What Are First-Class Functions?&lt;/big&gt;&lt;br /&gt;&lt;br /&gt;I wish I had studied SICP as a student. It would have saved me a lot of frustration. In that book, first-class elements of a language are described as elements which may be:&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;named by variables&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;passed as arguments to procedures&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;returned as the results of procedures&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;included in data structures&lt;br /&gt;&lt;br /&gt;Below we will look at the use of the first three features.&lt;br /&gt;&lt;br /&gt;&lt;big&gt;A Function to Find the Square Root of a Number&lt;/big&gt;&lt;br /&gt;&lt;br /&gt;Imagine that we are creating some software which will need to solve various types of math problems. We may decide that we need to function to calculate the square root of a number and therefore write the following code.&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(defn sqrt [x]&lt;br /&gt;  (loop [guess 1.0]&lt;br /&gt;    (let [good-enough? #(&lt; (abs (- (square %) x)) tolerance)&lt;br /&gt;          improve #(average % (/ x %))]&lt;br /&gt;      (if (good-enough? guess)&lt;br /&gt;          guess&lt;br /&gt;          (recur (improve guess))))))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;That’s not bad. It’s efficient and fairly clear. We may, at this point, decide that we are done and move on the next problem. If we program in this manner, we are going to end up with a lot more code than we actually need. The problem with this code is that there are hidden patterns which can be extracted, named and reused. Once we do this, we will not only have all of that reusable code, but we will also have a cleaner version of &lt;code&gt;sqrt&lt;/code&gt; and more readable code in general.&lt;br /&gt;&lt;br /&gt;&lt;big&gt;Finding the Fixed Point of a Function&lt;/big&gt;&lt;br /&gt;&lt;br /&gt;Since we are writing a program that is going to be solving math problems, we may also need to find the fixed point of a function. From section 1.3.3 of SICP we have the definition of a fixed point of a function: “A number &lt;code&gt;x&lt;/code&gt; is called a fixed point of a function &lt;code&gt;f&lt;/code&gt; if &lt;code&gt;x&lt;/code&gt; satisfies the equation &lt;code&gt;f(x) = x&lt;/code&gt;. For some functions &lt;code&gt;f&lt;/code&gt; we can locate a fixed point by beginning with an initial guess and applying &lt;code&gt;f&lt;/code&gt; repeatedly”&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_nymZllDZetA/Sx7eA9siLUI/AAAAAAAAA34/1JELn52KbSo/s1600-h/Figure1.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 57px;" src="http://2.bp.blogspot.com/_nymZllDZetA/Sx7eA9siLUI/AAAAAAAAA34/1JELn52KbSo/s320/Figure1.png" alt="" id="BLOGGER_PHOTO_ID_5413007910288633154" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;We can write a function that does this...&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(defn fixed-point [f first-guess]&lt;br /&gt;  (loop [guess first-guess]&lt;br /&gt;    (let [next (f guess)]&lt;br /&gt;      (if (close-enough? guess next)&lt;br /&gt;          next&lt;br /&gt;          (recur next)))))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;...and try it out by finding solutions to y = cos y and y = sin y + cos y.&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;; find solution to y = cos y&lt;br /&gt;(fixed-point cos 1.0)&lt;br /&gt;&gt;&gt; 0.7387603198742113&lt;br /&gt;&lt;br /&gt;; find solution to y = sin y + cos y&lt;br /&gt;(fixed-point #(+ (sin %) (cos %)) 1.0)&lt;br /&gt;&gt;&gt; 1.259003859740025&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;This is a useful technique which we are sure to use throughout our software.&lt;br /&gt;&lt;br /&gt;What does this have to do with square roots? Well, if we have a number &lt;code&gt;x&lt;/code&gt; then we are looking for a number &lt;code&gt;y&lt;/code&gt; such that &lt;code&gt;y * y = x&lt;/code&gt;. If we divide both sides of this equation by y we get &lt;code&gt;y = x / y&lt;/code&gt;. Given an &lt;code&gt;x&lt;/code&gt;, we need to find a solution to &lt;code&gt;y = x / y&lt;/code&gt; and we may be able to do this with our new &lt;code&gt;fixed-point&lt;/code&gt; function.&lt;br /&gt;&lt;br /&gt;If we try this...&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(defn sqrt [x]&lt;br /&gt;  (fixed-point #(/ x %) 1.0))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;...it will not work. If we apply that function to a value of &lt;code&gt;x&lt;/code&gt; over and over again we just oscillate between two values forever.&lt;br /&gt;&lt;br /&gt;&lt;big&gt;Average Damping&lt;/big&gt;&lt;br /&gt;&lt;br /&gt;To fix the above problem we can do this.&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(defn sqrt [x]&lt;br /&gt;  (fixed-point #(average % (/ x %)) 1.0))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Instead of using the new value of the function as the new guess, we use the average of the old guess and the new value of the function. This is called average damping. We could again stop here. But average damping is a concept that we may use again in our software. We can extract this into a method...&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(defn average-damp [f]&lt;br /&gt;  #(average % (f %)))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;...and rewrite our &lt;code&gt;sqrt&lt;/code&gt; function as shown below.&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(defn sqrt&lt;br /&gt;  "solve y -&gt; x / y to find the square root"&lt;br /&gt;  [x]&lt;br /&gt;  (fixed-point (average-damp #(/ x %)) 1.0))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;We could also create a cube-root function using the same pattern but finding a solution to &lt;code&gt;y = x / (y * y)&lt;/code&gt;.&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(defn cube-root&lt;br /&gt;  "solve y -&gt; x / (y * y) to find the cube root"&lt;br /&gt;  [x]&lt;br /&gt;  (fixed-point (average-damp #(/ x (square %))) 1.0))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;The &lt;code&gt;average-damp&lt;/code&gt; function is a function that returns a function. You pass it a function and it returns an average damped version of that function. We now have another powerful concept that we can use anywhere thanks to first-class functions. Also, our implementation of sqrt is much better. As stated in SICP “Notice how this formulation makes explicit the three ideas in the method: fixed-point search, average-damping, and the function &lt;code&gt;y -&gt; x / y&lt;/code&gt;.”&lt;br /&gt;&lt;br /&gt;&lt;big&gt;Newton’s Method&lt;/big&gt;&lt;br /&gt;&lt;br /&gt;If we are going to be finding solutions to equations then we will surely be using Newton’s method at some point. From SICP we have this description of Newton’s method.&lt;br /&gt;&lt;br /&gt;“If &lt;code&gt;x -&gt; g(x)&lt;/code&gt; is a differentiable function, then a solution of the equation &lt;code&gt;g(x) = 0&lt;/code&gt; is a fixed point of the function &lt;code&gt;x -&gt; f(x)&lt;/code&gt; where&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_nymZllDZetA/Sx7fpp3T8-I/AAAAAAAAA4A/EKKC4ZVKoV8/s1600-h/Figure2.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 245px; height: 116px;" src="http://2.bp.blogspot.com/_nymZllDZetA/Sx7fpp3T8-I/AAAAAAAAA4A/EKKC4ZVKoV8/s320/Figure2.png" alt="" id="BLOGGER_PHOTO_ID_5413009708851393506" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;and &lt;code&gt;Dg(x)&lt;/code&gt; is the derivative of &lt;code&gt;g&lt;/code&gt; evaluated at &lt;code&gt;x&lt;/code&gt;.”&lt;br /&gt;&lt;br /&gt;Notice that Newton’s method will use the fixed-point function that we have created. Nice!&lt;br /&gt;&lt;br /&gt;To implement Newton’s method we will need a derivative function. Notice that the derivative function will need to be a function that takes a function &lt;code&gt;g&lt;/code&gt; and returns a function of &lt;code&gt;x&lt;/code&gt;.&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_nymZllDZetA/Sx7gPBgjnBI/AAAAAAAAA4I/h23TQ0UoLNg/s1600-h/Figure3.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 125px;" src="http://4.bp.blogspot.com/_nymZllDZetA/Sx7gPBgjnBI/AAAAAAAAA4I/h23TQ0UoLNg/s320/Figure3.png" alt="" id="BLOGGER_PHOTO_ID_5413010350853561362" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Here is my Clojure implementation.&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(defn deriv [g]&lt;br /&gt;  (let [dx 0.00001]&lt;br /&gt;    #(/ (- (g (+ % dx)) (g %)) dx)))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;We now use this to create the &lt;code&gt;newton-transform&lt;/code&gt; function which is also a high-order function...&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(defn newton-transform [g] &lt;br /&gt;  #(- % (/ (g %) ((deriv g) %))))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;...and finally we create the &lt;code&gt;newtons-method&lt;/code&gt; function using &lt;code&gt;fixed-point&lt;/code&gt;.&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(defn newtons-method [g guess]&lt;br /&gt;  (fixed-point (newton-transform g) guess))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Newton’s method can find the solution to the equation &lt;code&gt;g(x) = 0&lt;/code&gt;. If we wanted to use Newton’s method to find square roots then we would need to find the &lt;code&gt;y&lt;/code&gt; such that &lt;code&gt;(y * y) - x = 0&lt;/code&gt;.&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(defn sqrt &lt;br /&gt;  "find the fixed point of y -&gt; (y * y) - x"&lt;br /&gt;  [x]&lt;br /&gt;  (newtons-method #(- (square %) x) 1.0))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;big&gt;The Final Abstraction&lt;/big&gt;&lt;br /&gt;&lt;br /&gt;Notice that our two different implementations of &lt;code&gt;sqrt&lt;/code&gt; follow a pattern: find the fixed point of a transformed function based on an initial guess. Let’s extract that pattern for reuse.&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(defn fixed-point-of-transform [g transform guess]&lt;br /&gt;  (fixed-point (transform g) guess))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;We can now use this to implement &lt;code&gt;sqrt&lt;/code&gt; using two different functions and function transformations.&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(defn sqrt [x]&lt;br /&gt;  (fixed-point-of-transform #(/ x %)&lt;br /&gt;                            average-damp&lt;br /&gt;                            1.0))&lt;br /&gt;&lt;br /&gt;(defn sqrt [x]&lt;br /&gt;  (fixed-point-of-transform #(- (square %) x)&lt;br /&gt;                            newton-transform&lt;br /&gt;                            1.0))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;These are clear implementations of &lt;code&gt;sqrt&lt;/code&gt; using high level concepts that are reusable in many areas of our software.&lt;br /&gt;&lt;br /&gt;&lt;big&gt;Conclusion&lt;/big&gt;&lt;br /&gt;&lt;br /&gt;Think about the simplicity, conciseness and maintainability of the software that you could write if you could master this kind of programming.&lt;br /&gt;&lt;br /&gt;I have already noticed a big difference in the kind of code that I write as I have started to use Clojure. Many of the most commonly used concepts have already been extracted to functions and are included in the Clojure API. Someone who has internalized this API and knows how to use it correctly can do amazing things with very little code. For exmaple, take a look at this code from a blog post by Tim Bray entitled &lt;a href="http://www.tbray.org/ongoing/When/200x/2009/11/30/Idiomatic-Clojure"&gt;Idiomatic Clojure&lt;/a&gt;.&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(defn find-widely&lt;br /&gt;  "Return a map of pages to hit counts in filename."&lt;br /&gt;  [filename] &lt;br /&gt;  (apply merge-with +&lt;br /&gt;         (pmap count-lines&lt;br /&gt;               (partition-all *batch-size*&lt;br /&gt;                              (line-seq (reader filename))))))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt; &lt;br /&gt;In another post entitled &lt;a href="http://www.tbray.org/ongoing/When/200x/2009/12/01/Clojure-Theses"&gt;Eleven Theses on Clojure&lt;/a&gt; Tim, who is otherwise inclined to like Clojure, writes that it is a handicap that Clojure is a Lisp and that some human minds may react poorly to the &lt;code&gt;find-widely&lt;/code&gt; function above. This is true for a reader who is new to Clojure and not already familiar with the concepts that are being used. But for someone who has internalized the API, this is more readable than most other ways you could code this same functionality. This is made possible by embracing and mastering the use of first-class functions.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4851261502438710182-8147601456729676366?l=formpluslogic.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://formpluslogic.blogspot.com/feeds/8147601456729676366/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://formpluslogic.blogspot.com/2009/12/power-of-first-class-functions.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4851261502438710182/posts/default/8147601456729676366'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4851261502438710182/posts/default/8147601456729676366'/><link rel='alternate' type='text/html' href='http://formpluslogic.blogspot.com/2009/12/power-of-first-class-functions.html' title='The Power of First-Class Functions'/><author><name>Brenton Ashworth</name><uri>http://www.blogger.com/profile/13919036386288728360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_nymZllDZetA/Sl5xXNc89zI/AAAAAAAAA28/27f1wAZ9KWo/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_nymZllDZetA/Sx7eA9siLUI/AAAAAAAAA34/1JELn52KbSo/s72-c/Figure1.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4851261502438710182.post-1390915715604641942</id><published>2009-12-01T11:06:00.001-08:00</published><updated>2010-03-30T10:34:39.206-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Clojure'/><title type='text'>My Clojure Setup - Update</title><content type='html'>Update: There is now an official &lt;a href="http://www.assembla.com/wiki/show/clojure/Getting_Started"&gt;Getting Started&lt;/a&gt; page for Clojure. Please refer to the instructions on this page for information about how to get started with Clojure in the environment that you are most comfortable with. The information below may now be irrelevant.&lt;br /&gt;&lt;br /&gt;I recently posted about &lt;a href="http://formpluslogic.blogspot.com/2009/09/my-clojure-setup.html"&gt;my Clojure setup&lt;/a&gt; because I thought that it would be useful to others who are getting started with Clojure. I have made a couple of changes to the way I am doing things and thought that it might be time for an update.&lt;br /&gt;&lt;br /&gt;&lt;big&gt;The Ruby Script&lt;/big&gt;&lt;br /&gt;&lt;br /&gt;There have been two changes to the Ruby script that I use to start Clojure. The &lt;a href="http://formpluslogic.blogspot.com/2009/09/my-clojure-setup.html"&gt;previous version&lt;/a&gt; did not check for command line arguments correctly. This has been fixed. Next, I made a small improvement. I don't like having to type ".clj" each time I run a script so I added some code to add the file extension if you leave it out.&lt;br /&gt;&lt;br /&gt;I have included the entire script below.&lt;br /&gt;&lt;br /&gt;This isn't meant to be used "as is" on your system. If you plan to use it then you will need to make the necessary modifications to get it working. This is what works for me so I thought I would share.&lt;br /&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/247899.js?file=clj.rb"&gt;&lt;/script&gt;&lt;br /&gt;&lt;big&gt;Running Tests&lt;/big&gt;&lt;br /&gt;&lt;br /&gt;I have also made improvements to the code that I use to run my tests. See my post on &lt;a href="http://formpluslogic.blogspot.com/2009/08/clojure-unit-testing-part-1.html"&gt;Unit Testing&lt;/a&gt; for more information.&lt;br /&gt;&lt;br /&gt;I like for my tests to run fast. Clojure makes concurrency easy. Therefore, I have changed my test runner to run each test namespace in parallel. Sometimes I only want to run tests for a single namespace. I can now do this by adding the file name, without the .clj extension as an argument to the script which runs my tests. Finally, if I add "-seq" as a command line argument, all of the test namespaces will be run sequentially.&lt;br /&gt;&lt;br /&gt;Here is the code:&lt;br /&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/247939.js?file=test.clj"&gt;&lt;/script&gt;&lt;br /&gt;This file is part of a small (but growing) set of utilities that I use which can be found on &lt;a href="http://github.com/brentonashworth/sandbar"&gt;GitHub&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;If you are going to run your tests in parallel then they have to be able to run in parallel. It is good practice to set your tests up so that they don't depend on each other. Actually running them in parallel forces you to do this.&lt;br /&gt;&lt;br /&gt;I only have two cores on my development machine and this is already saving me time. The more cores that I have in the future the more time it will save. It feels good to know that newer hardware will once again cause my programs to run faster.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4851261502438710182-1390915715604641942?l=formpluslogic.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://formpluslogic.blogspot.com/feeds/1390915715604641942/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://formpluslogic.blogspot.com/2009/12/my-clojure-setup-update.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4851261502438710182/posts/default/1390915715604641942'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4851261502438710182/posts/default/1390915715604641942'/><link rel='alternate' type='text/html' href='http://formpluslogic.blogspot.com/2009/12/my-clojure-setup-update.html' title='My Clojure Setup - Update'/><author><name>Brenton Ashworth</name><uri>http://www.blogger.com/profile/13919036386288728360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_nymZllDZetA/Sl5xXNc89zI/AAAAAAAAA28/27f1wAZ9KWo/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4851261502438710182.post-5253803002536064988</id><published>2009-11-24T15:17:00.001-08:00</published><updated>2009-12-09T13:47:37.174-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Concurrency'/><title type='text'>Programming Plato’s New Computer</title><content type='html'>There are four things that have a huge impact on how we think about solving problems as software developers: our experience, education, &lt;a href="http://www.bestinclass.dk/index.php/2009/11/mind-games-ascension/?utm_source=feedburner&amp;amp;utm_medium=feed&amp;amp;utm_campaign=Feed%3A+bestinclass-the-blog+%28Best+in+Class+-+The+Blog%29&amp;amp;utm_content=Google+Reader"&gt;programming languages&lt;/a&gt; and Plato’s computer.&lt;br /&gt;&lt;br /&gt;Plato’s computer is the ideal computer. Not the best computer, but the idea that we have in our minds about what a computer is and how it works. Our programming languages are not yet so high level that we don’t have to think about Plato’s computer when solving a problem. After all, we’re programmers, and we have to program something. We are programming Plato’s computer.&lt;br /&gt;&lt;br /&gt;So what does Plato’s computer look like these days? It has a processor, RAM, a disk, a network connection, and I/O capabilities.&lt;br /&gt;&lt;br /&gt;Computer technology changes very rapidly. But notice that Plato has been using the same computer for a very long time. I got a Commodore 64 back in the 80s and learned to program it using BASIC. Real computers have changed a lot since then. But Plato still has the same one.&lt;br /&gt;&lt;br /&gt;Sometime in the next 20 years Plato will be getting a new computer. There will only be one additional letter in the description of his new machine. An “s”. It will have processors, RAM, a disk, a network connection, and I/O capabilities.&lt;br /&gt;&lt;br /&gt;That’s right, it will now have processors.&lt;br /&gt;&lt;br /&gt;In this business, if something has been the same for 30 or 40 years, and then changes, that is a big deal. If one of the four things that impacts the way that we think about solving problems changes, that is a big deal. This is what we call a &lt;a href="http://en.wikipedia.org/wiki/Paradigm_shift"&gt;paradigm shift&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Once Plato gets his new computer, we will all be doing things differently. After all, that is the cause of him getting a new computer.&lt;br /&gt;&lt;br /&gt;Most of us now have computers with multiple processors and/or cores. My laptop has two. My Windows desktop machine has four. My Linux machine has eight. Maybe you know some really cool guy who has thirty two. The other day &lt;a href="http://media-newswire.com/release_1106331.html"&gt;I read about a machine that has 255,584&lt;/a&gt; (Unnecessary nerd fact: this machine also has 362 terabytes of RAM and a 10 petabyte file system.) Even though these machines exist, it has not penetrated through to the ideal. It won’t until most machines have thousands of cores. Today most machines have one or two cores. Some day most will have thousands. Some day millions.&lt;br /&gt;&lt;br /&gt;A huge change is coming. It has already started and will be complete sometime in the middle of my career. As with all &lt;a href="http://en.wikipedia.org/wiki/Paradigm_shift#Kuhnian_paradigm_shifts"&gt;paradigm shifts&lt;/a&gt;, there will be denial, crisis and maybe even despair.&lt;br /&gt;&lt;br /&gt;As for me, I would like to start wrapping my head around this as soon as possible. &lt;a href="http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hickey"&gt;Many are already doing this&lt;/a&gt;. I want to learn how to program Plato’s new computer. At the very least it will mean shifting my thinking from sequential to parallel problem solving, investigating new (to me) languages such as Clojure, Erlang and Haskell and questioning common architectural patterns which are based on the limitations of Plato's old computer.&lt;br /&gt;&lt;br /&gt;What do you think are the most significant changes that will occur as we move to this new paradigm?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4851261502438710182-5253803002536064988?l=formpluslogic.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://formpluslogic.blogspot.com/feeds/5253803002536064988/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://formpluslogic.blogspot.com/2009/11/programming-platos-new-computer.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4851261502438710182/posts/default/5253803002536064988'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4851261502438710182/posts/default/5253803002536064988'/><link rel='alternate' type='text/html' href='http://formpluslogic.blogspot.com/2009/11/programming-platos-new-computer.html' title='Programming Plato’s New Computer'/><author><name>Brenton Ashworth</name><uri>http://www.blogger.com/profile/13919036386288728360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_nymZllDZetA/Sl5xXNc89zI/AAAAAAAAA28/27f1wAZ9KWo/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4851261502438710182.post-2803972559453093976</id><published>2009-09-12T16:04:00.000-07:00</published><updated>2010-03-30T10:33:33.543-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Clojure'/><title type='text'>My Clojure Setup</title><content type='html'>Update: There is now an official &lt;a href="http://www.assembla.com/wiki/show/clojure/Getting_Started"&gt;Getting Started&lt;/a&gt; page for Clojure. Please refer to the instructions on this page for information about how to get started with Clojure in the environment that you are most comfortable with. The information below may now be irrelevant.&lt;br /&gt;&lt;br /&gt;I have just switched over to using SLIME instead of the basic Lisp interaction that was provided with clojure-mode. A discussion on the &lt;a href="http://groups.google.com/group/clojure/browse_thread/thread/746ab3adc44e2d4a/646f25acfab6fdab?hl=en&amp;amp;"&gt;clojure-group&lt;/a&gt; prompted me to do this. In this same discussion there where questions about how people setup Clojure and how it can be difficult for new users to get started. My setup is not perfect but I am really starting to like it. I thought I would share with others and maybe get some feedback on improvements I can make. I will update this entry as I make changes to my setup.&lt;br /&gt;&lt;br /&gt;&lt;big&gt;Overview&lt;/big&gt;&lt;br /&gt;&lt;br /&gt;Let me tell you a little bit about my setup so that you can get into how cool it is and then get excited about reading all of the stuff below.&lt;br /&gt;&lt;br /&gt;I have a command on my system named &lt;code&gt;clj&lt;/code&gt;.&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;clj =&gt; starts a REPL&lt;br /&gt;clj some_file.clj =&gt; Runs the script some_file.clj&lt;br /&gt;clj some_file.clj arg1 arg2 =&gt; Runs the script some_file.clj and passes &lt;br /&gt;arg1 arg2 to the script&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;When I start to get serious, I create a "project" which looks like this:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;my-project&lt;br /&gt;.cljrc.clj&lt;br /&gt;bin&lt;br /&gt;lib&lt;br /&gt;src&lt;br /&gt;test&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;The file &lt;code&gt;.cljrc.clj&lt;/code&gt; establishes this as a Clojure project. If I execute &lt;code&gt;clj&lt;/code&gt; anywhere within this project it will determine the root of the project by locating the &lt;code&gt;.cljrc.clj&lt;/code&gt; file and then start the REPL in that directory. It will also load any jar files within the &lt;code&gt;lib&lt;/code&gt; directory into the classpath. The file &lt;code&gt;.cljrc.clj&lt;/code&gt; is passed as a parameter to the REPL which will execute the Clojure code contained therein.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;bin&lt;/code&gt; contains commands that allow me to do things like run my tests, compile java code, package java code in a jar file and put it in the lib directory for use from Clojure, etc...&lt;br /&gt;&lt;br /&gt;All source files go into &lt;code&gt;src&lt;/code&gt; and all tests go into &lt;code&gt;test&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;I can run SLIME from emacs and the &lt;code&gt;clj&lt;/code&gt; script will be used to start Clojure. Once I have started a REPL using this command. I can open emacs and connect to the running REPL and interact with it from within emacs.&lt;br /&gt;&lt;br /&gt;&lt;big&gt;Configure Emacs&lt;/big&gt;&lt;br /&gt;&lt;br /&gt;I did not use &lt;code&gt;M-x clojure-install&lt;/code&gt; to configure emacs. Instead, I followed this tutorial &lt;a href="http://riddell.us/tutorial/slime_swank/slime_swank.html"&gt;http://riddell.us/tutorial/slime_swank/slime_swank.html&lt;/a&gt; which worked for me on OS X even though it targets Ubuntu. After doing this, I had SLIME working with Clojure in emacs.&lt;br /&gt;&lt;br /&gt;Here is my .emacs file:&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;;; clojure-mode&lt;br /&gt;(add-to-list 'load-path "/opt/clojure/clojure-mode")&lt;br /&gt;(require 'clojure-mode)&lt;br /&gt;&lt;br /&gt;;; swank-clojure&lt;br /&gt;(add-to-list 'load-path "/opt/clojure/swank-clojure")&lt;br /&gt;(setq swank-clojure-binary "clj")&lt;br /&gt;(require 'swank-clojure-autoload)&lt;br /&gt;&lt;br /&gt;;; slime&lt;br /&gt;(eval-after-load "slime"&lt;br /&gt;`(progn (slime-setup '(slime-repl))))&lt;br /&gt;&lt;br /&gt;(add-to-list 'load-path "/opt/slime")&lt;br /&gt;(require 'slime)&lt;br /&gt;(slime-setup)&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Notice that I added the &lt;code&gt;swank-clojure-binary&lt;/code&gt; line instead of &lt;code&gt;swank-clojure-config&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;&lt;big&gt;The Ruby Script&lt;/big&gt;&lt;br /&gt;&lt;br /&gt;This is the Ruby script that I use to start Clojure. I don't do much Ruby coding so please don't laugh.&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;#!/usr/bin/env ruby -wKU&lt;br /&gt;&lt;br /&gt;JAVA_HOME="/System/Library/Frameworks/JavaVM.framework/Versions/1.6/Home"&lt;br /&gt;JAVA="#{JAVA_HOME}/bin/java"&lt;br /&gt;GIT_ROOT=ENV['GIT_ROOT']&lt;br /&gt;CLJ="/opt/clojure"&lt;br /&gt;LIB="#{GIT_ROOT}/library"&lt;br /&gt;classpath=".:src:test:classes" +&lt;br /&gt;":#{CLJ}/clojure/clojure.jar" +&lt;br /&gt;":#{CLJ}/clojure-contrib/clojure-contrib.jar" +&lt;br /&gt;":#{CLJ}/swank-clojure" +&lt;br /&gt;":#{LIB}/tools/ant.jar" +&lt;br /&gt;":#{LIB}/tools/ant-launcher.jar" +&lt;br /&gt;":#{GIT_ROOT}/research/clojure/fpl-clojure-util/fpl-clojure-util.jar"&lt;br /&gt;JLINE="#{LIB}/bin-tools/jline-0.9.94.jar"&lt;br /&gt;&lt;br /&gt;def find_root(d, repl_config)&lt;br /&gt;Dir.chdir(d)&lt;br /&gt;if Dir.pwd == "/"&lt;br /&gt;nil&lt;br /&gt;else&lt;br /&gt;if Dir.glob("#{repl_config}").size == 1&lt;br /&gt;Dir.pwd&lt;br /&gt;else&lt;br /&gt;find_root("../", repl_config)&lt;br /&gt;end&lt;br /&gt;end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;repl_config=".cljrc.clj"&lt;br /&gt;dir = Dir.pwd&lt;br /&gt;if find_root(dir, repl_config)&lt;br /&gt;puts "Running in #{Dir.pwd}"&lt;br /&gt;else&lt;br /&gt;Dir.chdir(dir)&lt;br /&gt;puts "Running in #{Dir.pwd}"&lt;br /&gt;puts "Using default #{repl_config}"&lt;br /&gt;repl_config="~/.cljrc.clj"&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;if File.directory? "lib"&lt;br /&gt;Dir.foreach("lib") do |x|&lt;br /&gt;if x =~ /.*.jar$/&lt;br /&gt;classpath = classpath + ":lib/#{x}"&lt;br /&gt;end&lt;br /&gt;end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;if ARGV[0]&lt;br /&gt;puts "Running Clojure Script... #{ARGV[0]}"&lt;br /&gt;if ARGV[0].size &gt; 1&lt;br /&gt;system("#{JAVA} -Xms500M -Xmx500M -cp #{classpath} "+&lt;br /&gt;"clojure.lang.Script #{ARGV.shift} -- #{ARGV.join(" ")}")&lt;br /&gt;else&lt;br /&gt;system("#{JAVA} -Xms500M -Xmx500M -cp #{classpath} "+&lt;br /&gt;"clojure.lang.Script #{ARGV[0]}")&lt;br /&gt;end&lt;br /&gt;else&lt;br /&gt;puts "Starting Clojure REPL..."&lt;br /&gt;system("#{JAVA} -cp #{classpath}:#{JLINE} jline.ConsoleRunner "+&lt;br /&gt;"clojure.lang.Repl #{repl_config}")&lt;br /&gt;end&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Note: This file has been updated in a &lt;a href="http://formpluslogic.blogspot.com/2009/12/my-clojure-setup-update.html"&gt;more recent blog post&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I name this file &lt;code&gt;clj&lt;/code&gt; and put it somewhere in my path. If you want to use this then you will need to modify the default libraries that are loaded.&lt;br /&gt;&lt;br /&gt;Here is what I have in &lt;code&gt;.cljrc.clj&lt;/code&gt;:&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(use '[clojure.contrib.duck-streams :only (spit)])&lt;br /&gt;(use '[swank.swank :only (start-server ignore-protocol-version)])&lt;br /&gt;&lt;br /&gt;(defn exit [] (. System exit 0))&lt;br /&gt;&lt;br /&gt;(defn swank-server []&lt;br /&gt;(ignore-protocol-version "2009-09-08")&lt;br /&gt;(spit (java.io.File. "port.txt") "")&lt;br /&gt;(start-server "port.txt" :port 4005 :dont-close true))&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;This code will be executed when you run &lt;code&gt;clj&lt;/code&gt; within a project. It defines an exit function that you can use to exit the REPL. It also defines a function that will start a swank server from within the REPL. You will need to the set the correct value for &lt;code&gt;ignore-protocol-version&lt;/code&gt;. If you don't know what to put here then you can delete this line and emacs will give you a hint as to what it should be.&lt;br /&gt;&lt;br /&gt;&lt;big&gt;So how does this all work?&lt;/big&gt;&lt;br /&gt;&lt;br /&gt;On Mac OS X I have associated the &lt;code&gt;.clj&lt;/code&gt; file type with Carbon Emacs. This allows me to open a file for editing by typing &lt;code&gt;open some_file.clj&lt;/code&gt;. I can also use wildcards to open multiple files from the command line in emacs.&lt;br /&gt;&lt;br /&gt;Once emacs is open, start SLIME by typing &lt;code&gt;M-x slime&lt;/code&gt;. This will start the Clojure REPL using the &lt;code&gt;clj&lt;/code&gt; script with the classpath just how you want it.&lt;br /&gt;&lt;br /&gt;You may also connect to an existing REPL. Start the REPL from the command line using &lt;code&gt;clj&lt;/code&gt;. Once the REPL is up type &lt;code&gt;(swank-server)&lt;/code&gt;. In emacs, type &lt;code&gt;M-x slime-connect&lt;/code&gt;. Emacs will ask about the host and port, press enter twice. &lt;br /&gt;&lt;br /&gt;That's how I do it for now. I am still working on it. Once I get more comfortable using SLIME I will update this post with any improvements I have made. The one improvement that I do want to make is to change my method of testing to fit with &lt;code&gt;clojure-test-mode&lt;/code&gt; so that I can utilize its featues.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4851261502438710182-2803972559453093976?l=formpluslogic.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://formpluslogic.blogspot.com/feeds/2803972559453093976/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://formpluslogic.blogspot.com/2009/09/my-clojure-setup.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4851261502438710182/posts/default/2803972559453093976'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4851261502438710182/posts/default/2803972559453093976'/><link rel='alternate' type='text/html' href='http://formpluslogic.blogspot.com/2009/09/my-clojure-setup.html' title='My Clojure Setup'/><author><name>Brenton Ashworth</name><uri>http://www.blogger.com/profile/13919036386288728360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_nymZllDZetA/Sl5xXNc89zI/AAAAAAAAA28/27f1wAZ9KWo/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4851261502438710182.post-3741223221868990666</id><published>2009-09-07T10:11:00.001-07:00</published><updated>2009-09-08T08:46:08.050-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Unit Testing'/><category scheme='http://www.blogger.com/atom/ns#' term='Clojure'/><title type='text'>Clojure Unit Testing - Part 2</title><content type='html'>This is the second part of an entry on unit testing in Clojure. In the &lt;a href="http://formpluslogic.blogspot.com/2009/08/clojure-unit-testing-part-1.html"&gt;first part&lt;/a&gt; I covered my test setup and how to test private functions. In this part I will show how I set up the database stuff so that I could easily provide alternative database implementations for testing.&lt;br /&gt;&lt;br /&gt;&lt;big&gt;Mocking the database&lt;/big&gt;&lt;br /&gt;&lt;br /&gt;I have a lot of functions that I would like to test that use the database. Here is one example:&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(defn- record-exists?&lt;br /&gt; "Determine if a record exists in the database that is the same as the passed &lt;br /&gt;  spending map. A record is the same if it has the same date, amount and ends &lt;br /&gt;  with the same description.  Records with a description like 'Check 1234' &lt;br /&gt;  can be changed to 'Car Payment - Check 1234' and will still be recognized as &lt;br /&gt;  the same record."&lt;br /&gt; [s]&lt;br /&gt; (let [coll (db/find-in :spending {:date (:date s) :amount (:amount s)})]&lt;br /&gt;   (if (seq coll)&lt;br /&gt;       (if (seq (filter #(. (:description %) endsWith (:description s)) coll)) &lt;br /&gt;           true)&lt;br /&gt;       false)))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Note the use of db/find-in to retrieve data from the database. For testing I will need this function to return predictable results. This function is in the namespace &lt;code&gt;com.formpluslogic.budget.main&lt;/code&gt; which is setup like this:&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(ns com.formpluslogic.budget.main&lt;br /&gt; (:require (com.formpluslogic.budget&lt;br /&gt;             [db_interface :as db :only (save-or-update &lt;br /&gt;                                         find-in &lt;br /&gt;                                         create-budget &lt;br /&gt;                                         create-spending)])))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;code&gt;com.formpluslogic.budget.db_interface&lt;/code&gt; is an interface to the physical database and so relies on a concrete database implementation to do its work. One of the functions in the interface is named &lt;code&gt;find-in&lt;/code&gt;:&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(defn find-in&lt;br /&gt; "Find all items in a table or find items using a query"&lt;br /&gt; ([table] (find-in table {}))&lt;br /&gt; ([table criteria]&lt;br /&gt;   (add-budget-to-coll (map #(assoc % :type table) (*db-find* table criteria)))))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;The physical database implementation is provided by the function &lt;code&gt;*db-find*&lt;/code&gt;. There are four of these functions used by &lt;code&gt;db_interface&lt;/code&gt;: &lt;code&gt;*db-find*, *db-update*, *db-insert* and *db-delete*&lt;/code&gt;. I have an implementation of these functions that interacts with a Derby database but I do not want to hard code this into the interface. Instead I do the following at the top of the &lt;code&gt;db_interface&lt;/code&gt;:&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(defn use-database [ns]&lt;br /&gt; (require ns)&lt;br /&gt; (def *db-find* (ns-resolve (the-ns ns) 'db-find))&lt;br /&gt; (def *db-update* (ns-resolve (the-ns ns) 'db-update))&lt;br /&gt; (def *db-insert* (ns-resolve (the-ns ns) 'db-insert))&lt;br /&gt; (def *db-delete* (ns-resolve (the-ns ns) 'db-delete)))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;When the application starts, the first thing that it needs to do is call &lt;code&gt;use-database&lt;/code&gt; passing the namespace that contains the implementations of the functions. The functions from that namespace are then mapped to vars that are used in the interface. This allows me to easily use one implementation at run time and another during testing.&lt;br /&gt;&lt;br /&gt;&lt;big&gt;Testing printed output&lt;/big&gt;&lt;br /&gt;&lt;br /&gt;Many of the functions that I want to test generate printed output. I want to be able to check the resulting output and I also don't want the output to be displayed along with my test results. Clojure provides &lt;code&gt;with-out-str&lt;/code&gt; for this purpose.&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(defn budget-list [] (db/find-in :budget))&lt;br /&gt;(defn pb&lt;br /&gt; "Print the current budget."&lt;br /&gt; ([] (pb :item))&lt;br /&gt; ([field] (ui/display (sort-by #(field %) (budget-list)))))&lt;br /&gt;&lt;br /&gt;; Test Printing Budget&lt;br /&gt;(def test-pb-result&lt;br /&gt; (str&lt;br /&gt;   "  1                 Auto         200.0\n"&lt;br /&gt;   "  2            Bank Fees          25.0\n"&lt;br /&gt;   "  3            Groceries         500.0\n"&lt;br /&gt;   "                                 725.0\n"&lt;br /&gt;   "Total Count: 3\n"))&lt;br /&gt;&lt;br /&gt;(deftest test-pb&lt;br /&gt;(is (= (with-out-str (main/pb)) test-pb-result)))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;This concludes my description of how I have got around some tricky issues in setting up and performing unit tests in Clojure. I'm still new to Clojure so there may be a better way to do these things. Please let me know what you think.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4851261502438710182-3741223221868990666?l=formpluslogic.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://formpluslogic.blogspot.com/feeds/3741223221868990666/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://formpluslogic.blogspot.com/2009/09/clojure-unit-testing-part-2.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4851261502438710182/posts/default/3741223221868990666'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4851261502438710182/posts/default/3741223221868990666'/><link rel='alternate' type='text/html' href='http://formpluslogic.blogspot.com/2009/09/clojure-unit-testing-part-2.html' title='Clojure Unit Testing - Part 2'/><author><name>Brenton Ashworth</name><uri>http://www.blogger.com/profile/13919036386288728360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_nymZllDZetA/Sl5xXNc89zI/AAAAAAAAA28/27f1wAZ9KWo/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4851261502438710182.post-5915566530684831865</id><published>2009-08-04T08:34:00.001-07:00</published><updated>2009-09-08T08:46:23.912-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Unit Testing'/><category scheme='http://www.blogger.com/atom/ns#' term='Clojure'/><title type='text'>Clojure Unit Testing - Part 1</title><content type='html'>This week I have been writing some Clojure code and starting to think about how to test it. What follows is a description of some of the tricky issues that I am running into while trying to implement a few of these tests and how I solved them.  Please use the comments to give me feedback. This blog entry has got quite long so I will be splitting it into a couple of parts.&lt;br /&gt;&lt;br /&gt;The code I am testing implements a simple budget system for my wife and I. It's fairly small but it will allow me to learn how to do several interesting things with Clojure.&lt;br /&gt;&lt;br /&gt;&lt;big&gt;My test setup&lt;/big&gt;&lt;br /&gt;&lt;br /&gt;I like to keep my tests separate from the code it is testing. In the root directory of my project I have a &lt;code&gt;src&lt;/code&gt; directory and &lt;code&gt;test&lt;/code&gt; directory. In each directory I have namespaces under &lt;code&gt;com.formpluslogic.budget&lt;/code&gt;. For the namespace &lt;code&gt;com.formpluslogic.budget.main&lt;/code&gt; the tests will be in &lt;code&gt;com.formpluslogic.budget.test_main&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;Now that I am organized I'll need an easy way to run all of my tests. I would like to be able to run &lt;code&gt;bin/test&lt;/code&gt; from the root of my project directory and have all of the tests run. To accomplish this I have created two utilities.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;file_utils&lt;/code&gt; contains some functions that help in running tests but may also be useful in other situations.&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(ns com.formpluslogic.util.file_utils&lt;br /&gt;  (:use [clojure.contrib.str-utils :only (re-split re-gsub)])&lt;br /&gt;  (:import (java.io File)))&lt;br /&gt;&lt;br /&gt;(defn remove-file-ext [file-name]&lt;br /&gt;  (let [index (.lastIndexOf file-name ".")]&lt;br /&gt;    (apply str (first (split-at index file-name)))))&lt;br /&gt;&lt;br /&gt;(defn file-to-ns-string [f root-dir]&lt;br /&gt;  (let [f-sep File/separator&lt;br /&gt;        td-p (re-pattern (str f-sep root-dir f-sep))]&lt;br /&gt;    (re-gsub (re-pattern f-sep) "."&lt;br /&gt;      (remove-file-ext&lt;br /&gt;        (last (re-split td-p (.getAbsolutePath f)))))))&lt;br /&gt;&lt;br /&gt;(defn file-seq-map-filter [dir mf ff]&lt;br /&gt;  (filter ff (map mf (file-seq (File. dir)))))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;code&gt;run_tests&lt;/code&gt; will run all of the tests that are found under the test directory.&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(ns com.formpluslogic.util.run_tests&lt;br /&gt;  (:use [clojure.test :only (run-tests)]&lt;br /&gt;        [com.formpluslogic.util.file_utils]))&lt;br /&gt;&lt;br /&gt;(def test-dir "test")&lt;br /&gt;(def test-file-prefix "test_")&lt;br /&gt;(def test-file-ext ".clj")&lt;br /&gt;&lt;br /&gt;(defn- is-test-file? [file-info]&lt;br /&gt;  (let [file-name (first file-info)&lt;br /&gt;        re-s (str test-file-prefix ".*" test-file-ext)&lt;br /&gt;        re-p (re-pattern re-s)]&lt;br /&gt;    (re-matches re-p file-name)))&lt;br /&gt;            &lt;br /&gt;(defn- get-file-info [f]&lt;br /&gt;  [(.getName f) (file-to-ns-string f test-dir)])&lt;br /&gt;                    &lt;br /&gt;(def test-namespaces&lt;br /&gt;  (map #(symbol (last %))&lt;br /&gt;    (file-seq-map-filter test-dir &lt;br /&gt;                         get-file-info &lt;br /&gt;                         is-test-file?)))&lt;br /&gt;    &lt;br /&gt;(defn run&lt;br /&gt;  "Runs all defined tests"&lt;br /&gt;  []&lt;br /&gt;  (println "Loading tests...")&lt;br /&gt;  (apply require :reload-all test-namespaces)&lt;br /&gt;  (time (apply run-tests test-namespaces)))&lt;br /&gt;&lt;br /&gt;(run)&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;I started with code that I found in &lt;code&gt;clojure.contrib&lt;/code&gt; and made a couple of modifications. The &lt;code&gt;run&lt;/code&gt; function should be called from the root directory of the project. It will search the &lt;code&gt;test&lt;/code&gt; directory for test namespaces and run them. All I need to do to add new tests is create new test files that start with "test_".&lt;br /&gt;&lt;br /&gt;Finally I created a script in the &lt;code&gt;bin&lt;/code&gt; directory named &lt;code&gt;test&lt;/code&gt; that will run the &lt;code&gt;run_tests&lt;/code&gt; file.&lt;br /&gt;&lt;br /&gt;Now that I have an easy, low maintenance way to run my tests, I can start writing them.&lt;br /&gt;&lt;br /&gt;&lt;big&gt;Testing private functions&lt;/big&gt;&lt;br /&gt;&lt;br /&gt;The first function that I chose to test was private. So how do you test private functions? After some research I found some possible solutions on the &lt;a href="http://groups.google.com/group/clojure/browse_thread/thread/3835e5405ab930f6/"&gt;Clojure group&lt;/a&gt;. I went with the following approach.&lt;br /&gt;&lt;br /&gt;Here is the private function which is located in the &lt;code&gt;com.formpluslogic.budget.derby&lt;/code&gt; namespace.&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(defn- split-criteria&lt;br /&gt;  "Create a sequence where the first element is the vector&lt;br /&gt;   of keys and the remaining elements are the values"&lt;br /&gt;  [criteria]&lt;br /&gt;  (cons (vec (keys criteria)) (vals criteria)))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;My tests are in &lt;code&gt;com.formpluslogic.budget.test_derby&lt;/code&gt; which is why I cannot directly access the private function. I use &lt;code&gt;ns-resolve&lt;/code&gt; to map the function to a var in the &lt;code&gt;com.formpluslogic.budget.test_derby&lt;/code&gt; namespace.&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(def split-criteria &lt;br /&gt;  (ns-resolve 'com.formpluslogic.budget.derby &lt;br /&gt;              'split-criteria)) &lt;br /&gt;(deftest test-split-criteria&lt;br /&gt;  (is (= (split-criteria {:id 1}) (list [:id] 1)))&lt;br /&gt;  (is (= (split-criteria {:id 1 :name "John"})&lt;br /&gt;         (list [:id :name] 1 "John"))))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;What do you think about this? Is there are better way?&lt;br /&gt;&lt;br /&gt;&lt;big&gt;Mocking the database and testing printed output&lt;/big&gt;&lt;br /&gt;&lt;br /&gt;This application uses a database to store information on disk. When testing, I want to be able to run my tests without using the rdms that I am using for functional and integration testing. I also want to make it easy to use a different database implementation. At the moment I am using Apache Derby. In my next post I will show how I set this up as well as how to test printed output.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4851261502438710182-5915566530684831865?l=formpluslogic.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://formpluslogic.blogspot.com/feeds/5915566530684831865/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://formpluslogic.blogspot.com/2009/08/clojure-unit-testing-part-1.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4851261502438710182/posts/default/5915566530684831865'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4851261502438710182/posts/default/5915566530684831865'/><link rel='alternate' type='text/html' href='http://formpluslogic.blogspot.com/2009/08/clojure-unit-testing-part-1.html' title='Clojure Unit Testing - Part 1'/><author><name>Brenton Ashworth</name><uri>http://www.blogger.com/profile/13919036386288728360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_nymZllDZetA/Sl5xXNc89zI/AAAAAAAAA28/27f1wAZ9KWo/S220/me.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4851261502438710182.post-6846926175875518275</id><published>2009-07-24T14:54:00.000-07:00</published><updated>2009-12-09T13:47:37.175-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Concurrency'/><category scheme='http://www.blogger.com/atom/ns#' term='Clojure'/><title type='text'>Clojure Concurrency - Part 1</title><content type='html'>As I continue to slowly go through my copy of "On Lisp" I have come across another interesting piece of example code on page 18 in the section on closures. It illustrates some interesting ideas from functional programming in general and also some very cool Clojure specific ways of dealing with mutable state and concurrency. The Common Lisp version of the code is shown below.&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(let ((counter 0))&lt;br /&gt;  (defun new-id ()   (incf counter))&lt;br /&gt;  (defun reset-id () (setq counter 0)))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Two "functions" are produced that share a counter variable. Each call to &lt;code&gt;new-id&lt;/code&gt; will increment the counter. A call to &lt;code&gt;reset-id&lt;/code&gt; will reset the counter to 0. Notice that I quoted the word "functions". These are not pure functions because they have side effects (mutable state) and do not always produce the same result when called with the same arguments. But that is what makes them interesting. This code produces something that is kind of like an object. It has private state that can only be modified using the interface that it provides. I am eager to see other ways that this construct is used as I continue through the book.&lt;br /&gt;&lt;br /&gt;Clojure does not allow you to write code like that shown above. All data is immutable in Clojure so you cannot create a variable and then change its value. That's not totally true. One version of this code ported to Clojure is shown below. This implementation was taken from &lt;a href="http://blog.fogus.me/2008/09/26/on-lisp-clojure-chapter-2/"&gt;Fogus'&lt;/a&gt; blog.&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(let [counter (to-array [0])]&lt;br /&gt;  (defn new-id [] (aset counter 0 (inc (aget counter 0))))&lt;br /&gt;  (defn reset-id [] (aset counter 0 0)))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;This code uses Clojure's Java roots to create the mutable state. The &lt;code&gt;(to-array [0])&lt;/code&gt; call creates a Java array. This allows you to change the value in the array without changing the counter itself. This is a trick to accomplish the same thing as the code above. Because Clojure allows integration with Java, you will always be able to do this kind of thing. This codes works. Or does it? Let's write some code to test it.&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(defn make-100-ids [id-fun]&lt;br /&gt;  (doall (take 100 (repeatedly id-fun))))&lt;br /&gt;&lt;br /&gt;(defn test-c [nthreads id-fun]&lt;br /&gt;  (reset-id)&lt;br /&gt;  (apply max (apply concat&lt;br /&gt;    (apply pcalls (repeat nthreads #(make-100-ids id-fun))))))&lt;br /&gt;&lt;br /&gt;(test-c 100 new-id)&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;The function &lt;code&gt;make-100-ids&lt;/code&gt; will call the &lt;code&gt;id-fun&lt;/code&gt; 100 times creating 100 new ids. The &lt;code&gt;test-c&lt;/code&gt; function will create any number of threads and each thread will concurrently create 100 ids. It will return the highest id that is created. In the last bit of code we call &lt;code&gt;test-c&lt;/code&gt; and ask it to create 100 threads using the &lt;code&gt;new-id&lt;/code&gt; function. What should we expect to happen? If 100 threads create 100 ids then highest id should be 10000.&lt;br /&gt;&lt;br /&gt;If you run this test using the Clojure implementation above you may not get 10000. When I ran this code I got 9785. This means that somewhere along the way more than one thread is getting the same id returned from &lt;code&gt;new-id&lt;/code&gt;. The same thing would happen if we tested the Common Lisp version above. These functions are not thread-safe. Clojure gives us a set of tools to make writing thread-safe code easy.&lt;br /&gt;&lt;br /&gt;Below I have created a new version of this code that uses refs to manage the mutable state.&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(let [counter (ref 0)]&lt;br /&gt;  (defn new-id [] (dosync (ref-set counter (inc @counter))))&lt;br /&gt;  (defn reset-id [] (dosync (ref-set counter 0))))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;This still looks more complex than the Common Lisp version and also looks like it has about the same amount of code as the previous Clojure version. So why is this better? It is more complex but that is because it is doing a lot more. Instead of just setting the counter to 0 we set it to a ref which has a value of 0. refs can only be changed within a transaction so we have to surround the code that changes the ref with &lt;code&gt;dosync&lt;/code&gt;. This is enforced by Clojure. If you try to change the ref outside of a transaction you will receive an error message. Within &lt;code&gt;dosync&lt;/code&gt; the value of the ref will not be altered by any other thread. Within &lt;code&gt;dosync&lt;/code&gt; you will always see a consistent view of all your refs. If you think of &lt;code&gt;dosync&lt;/code&gt; like a database transaction you will not be far off. &lt;a href="http://clojure.org/refs"&gt;The documentation on the Clojure site regarding refs&lt;/a&gt; is very good and will explain in detail what refs do for you. I will not repeat that here.&lt;br /&gt;&lt;br /&gt;If we run this same test using this new Clojure version we get the correct answer every time.&lt;br /&gt;&lt;br /&gt;&lt;big&gt;Update&lt;/big&gt;&lt;br /&gt;&lt;br /&gt;As Erik points out in the first comment, a better way to write this code would have been to use an &lt;code&gt;atom&lt;/code&gt; instead of using &lt;code&gt;ref&lt;/code&gt; and &lt;code&gt;dosync&lt;/code&gt;. The code is smaller and it runs faster. See comment below. &lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(let [counter (atom 0)]&lt;br /&gt;  (defn new-id [] (swap! counter inc))&lt;br /&gt;  (defn reset-id [] (reset! counter 0)))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4851261502438710182-6846926175875518275?l=formpluslogic.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://formpluslogic.blogspot.com/feeds/6846926175875518275/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://formpluslogic.blogspot.com/2009/07/clojure-concurrency-part-1.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4851261502438710182/posts/default/6846926175875518275'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4851261502438710182/posts/default/6846926175875518275'/><link rel='alternate' type='text/html' href='http://formpluslogic.blogspot.com/2009/07/clojure-concurrency-part-1.html' title='Clojure Concurrency - Part 1'/><author><name>Brenton Ashworth</name><uri>http://www.blogger.com/profile/13919036386288728360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_nymZllDZetA/Sl5xXNc89zI/AAAAAAAAA28/27f1wAZ9KWo/S220/me.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4851261502438710182.post-3894422509203127447</id><published>2009-07-16T17:00:00.000-07:00</published><updated>2009-08-04T11:42:14.103-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Clojure'/><category scheme='http://www.blogger.com/atom/ns#' term='On Lisp'/><title type='text'>Clojure lazy-seq and Recursion</title><content type='html'>Finishing Stuart Halloway's excellent book, "Programming Clojure", has renewed my interest in functional programming. It has also made me realize how much I am wired to think in terms of imperative solutions to problems. I need to delve a little deeper into the mysterious world of functional programming. Therefore, my next reading project will be to go through "On Lisp" while following &lt;a href="http://blog.fogus.me/2008/09/26/on-lisp-clojure-chapter-2/"&gt;Fogus'&lt;/a&gt; and &lt;a href="http://blog.thinkrelevance.com/2008/12/12/on-lisp-clojure"&gt;Stuart's&lt;/a&gt; blogs where they port example code to Clojure.&lt;br /&gt;&lt;br /&gt;This is day one and my effort has already been fruitful. Today I had to confront the &lt;code&gt;lazy-seq&lt;/code&gt; macro.&lt;br /&gt;&lt;br /&gt;On page 15 in my version of "On Lisp" is the &lt;code&gt;our-remove-if&lt;/code&gt; function which is equivalent to &lt;code&gt;remove&lt;/code&gt; in Clojure. Below is the Fogus port to Clojure with one small modification (using &lt;code&gt;lazy-seq&lt;/code&gt; instead of &lt;code&gt;lazy-cons&lt;/code&gt; which has been removed from Clojure).&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;1 (defn remove-if [f lst]&lt;br /&gt;2  (if (seq lst) ; idiomatic&lt;br /&gt;3   (if (f (first lst))&lt;br /&gt;4      (recur f (rest lst))&lt;br /&gt;5      (lazy-seq (cons (first lst) (remove-if f (rest lst)))))&lt;br /&gt;6  nil))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;This code will work with any size data set. Let's go through this line by line and pay special attention when we get to line 5.&lt;br /&gt;&lt;br /&gt;In line 2 we use &lt;code&gt;(seq lst)&lt;/code&gt; to determine if the list is empty. If it is then we return nil on line 6 otherwise we evaluate line 3. &lt;code&gt;(seq lst)&lt;/code&gt; will return nil if the list is empty.&lt;br /&gt;&lt;br /&gt;On line 3 we determine if the first element in the list is something that we want to remove. If it is then we remove it on line 4 by calling &lt;code&gt;(recur f (rest lst))&lt;/code&gt;. This is a recursive call of the &lt;code&gt;remove-if&lt;/code&gt; function. Why not just use &lt;code&gt;(remove-if f (rest lst))&lt;/code&gt;? Clojure does not automatically do tail-call optimization. You have to be explicit and use &lt;code&gt;recur&lt;/code&gt; which will allow you to recursively call the function without consuming stack frames with each call. For this to work (and compile) the call to &lt;code&gt;recur&lt;/code&gt; has to be in tail position meaning that no executable code appears after the call to &lt;code&gt;recur&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;If we are not going to remove the first element then we need to do something like this&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(cons (first lst) (remove-if f (rest lst)))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;This is basic recursion. We want to create a new list composed of the first item and the result of processing the rest of the list with &lt;code&gt;remove-if&lt;/code&gt;. Unfortunately this code will not work with large lists. We will eventually use all of the available stack frames. We also cannot use &lt;code&gt;recur&lt;/code&gt; here because it would not be in tail position. &lt;code&gt;cons&lt;/code&gt; creates a list from the first element and the result of the recursive call. It's stack frame needs to stick around until that recursive call completes. What to do. What to do...&lt;br /&gt;&lt;br /&gt;We need to make one simple change to make this work. Wrap the above code in a &lt;code&gt;lazy-seq&lt;/code&gt;.&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(lazy-seq (cons (first lst) (remove-if f (rest lst))))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;It does work. But why and how does it work? This was hard for me to understand only because I come from a non-functional (or maybe it's dysfunctional) background.&lt;br /&gt;&lt;br /&gt;When we make a call to &lt;code&gt;remove-if&lt;/code&gt; we don't get a list, we get a function that can create the list, but only if and when we need it. &lt;code&gt;lazy-seq&lt;/code&gt; creates a logical sequence but does not execute any of the code in its body until it has to. Imagine calling &lt;code&gt;remove-if&lt;/code&gt; with a list where all of the items will be retained, it will immediately, without performing any recursive calls, return a lazy sequence (a function enclosing all of the state of the call to &lt;code&gt;remove-if&lt;/code&gt;). As we start to actually consume this sequence it will evaluate its body which will return a sequence where &lt;code&gt;first&lt;/code&gt; is the first item in the list and &lt;code&gt;rest&lt;/code&gt; is another lazy sequence (function) which has not been evaluated. Each call to &lt;code&gt;remove-if&lt;/code&gt; will immediately return without performing a recursive call.&lt;br /&gt;&lt;br /&gt;I think that one of the things that can be confusing here is that when you execute this code in the REPL it will print the resulting list. This may cause you to think that the list is actually being created when you call the function. In reality, the REPL is forcing the result list to be actualized in the process of printing it.&lt;br /&gt;&lt;br /&gt;Hopefully this information will be helpful to anyone who is struggling with &lt;code&gt;lazy-seq&lt;/code&gt;, especially when trying to understand how it relates to recursion.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4851261502438710182-3894422509203127447?l=formpluslogic.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://formpluslogic.blogspot.com/feeds/3894422509203127447/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://formpluslogic.blogspot.com/2009/07/clojure-lazy-seq-and-recursion.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4851261502438710182/posts/default/3894422509203127447'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4851261502438710182/posts/default/3894422509203127447'/><link rel='alternate' type='text/html' href='http://formpluslogic.blogspot.com/2009/07/clojure-lazy-seq-and-recursion.html' title='Clojure lazy-seq and Recursion'/><author><name>Brenton Ashworth</name><uri>http://www.blogger.com/profile/13919036386288728360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_nymZllDZetA/Sl5xXNc89zI/AAAAAAAAA28/27f1wAZ9KWo/S220/me.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4851261502438710182.post-2509372976479665367</id><published>2009-07-14T09:54:00.001-07:00</published><updated>2009-08-04T11:43:19.628-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Clojure'/><title type='text'>Using the Clojure -&gt; Macro</title><content type='html'>Today I started going through the Clojure api reviewing everything up to the letter "a". Everything in this section was straight forward except for this one&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;(-&gt; x form)&lt;br /&gt;(-&gt; x form &amp;amp; more)&lt;br /&gt;&lt;br /&gt;Threads the expr through the forms. Inserts x as the second &lt;br /&gt;item in the first form, making a list of it if it is not a &lt;br /&gt;list already. If there are more forms, inserts the first form &lt;br /&gt;as the second item in second form, etc.&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;I had seen this used in the ants.clj example and did not understand it. The description here also did not make it clear (because of my inexperience with Clojure) so I did an experiment in the REPL:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;user=&gt; (-&gt; 2 (* 2))&lt;br /&gt;4&lt;br /&gt;user=&gt; (-&gt; 2 (* 2) (+ 3))&lt;br /&gt;7&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;As you can see from the second example above the expr 2 is passed as the second item to the first form (* 2) which results in evaluating (* 2 2) which results in 4. The result is then passed as the second item to (+ 3) etc.&lt;br /&gt;&lt;br /&gt;To see the advantage of this, what would we have to do if we didn't have this marco.&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;user=&gt; (* 2 2)&lt;br /&gt;4&lt;br /&gt;user=&gt; (+ (* 2 2) 3)&lt;br /&gt;7&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;In the first example you would not use &lt;code&gt;-&gt;&lt;/code&gt; because the normal way of doing this is clearer. In the second example you can start to see the benefit. These are very simple examples and perhaps arithmetic is not the best way to show its use. Let's look at two slightly more complex examples.&lt;br /&gt;&lt;br /&gt;In the ants.clj example, some code that uses this macro is&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(defn place [[x y]]&lt;br /&gt;   (-&gt; world (nth x) (nth y)))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Here we are trying to get a cell from the world which is a 2d vector. How would this look without &lt;code&gt;-&gt;&lt;/code&gt;?&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(defn place [[x y]]&lt;br /&gt;   (nth (nth world x) y))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Another good example involves getting data from nested maps. Suppose you have a map that looks like this&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(def m {:type "Car" &lt;br /&gt;        :owner {:name "John" :age 27 &lt;br /&gt;                :parents {:mother {:name "Jane" :age 53} &lt;br /&gt;                          :father {:name "William" :age 56}}}})&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;If you want to get the name of the father of the car's owner you have to work your way from the inside out.&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(:name (:father (:parents (:owner m))))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Or you can use &lt;code&gt;-&gt;&lt;/code&gt; to work in the other direction.&lt;br /&gt;&lt;pre&gt;&lt;code class="clojure"&gt;&lt;br /&gt;(-&gt; m :owner :parents :father :name)&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;To me, the second version is much easier to write.&lt;br /&gt;&lt;br /&gt;Hopefully this clears up your understanding of the &lt;code&gt;-&gt;&lt;/code&gt; macro and also gives an example of the power of macros to allow you to improve the clarity of your code (please also note that the abuse of macros can greatly obscure your code).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4851261502438710182-2509372976479665367?l=formpluslogic.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://formpluslogic.blogspot.com/feeds/2509372976479665367/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://formpluslogic.blogspot.com/2009/07/using-clojure-macro.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4851261502438710182/posts/default/2509372976479665367'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4851261502438710182/posts/default/2509372976479665367'/><link rel='alternate' type='text/html' href='http://formpluslogic.blogspot.com/2009/07/using-clojure-macro.html' title='Using the Clojure -&gt; Macro'/><author><name>Brenton Ashworth</name><uri>http://www.blogger.com/profile/13919036386288728360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_nymZllDZetA/Sl5xXNc89zI/AAAAAAAAA28/27f1wAZ9KWo/S220/me.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4851261502438710182.post-1986960084287467017</id><published>2009-07-14T09:16:00.000-07:00</published><updated>2009-07-30T09:52:50.910-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Clojure'/><title type='text'>Learning Clojure</title><content type='html'>I have recently decided to focus my attention on learning Clojure. Over the past eight years most of my code has been written in Java. Recently I have started to use Groovy quite a bit. After spending the last year researching several languages including Groovy, Erlang, Ruby, Scala and Clojure I have decided that I want to invest my valuable time and energy into Clojure. In a future blog post I will give my reasoning behind this decision.&lt;br /&gt;&lt;br /&gt;My plan of attack is to first read the "Programming Clojure" book, which I have done. I will then attempt to become more familiar with functional programming in general by reading "On Lisp", "Practical Common Lisp" and "Real World Haskell". Next I want to go through the &lt;a href="http://clojure.org/"&gt;Clojure web site&lt;/a&gt; and familiarize myself with the &lt;a href="http://clojure.org/api"&gt;api&lt;/a&gt;.  Finally (because you can't learn without writing code) I will try to port the core part of one of my major projects to Clojure as a learning experience. If it goes well then I will put it into production. If not then I will have learned many valuable lessons.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4851261502438710182-1986960084287467017?l=formpluslogic.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://formpluslogic.blogspot.com/feeds/1986960084287467017/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://formpluslogic.blogspot.com/2009/07/learning-clojure.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4851261502438710182/posts/default/1986960084287467017'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4851261502438710182/posts/default/1986960084287467017'/><link rel='alternate' type='text/html' href='http://formpluslogic.blogspot.com/2009/07/learning-clojure.html' title='Learning Clojure'/><author><name>Brenton Ashworth</name><uri>http://www.blogger.com/profile/13919036386288728360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_nymZllDZetA/Sl5xXNc89zI/AAAAAAAAA28/27f1wAZ9KWo/S220/me.jpg'/></author><thr:total>0</thr:total></entry></feed>
