OdeToCode IC Logo

Clojure and the CLR

Tuesday, August 16, 2011

From the Clojure home page:

Clojure is a dialect of Lisp, and shares with Lisp the code-as-data philosophy and a powerful macro system. Clojure is predominantly a functional programming language, and features a rich set of immutable, persistent data structures. When mutable state is needed, Clojure offers a software transactional memory system and reactive Agent system that ensure clean, correct, multithreaded designs.

I’ve had an interest in Clojure ever since I saw Craig Andera do a talk on the topic in D.C. (Craig also has a set of Clojure videos @ Pluralsight). It was just an intellectual fascination until clojure-clr appeared and things took a turn towards the possibly practical.

Why Am I Interested in Clojure?

As a dialect of Lisp, Clojure embodies the spirit of the greatest single programming language ever designed, including the parentheses, prefix notation, and a simple, clutter-free syntax.

Clojure C#
; Comparing 5 and 3+2 returns 0
(println (compare 5 (+ 3 2)))
// Comparing 5 and 3+2 returns 0
Console.WriteLine(5.CompareTo(2 + 3));

Functions are first class citizens in Clojure, of course, so you can pass functions as parameters and return them as the result of other functions. There are closures, currying, and recursive looping. Fans of LINQ and functional programming with Func<> and Action<> on the CLR should know that you won’t be missing anything with Clojure, in fact, there is a whole new world to explore.

Clojure C#
(take 2 (reverse 
  (filter (fn [s] (= \L (first s))) 
    ["Minnesota", "Detroit", "London", "Las Vegas"] )))
var places = new string[] 
    { "Minnesota", "Detroit", 
       "London", "Las Vegas" }
    .Where(s => s.First() == 'L')

Also, like any LISP, the compiler offers extensibility through macros. Program code is data you can evaluate or manipulate. However, the hallmark of Clojure is the inherent support for safe and simple concurrency. I plan on using Clojure in some data analysis work, and we'll explore interop and threading in a future post.