Thursday, October 27, 2011

Getting Started with Clojure-clr

Update: All github ClojureCLR links have been updated to use the new repository at github.com/clojure/clojure-clr

After taking the summer off from blogging to spend time with the family, I am ready to get back to my blog. My first post of the ‘fall blogging season’ is a brief intro Clojure-clr. In this post I will walk you though getting clojure-clr installed, show you how to interact with the REPL and compile an application.

The Goal

By the end of this post I will be able to interact with .NET assemblies from the clojure-clr REPL and be able to compile a basic clojure-clr application from the command line.

The Setup

The first thing to do is to visit the Download Page of the Clojure-clr project on github. I chose to install the clojure-clr-1.3.0-Debug-4.0zip version. Once you have downloaded a version follow these instructions Getting started binary distribution page. Make sure to ‘Unblock’ the zip file before you unzip it. Failure to do so will cause exceptions to be thrown every time you try to run any of the executables or use any of the DLLs in the zip file. For ease of use I added the directory I extracted the files to into my PATH environment variable.

The REPL

Next, I started up cmd.exe and typed: clojure.main.exe . This will start up the REPL. If everything goes right you should see something similar to this image below.

image

The version number you see will be determined by the version you downloaded. Now that we have the REPL up and running lets take try some clojure code.  At the prompt enter:  (println “yep, it worked!”)  and press the enter key.  That should give you:

image

Ok, the ‘normal’ clojure seems to be working, now its time to try interacting with .NET.

Interacting with .NET

Now that we know we have the REPL working it is time to try out a few calls into the .NET world.  The first call we will make is to Console.WriteLine.  Since System.Console is loaded automatically by the REPL we can call it like this: 

(System.Console/WriteLine “I just called a .NET method!”)

image

It works the same as the println call did.  What if you want to interact with a .NET lib that hasn’t already been loaded into our namespace by the REPL?  There are a couple of ways to do it one takes a lot of typing and the other takes about half the amount.  To illustrate I will load the System.Windows.Forms assembly and load the MessageBox class. The verbose way to load a library is to call the Assembly.Load method:

(System.Reflection.Assembly/Load "System.Windows.Forms,
Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")

When you hit enter after typing the above code in you should see this:

image

The second way to load a .NET assembly takes far less typing.  It makes use of the Assembly/LoadWithPartialName method.  Here’s what it looks like:

(System.Reflection.Assembly/LoadWithPartialName "System.Windows.Forms")

The results of this call will give you the same output as the more verbose Load call did.  Either way you choose will work fine.  If loading a particular version of a an assembly is crucial then I would go with the Load call.  Otherwise I would stick with the LoadWithPartialName method. 

Now that we have loaded System.Windows.Forms I’m going to include it into our namespace so I can use the MessageBox class so I can make calls into it a little cleaner.  I can do that by typing the following in the REPL

(import (System.Windows.Forms MessageBox))

The call above tells the REPL we want to bring the System.Windows.Forms.MessageBox into our user namespace.  This will allow us to use MessageBox/Show instead of System.Windows.Forms.MessageBox/Show.   When entered the line of code below I saw the dialog box that follows it. Pretty straight forward.

(MessageBox/Show “Hi from clojure-clr!” “Clojure-CLR Dialog”)

image

Now that I’ve shown you how to make a call into .NET from the REPL let’s compile a clojure-clr ‘application’. 

Compiling a Clojure-clr Application

For our example I will create an ‘application’ that consists of all the code that we entered into the REPL above in a file called intro.clj .  After you have downloaded the file, change into the directory where it was saved.  Then run:

clojure.compile intro

The compile command will create the following files in the same directory where the clojure.compile.exe file lives.  image

I haven’t found out how to tell the compiler where to put the output yet so for now I just run them from that directory.  (If you know how to tell the compiler where to put the output please leave a comment below.  I would really appreciate it!)

Running the intro.exe file will produce the println, Console.Writeln, and MessageBox.Show output just as it was in the REPL.

Summary

That’s it for my very brief intro into the world of clojure on the CLR.  I walked you through using the REPL to call ‘normal’ clojure and how to interact with .NET.  I also showed you how to compile a clojure-clr application on the command line.

In future clojure-clr posts I will convert my hugo project posts (Parsing Web Pages with Clojure and Enlive, Creating Hugo Awards DB-with Clojure, and Creating a Simple UI for the Hugo Awards DB) to hugo-clr using the .NET equivalents.  Plus I plan on having a post or two on how to use the clojure-clr assemblies in a C# application.