Tuesday, January 25, 2011

Install Clojure on Windows

I'm not a big fan of the Microsoft platform. I'm not a hater either, though in a binary world I would probably be the second. Luckily enough we have some degree of fuzziness which makes life more fun (besides, I think that programmers in a binary world would feel perfectly comfortable with directly writing opcodes, possibly directly using a magnet on a hard disk, so no Lisp at all).

For a very long list of reasons (which is so long that it would deserve a post on its own, provided that someone but me cared) I'm using windows a lot at work. This has something to do with my macbook having a broken hard disk and me being lazier than a Haskell interpreted with a Haskell interpreter. Anyway...

HasOffice - {Mac} = {Windows}

So... and I'm a lot into experimenting new technologies. My new found subject of experimentation is clojure: after at least an year I'm planning to start using it for some real world apps, eventually the time has come. And unfortunately I have to do it in an hostile environment. I usually find easier to try new stuff on the Mac or on some other Linux systems. I'm more at ease with the OS and usually developers tested and developed the thing on a system rather similar. Especially the installation stages are troublesome, as a working compiler is often assumed present (and usually it should be gcc).

On the other hand Clojure lives in a Java environment. Essentially it follows different rules from this point of view. The runtime is a jar, altready compiled. My IDE just downloads it and things work. I also have clojure box and things work out of the box (a part from a very strange bug which freezes the whole Emacs). Amazingly enough, some years ago I had some troubles with using it CLI on the mac (I think it was version 1.0 and something in the internal class structure changed so my old way of invoking the repl just did not work -- this is solved, thanks brew!).

The only "problem" with installing clojure on windows has to do with putting things in the right places.
First I downloaded the clojure zip from the official site and tested that the jar actually worked (which it does) [ I actually substitute the greater than char with % to have less troubles with escaping].

% java -cp clojure.jar clojure.main
Clojure 1.2.0
user=% (println "foo")
foo
nil
user=% (println "foo")

So, now, it is just a matter of placing it on the path and perhaps use some nocturnal mammal script to improve usability. There is such a script in the help page, however, it needs some modifications.

The modifications basically account for the very first lines in the script. I think that it is better if we just omit the version numbers, so that when upgrading we can just put the new stuff in place of the old. However, the modified version is included afterward.

We create a directory clojure in the root of the file-system (well... Windows "root" C:, so C:\clojure). I assume that all the libraries have been unpacked in the same directory (e.g., Downloads). And now we are going to copy the clojure, clojure contrib and jline jars in the that (C:\clojure) directory.

% mkdir \clojure
% cd clojure-1.2.0
% copy clojure.jar \clojure
1 file(s) copied.
% cd ..\clojure-contrib-1.2.0
% copy target\clojure-contrib-1.2.0.jar \clojure\clojure-contrib.jar
1 file(s) copied.
% cd ..
% copy jline-0_9_5.jar \clojure\jline.jar
1 file(s) copied.
% dir \clojure
Volume in drive C has no label.
Volume Serial Number is 74BF-5A64

Directory of C:\clojure
24/01/2011  11:12     DIR           .
24/01/2011  11:12     DIR           ..
19/08/2010  10:01           477.050 clojure-contrib.jar
19/08/2010  10:06         3.237.168 clojure.jar
24/01/2011  11:05            46.424 jline.jar
3 File(s)      3.760.642 bytes
2 Dir(s)  47.933.681.664 bytes free

I also saved a slightly modified clj.bat script and saved it in \clojure:
:: Setup:
:: 
:: 1. Change the constants to match your paths
:: 2. Put this clj.bat file on your PATH
::
:: Usage:
::
:: clj                           # Starts REPL
:: clj my_script.clj             # Runs the script
:: clj my_script.clj arg1 arg2   # Runs the script with arguments

@echo off

:: Change the following to match your paths
set CLOJURE_DIR=C:\clojure
set CLOJURE_JAR=%CLOJURE_DIR%\clojure.jar
set CONTRIB_JAR=%CLOJURE_DIR%\clojure-contrib.jar
set JLINE_JAR=%CLOJURE_DIR%\jline.jar

if (%1) == () (
:: Start REPL
java -cp .;%JLINE_JAR%;%CLOJURE_JAR%;%CONTRIB_JAR% jline.ConsoleRunner clojure.main
) else (
:: Start some_script.clj
java -cp .;%CLOJURE_JAR%;%CONTRIB_JAR% clojure.main %1 -- %*
)

Then it is just a matter of putting C:\clojure in the path. From the CLI it is just (here % stands for %, not for greater than):

set Path=C:\clojure;%Path%

Or better it can be set from the GUI once and for all:
  1. right-click on "Computer"
  2. choose Properties
  3. choose "Advanced System Settings"
  4. choose the Advanced tab
  5. click "environment variables" button
  6. select the Path line from the System Variables box
  7. add at the beginning C:\clojure; [note the ; at the end]
  8.  click ok
The Paths variable is a sequence of ; separated directories, that's it. I'm also considering adding C:\clojure\clojure.jar in the CLASSPATH variable.

2 comments:

Unknown said...

Personally I found it easy to download curl and lein.bat and place them on the path. Then with lein self-install it will setup itself and i can do lein new. Also swank/repl seems to work without problems.

Unknown said...

I agree. It is indeed easier (provided you want to have lein). However, most clojure novices never heard of lein, I think.