Saturday 10 January 2015

Getting Clojure installed and running and "G'day World"-ing

G'day:
This is just another one of those article about my experience with working out how to get a language operational in my dev environment. All it really serves to do is to demonstrate there's not much to it, so it should not be a "barrier to entry" if you decide to have a look at Clojure. I am way too much a newbie with it to be offering anything actually insightful here though.

Obviously that said if one's just wanting to give it a bash, there's online REPLs about the place (eg: Try Clojure) so no need to install it, but their scope will be limited, and for some reason I prefer to have stuff running locally.

I've worked through the Try Clojure tutorial before - ages ago - but other than that know nothing about it other than it seems to be overly in love with parentheses. Here goes...

Locate

It goes without saying finding out how to get it installed was a matter of googling: "install clojure windows". The first link is their website ("Clojure: Quick Start"), unsurprisingly.

And there, fourth sentence on the website is where to download it from:



No messing around. Not like trying to find how to install ColdFusion.

Install

Clearly install easy too (based on the instructions on that same screen shot!). Indeed it is. I simply D/Led and unzipped into C:\apps\clojure. I've got Java 8 installed btw.

Running the REPL

I literally copy and pasted the instructions from their website into my CLI and it worked:

Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation.  All rights reserved.

C:\Users\adam.cameron>cd \apps\clojure

C:\apps\clojure>java -cp clojure-1.6.0.jar clojure.main
Clojure 1.6.0
user=>


And keying in the first example (or actually: more copy and paste) demonstrates it working:

user=> (+ 1 2 3)
6

And even a GUI example:


Cool!

Running from file

REPLs are cool, but I wanted to be able to write my code in files, and run 'em. Once again I had no idea what to do, but googled "clojure execute file" and the second link too me through it.

NB: I initially looked for a clojure executable, expecting perhaps to be able to go:

> clojure myFile.clj


But Clojure doesn't work that way. Oh, hey: I'm such a n00b with Clojure I even had to google what the file extension ought to be!

Installing Leiningen

Anyway, that second link was to this article: "Building, Running, and The REPL", wihch was an excellent read. It mentions "Leiningen" which seems to be the Clojure package manager du jour, and I figured I needed to get that installed too.

Fortunately installation was bloody easy, and there's a Windows installer for it to boot.

Creating a project

Back to that article, and down to the "2.1 Creating a new Clojure Project" section.

All I need to do is go to a command line, nav to where I want to create the project and get Leiningen to do it:


C:\blogExamples\otherLanguages\clojure>lein new app gdayworld

That churns away and does its stuff and creates a subdirectory full of stuff:


./clojure/
 gdayworld/
  doc/
   intro.md
  resources/
  src/
   gdayworld/
    core.clj
  test/
   gdayworld/
    core_test.clj
  .gitignore
  .hgignore
  LICENSE
  project.clj
  README.md


I think it's pretty cool it creates it in a Git-aware way, and also includes a stub for tests. So they're encouraging TDD right from the outset. Bravo. I must check with Brad if CommandBox creates its default projects in a TestBox-ready way?

G'day World

The core.clj file seems to be the code entry point into the project:

(ns gdayworld.core
  (:gen-class))

(defn -main
  "I don't do a whole lot ... yet."
  [& args]
  (println "Hello, World!"))

It wouldn't be me if I didn't change that to "G'day World!" so I have done so.

Running

I can run that from the command line:

C:\blogExamples\otherLanguages\clojure\gdayworld> lein run
G'day, World!
C:\blogExamples\otherLanguages\clojure\gdayworld>

This takes a bloody age to run (about 12sec on this machine), but one needs to bear in mind Clojure is a JVM language, so it needs to crank up the JVM too. The main thing is that it works.

Compiling to JAR

This is easy too:
C:\blogExamples\otherLanguages\clojure\gdayworld> lein uberjar
Compiling gdayworld.core
Created C:\blogExamples\otherLanguages\clojure\gdayworld\target\uberjar+uberjar\gdayworld-0.1.0-SNAPSHOT.jar
Created C:\blogExamples\otherLanguages\clojure\gdayworld\target\uberjar\gdayworld-0.1.0-SNAPSHOT-standalone.jar
C:\blogExamples\otherLanguages\clojure\gdayworld>


I dunno about the cutesy (?) "uberjar" command, but so be it. Anyway... from here I can run it:

C:\blogExamples\otherLanguages\clojure\gdayworld>
java -jar target\uberjar\gdayworld-0.1.0-SNAPSHOT-standalone.jar
G'day, World!

C:\blogExamples\otherLanguages\clojure\gdayworld>

It worked. It's still slow, but Clojure projects are a bit of overkill for a "G'day World" example.

Running a file from the REPL

Bearing that in mind, I decided to try to use the best of both worlds: putting my code in a file, but running it as a script from within the REPL. This time I googled "clojure repl load from file", and the first link (ClojureDocs: load-file) shows how to do that.

(load-file filename)

The docs say: "Sequentially read and evaluate the set of forms contained in the file."

Perfect. So I save my code to a file:

;; gdayWorld.clj
(println "G'day World!")

Then I decided I can't be arsed keying in java -cp c:\apps\clojure\clojure-1.6.0.jar clojure.main every time I want a REPL to open, so I save that as a batch file, and put it in my C:\bin\ dir (which is on my path). Now I can open a command prompt wherever my code is, run clojure, then run my file:


C:\blogExamples\otherLanguages\clojure>clojure

C:\blogExamples\otherLanguages\clojure>java -cp c:\apps\clojure\clojure-1.6.0.jar clojure.main
Clojure 1.6.0
user=> (load-file "gdayWorld.clj")
G'day World!
nil
user=>

And running in this environment is instant.

Excellent.

Oh... I had to google this too. It seems to get out of the REPL, one needs to run this:

(System/exit 0)

CTRL-C works too, but it seems a bit like killing it rather than exiting it. It probably doesn't matter too much.

I have not looked at any code yet beyond what's shown here, but I am all good to go to try some quiz exercises ("Something for the weekend? A wee code quiz (in CFML, PHP, anything really...)" and "Another quick code puzzle (any language)"). As per usual, I'll try to come up with my own answer before looking at anyone else's answer for the given language. I have two Clojure answers to look at for that first quiz: Charlie Griefer's one, and Sean's one. I've got a busy day tomorrow, but I'll see if I can sit back down and try some of my own Clojure code. If not tomorrow, over the coming days. I also have some PHP and some CFML code to knock together soonish too.

Righto. I think I need a glass of wine, so I shall need to go buy some.

--
Adam