A Lazy Sequence

Welcome to Andrew Brehaut's unvarnished site. I'm a freelance software and web developer, coffee snob and all round geek from Hamilton, New Zealand.

Popular articles on A Lazy Sequence: A Brief Overview of the Clojure Web Stack, Start Parsing in Clojure: fnparse

23 Jan

MetaWeblog API with Clojure

I've added a recipe for implementing a basic MetaWeblog server endpoint in Clojure to the necessary-evil github wiki. It's bare bones and uses a dummy store that does the bare minimum. Because so much of the detail of MetaWeblog is dependant on the backend and model you use, it's not much more than the public interface.
20 Jan

Configuration Middleware

When you are developing a web application in Clojure, there are likely to be libraries (such as database access libs) that require configuration such as connection information to be provided. If the library provides a way to dynamically bind the configuration data, we can use Ring middleware to simplify our applications. I assume you already know about Ring. I’m going to use Moustache for my routes here, by the principle applies to Compojure – and presumably noir – as well. For a database library I’ll show an example using Clutch (the Clojure CouchDB api), again this also applies to other libraries.

Lets imagine a simple moustache app:

(def my-app 
    [] (delegate home)
    [slug] (delegate page slug))

In this example, home and page do some lookups into a CouchDB database, and return some html, for example:

(use '[ring.util.response :only [response]]
    '[com.ashafa.clutch :only [with-db get-view]])

(defn get-page-from-db
    [slug]
    (-> (with-db "example-db" (get-view "site" :page {:key slug}))
                 first
                 :content))    

(defn get-page-from-db-2
    [slug]
    (-> (get-view "example-db" "site" :page {:key slug})
        first
        :content))

(defn page 
    [req slug]
    (response (get-page-from-db slug)))

This simplified handler and database access function (and its variant) highlight the problem: the connection information (in this case just the string "example-db") is coupled with the code the does the request. Newer Clojure programmers may try hoisting the (with-db …) above the defns but this doesn’t work due to the binding semantics of dynamic scopes.

Ring middleware presents an answer to this problem. If we create a middleware that will set the (with-db …) for us on each request, then hoist the definition out of the data access code and specify it only once. Here is an example:

(defn clutch-with-db
  "Wraps the routes in a clutch with-db binding"
  [app database]
  (ƒ [req]
    (com.ashafa.clutch/with-db database (app req))))

(def my-app2
   (app 
     (clutch-with-db "example-db")

     [] (delegate home)
     [slug] (delegate page slug)))

Easy!

In addition to hoisting the configuration out of the data access code, we can now trivially use a different database for two sub apps that use the same app definition but accesses a different database, in this case two blogs: one with serious content, and another with humorous cats:

(def simple-blog (app …))

(def blogs 
    (app 
       ["funny-cats" &] (clutch-with-db simple-blog "cats-blog")
       [&] (clutch-with-db simple-blog "serious-blog")))

Finally, this also means you can write test harnesses that work off separate databases without fear.

12 Jan

ClojureScript One

Clojure/core have released a guide and sample project for producing web applications based on Clojure and ClojureScript. As a bonus the project is an excellent example of using Marginalia for documentation.
11 Jan

Matt Gemmell on the blog comments.


Matt Gemmell recently kicked the discussion around blog comments back to life, first by disabling comments on his own site and then by posting a short followup piece. He has now compiled a comprehensive set of the responses to his initial post. The cloud of discussion around this issue has generated a broad range of points of view that are worth the time to read.

I discarded comments here on A Lazy Sequence back in 2009 and have no regrets. I have found that Twitter, Hacker News, and Reddit provide much better forums for discussing articles I have posted than I could have provided here.

05 Jan

Fiction (Read Recently)

A brief summary of some the fiction I have read recently:

Stephen King

  • Cujo. A relatively short King book without overt supernatural elements. It maintains suspense better than a lot of his other books. This, along with books 4 and 5 of the Dark Tower are my favorite of Kings books that I have read.
  • The Tommyknockers. A massive King tome with a lot of his typical small-town-in-Maine-goes-to-hell tropes spun from the stock of B-Movie sci-fi and H.P. Lovecraft’s The Colour out of Space. Enjoyable but nothing amazing.
  • The Dark Tower. I finished the last three books of this spaghetti western fantasy. Overall I enjoyed the series, but it is certainly uneven and more than a bit chaotic. I did enjoy the ending.

Tim Powers

I’ve recently discovered Powers, and have really enjoyed the three books I’ve read. He has a fairly clear formula with his secret history approach. He has a couple of tropes that some readers might find annoying, especially with respect to his main protagonist and that characters relationship with the main female character. The stories are very plot and action driven.

  • Declare. This is an excellent World War 2 and Cold War spy thriller with magic tangled around the real history and people. Of the three Power’s books I’ve read, this is probably the best. In particular, Andrew Hale is a better developed character than the protagonists of the other two I have read.
  • The Anubis Gates. A fantastical timetravelling romp centering on 1800s London that starts slow but doesn’t slow down once its moving.
  • Last Call. Powers doing a Gaimen-esq modern fantasy set in Las Vegas.

05 Jan

Mercury

Mercury is a statically typed Logical programming language. It's type system includes agebraic data types, “modes” (whether an predicates parameters may be inputs or outputs), and definitions of the determinism a predicate provides (the number of values it generates on outputs).