Search This Blog

Thursday, December 30, 2021

Clojure Setup from Scratch on a Clean Install of Debian 11

I've just installed Debian 11 on an ancient netbook whose hard disk failed, so that seems a chance to find out what
we need to do to make a functioning clojure environment from scratch.

The only changes I've made to my default install are things like getting sudo working and setting the UMASK, my home directory is brand new and empty.

first install clojure

$ sudo apt install clojure

$ clojure
Clojure 1.10.2

Latest stable according to is 1.10.3, so that's really not bad!

and we've got a nice command-line REPL with bracket-balancing and history working

user=> (* 8 8)

Ctrl-D kills the REPL

Let's see if we can write a program:

$ cat > hello.clj
#!/usr/bin/env clojure
(println "hello")

$ chmod + x hello.clj

$ ./hello.clj

Startup time is quite long on my old netbook, so hello.clj takes 14 seconds to run, but the REPL, although sluggish to start up, actually runs pretty responsively once it has started.

And that's on a dell-mini, a 10 year old netbook that wasn't built for speed when it was new.

So that's a working installation, and you can use any editor to edit scripts and run them from the command line.

So far so good! Actually really impressed.

I can program like that, but I like to run clojure from within emacs, which is always the hard bit of getting any new language to work, so let's install emacs

$ sudo apt install emacs

and run it on our file

$ emacs hello.clj

We get no syntax highlighting, and the file is in 'fundamental mode', so emacs by default doesn't recognise .clj files

M-x package-list-packages

Shows some packages, but nothing clojure related, we need to add the melpa archive.

Suggests adding an incantation to your .emacs file:

So create the file ~/.emacs, and put:

(require 'package)
(add-to-list 'package-archives '("melpa-stable" . "") t)


in it.

Close emacs (Ctrl-X Ctrl-C) and restart it with:

$ emacs hello.clj

Now we can install clojure-mode

M-x package-refresh-contents

M-x package-install

Again, close emacs and restart

$ emacs hello.clj

On restart, emacs recognises hello.clj as a clojure file, and syntax highlights it.

Again, this all works well so far. Adding MELPA to emacs is just one of those things you have to do in life.

But programming in clojure is best done with a running REPL, and for this we need CIDER

M-x package-install

Once CIDER is installed, the hello.clj file has a CIDER menu, check that you've got CIDER 1.1.1
because all this stuff is still changing quite quickly, and it's a bit temperamental about version

and there's an option to start a REPL

CIDER/Clojure/Start Clojure REPL

It complains 'are you sure you want to run cider-jack-in without a clojure project', which is exactly what I want to do, so I say yes.

I was so hoping this would work...

And it looks like it's doing something sensible, trying to start the system clojure with a command line, but it fails with an incomprehensible error message.

I think the problem is that it's trying to use the relatively new clojure command line tools to start a repl, which would be great, except that Debian hasn't got round to packaging them yet.

There doesn't seem to be a way to just use CIDER to edit and run a program using the system version of clojure.

(Although it does look like the CIDER people have at least tried to make that work, more power to them, and maybe it will work one day when the CLI tools get into debian)

So with a heavy heart, install leiningen and create a project file.

$ sudo apt install leiningen

$ cat > project.clj
(defproject vile "" :dependencies [ [org.clojure/clojure "1.10.2"] ])

and now try:

$ lein repl

That will then download a completely new version of clojure 1.10.2 into a local maven repository and
create a "target" directory full of crap in whatever directory you're in.

and eventually give you a repl

check it works, and then kill it with Ctrl-D

go back into emacs, and go into the hello.clj buffer, and again, try

CIDER/Clojure/Start Clojure REPL

Eventually, up should come a usable clojure REPL in emacs.

Now everything should be working, add (* 8 8) to hello.clj, and put the cursor in the middle of the
expression, and press C-M-x , and you should see the result of the evaluation => 64 display
conveniently in the buffer.

Also try M-. to go to the source code of a function, and M-, to go back to where you were

And there are lots of other lovely things about CIDER and using emacs and lisp together as they were meant to be used, which I will leave you to discover on your own.

Have fun!


Doing it the hard way:

CIDER's jack-in function is a bit magical for me, but luckily it will tell us what it's doing and which versions it needs:

The crucial line in the REPL startup text is:

;;  Startup: /usr/bin/lein update-in :dependencies conj \[nrepl/nrepl\ \"0.8.3\"\] -- update-in :plugins conj \[cider/cider-nrepl\ \"0.26.0\"\] -- repl :headless :host localhost

Which implies that we need [nrepl/nrepl "0.8.3"] as a dependency, and [cider/cider-nrepl "0.26.0"]
as a leiningen plugin, presumably to get leiningen to insert the cider-nrepl middleware to its nrepl

So if we modify our project.clj file to look like:

(defproject vile ""
  :dependencies [ [org.clojure/clojure "1.10.2"]
                  [nrepl/nrepl "0.8.3"] ]
  :plugins      [ [cider/cider-nrepl "0.26.0"] ])


$ lein repl

will start a command line REPL which also has a network port open with CIDER middleware attached,

and which you can connect to from CIDER with

M-x cider-connect

I prefer this way of doing things, for some reason. I think it feels a bit more solid and comprehensible than having emacs running my clojure process.

No comments:

Post a Comment