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.

Gravatar Aaron Fischer Wednesday, August 17, 2011
How would this compare to F#?
Gravatar scott Wednesday, August 17, 2011
@Aaron: lots of similarities, I think. Both are functional, both have immutable data structures, both offer easy async and concurrent operations.

I think the primary differences (other than syntax) would be that Clojure is dynamic, offers transactional memory, and runs on both the CLR and the JVM.
Neyah Wednesday, August 17, 2011
Can you check your blog css? The link hover color of white combined with the faint yellow background makes the link text impossible to read when hovering. At least for me.
Gravatar Doeke Thursday, August 18, 2011
Why does a language, that uses polish notation (+ 3 2 instead of 3+2) still need an overuse of brackets?
Gravatar scott Thursday, August 18, 2011
@Doeke: Will fix this weekend. Thanks!
Gravatar Blaise Pascal Sunday, August 21, 2011
Why does a language, that uses polish notation (+ 3 2 instead of 3+2) still need an overuse of brackets?

Two reasons: syntactic consistency and variable arity.

Polish notation does not need parenthesis as long as every operator is of known arity. In lisps, the arity of many functions (including +) is variable, so there is no way to know, without the functional equivalent to parenthesis, to know when the arguments to a function are complete. So parenthesis are at least sometimes necessary.

Syntactic consistency ensures that they are always used and never optional. It makes it real easy to parse, and it isn't that hard to get used to them with a little exposure.
Comments are closed.