I already started learning Clojure some time ago by following the tutorial Clojure - Functional Programming for the JVM by R. Mark Volkmann, a Partner of Object Computing, Inc. (OCI). I also did the casting Clojure tutorial, read a lot of Clojure blog posts and saw some videos about Clojure.
What I was missing was a sane Clojure development environment configuration which could live at peace with my Common Lisp Emacs SLIME development environment. Well, by following the Swank_clojure_setup_for_hardcore_Emacs_users.el I achieved it. But, first I had to ditch my Debian based SLIME installation and go to the SLIME CVS version. That was the base recommendation that hardcore Emacs and Common Lisp hackers give, so, nothing too wild here.
Besides Clojure, I also wanted to have working Common Lisp implementations connected to Emacs. My choice was previously the SBCL version available from Debian repositories and ABCL from the Subversion checkout.
So, enough introduction, follows the objectives and how I did it on a Debian based GNU/Linux distribution and bash.
- Emacs snapshot from Debian's repositories.
~$ sudo apt-get install emacs-snapshot-gtk emacs-snapshot-el
- SLIME from CVS.
~$ sudo apt-get install cvs # only if you don't have CVS yet
~$ cd programacao/lisp # I have all Lisp related programming sources here
~/programacao/lisp$ cvs -d :pserver:anonymous:firstname.lastname@example.org:/project/slime/cvsroot co slime
~/programacao/lisp$ cd slime/doc
~/programacao/lisp/slime/doc$ sudo apt-get install texlive # because I want to build an up-to-date slime-doc
~/programacao/lisp/slime/doc$ gzip slime.info # TODO: this is available as make install, but, my distribution paths are different...
~/programacao/lisp/slime/doc$ sudo install-info slime.info # make it available to info
~/programacao/lisp/slime/doc$ sudo cp slime.info.gz /usr/share/info/
~/programacao/lisp/slime/doc$ cd ~
- SBCL from source tarball download, which I placed in
~$ cd programacao/lisp/sbcl
~/programacao/lisp/sbcl$ tar -xvjf sbcl-1.0.39-source.tar.bz2
~/programacao/lisp/sbcl$ cd sbcl-1.0.39/
Now, check the INSTALL...
Now, check the Getting started...
I already had the SBCL from Debian, so, this would be my Common Lisp host which would be automatically used by
~/programacao/lisp/sbcl/sbcl-1.0.39$ sh make.sh # and detach with C-a d, using screen -r to check its state from time to time
An alternative I will try next time is to use a non-GUI terminal by going C-M-F1.
TODOs: install binaries, build and install doc.
~/programacao/lisp/slime/doc$ cd ~
- ABCL from Subversion. I already had Subversion and Ant installed via
~$ mkdir -p programacao/lisp/abcl/svnco && cd programacao/lisp/abcl/svnco
~/programacao/lisp/abcl/svnco$ svn co svn://common-lisp.net/project/armedbear/svn/trunk/abcl && cd abcl
~/programacao/lisp/abcl/svnco/abcl$ ant # this creates the abcl executable shell script to launch ABCL
~/programacao/lisp/abcl/svnco/abcl$ cd ~
- Ant and Maven binaries downloaded and installed.
~$ sudo apt-get install maven2
- Clojure and Clojure-contrib from their Git repositories. Git was already installed.
~$ cd programacao/clojure
~/programacao/clojure$ git clone http://github.com/richhickey/clojure.git
~/programacao/clojure$ git clone http://github.com/richhickey/clojure-contrib.git
~/programacao/clojure$ cd clojure
~/programacao/clojure/clojure$ ant jar
~/programacao/clojure/clojure$ cd ../clojure-contrib
~/programacao/clojure/clojure-contrib$ mvn package
~/programacao/clojure/clojure-contrib$ cp target/clojure-contrib-*.jar clojure-contrib.jar
~/programacao/clojure/clojure-contrib$ cd ~
- Leiningen binary downloaded and installed.
~$ mkdir -p progs/lein && cd progs/lein/
~/progs/lein$ wget http://github.com/technomancy/leiningen/raw/stable/bin/lein && chmod u+x lein
~/progs/lein$ cat >> ~/.profile
# finish editing with C-d
~/progs/lein$ lein self-install
~/progs/lein$ cd ~
- Clojure-mode and Swank-clojure also from Git repositories.
~/programacao/clojure$ git clone http://github.com/technomancy/clojure-mode.git
~/programacao/clojure$ git clone http://github.com/technomancy/swank-clojure.git
~/programacao/clojure$ cd swank-clojure && lein jar
~/programacao/clojure/swank-jar$ cd ..
- Create a shell script to launch Clojure with all the required goodies in the classpath. Note that this script will be used within Emacs and therefore you don't want fancy wrapping and history with
rlwrap. You may create one of those to use in the command line, though.
~/programacao/clojure$ cat > clj-dev.sh
CLJ="$JAVA -server -cp $CLOJURE_JAR:$CLOJURE_CONTRIB_JAR:$SWANK_CLOJURE_JAR clojure.main"
exec $CLJ "$@"
# not part of the file, finish with C-d
So, after writing all this in shell language, would it be possible to have it in Clojure, Common Lisp or Emacs Lisp? With Clojure we could get fancy and execute some long lasting tasks in parallel.
Finally, the relevant part of my ~/.emacs file:
;;; SLIME and Lisp and Clojure support (require 'cl) (add-to-list 'load-path "~/programacao/lisp/slime/") (setq slime-backend "swank-loader.lisp") (setq inferior-lisp-program "~/programacao/lisp/sbcl/sbcl-1.0.39/run-sbcl.sh") (add-to-list 'load-path "~/programacao/clojure/clojure-mode/") (add-to-list 'load-path "~/programacao/clojure/swank-clojure/") (pushnew '("\.clj$" . clojure-mode) auto-mode-alist) (require 'clojure-mode) (setq slime-lisp-implementations '((sbcl ("~/programacao/lisp/sbcl/sbcl-1.0.39/run-sbcl.sh")) (abcl ("~/programacao/lisp/abcl/svnco/abcl/abcl") :coding-system iso-latin-1-unix) (clojure ("~/programacao/clojure/clj-dev.sh") :init swank-clojure-init))) (require 'slime-autoloads) (setf slime-use-autodoc-mode nil) ; swank-clojure doesn't support autodoc-mode (slime-setup '(slime-banner slime-repl slime-fancy slime-scratch slime-editing-commands slime-scratch slime-asdf)) (setf slime-net-coding-system 'utf-8-unix) (setf swank-clojure-binary "~/programacao/clojure/clj-dev.sh") (require 'swank-clojure) (defun run-clojure () "Runs clojure lisp REPL" (interactive) (slime 'clojure)) (defun run-abcl () "Runs ABCL lisp REPL" (interactive) (slime 'abcl))
I still have Paredit configured for the Lisp dialects I use, which is another recommended way to customize Emacs. Definitely, there are pieces missing, but, I reached a target with enough relevancy for me to be worthy of careful documentation :-) I could have earned extra hacking points if it would be automated, though, so, thou shall not halt here!