Abuse of “lein run”

I have a collection of functions packaged into a Clojure library that I am working on for a bigger application. It occurred to me that many of these Clojure functions would be very useful if I could call them from my bash shell, not just from a REPL. I don’t care about the three second startup time of the JVM, and I don’t want to make a new jar for each little ‘application’ that I am making, since most of these are throw-away scripts or one-liners used for development purposes anyway. How can I start a JVM, load the appropriate libraries, and run a function that I want from the command line or a shell script?

The approach I took was to leverage leiningen to manage dependencies, start up the JVM, load appropriate libraries, and call the appropriate function.

You may be familiar with the acronym REPL, which stands for ‘Read Eval Print Loop”. For this type of task, what we really need is just a ‘Read Eval’ function defined somewhere, since we don’t want to loop. I wrote this stupid function, “Read-eval”, and threw it into one of my libraries.

(defn read-eval
  "Read and evaluate an expression contained in string."
  [string]
  (eval (read-string string)))

Assuming that I put that into the ‘mylib.util’ namespace, I then run this command in my bash shell:

  $ lein run -m mylib.util/read-eval '(+ 1 2 3)'                     # Add numbers
  $ lein run -m mylib.util/read-eval "(mylib.math/std-dev [1 2 3])"  # variance

If I need to type more than a one-liner, it’s easier just to use ‘load’:

  $ echo "(+ 1 2 3)" > ~/test.clj
  $ lein run -m clojure.core/load-file ~/test.clj

It’s kind of neat how BASH replaces ‘~/’ with the proper home directory before sending it to leiningen.

Anyone got a better way of doing this?


Using Leiningen to Build Projects

Leiningen is a tool for building Clojure code, downloading jars, handling java classpaths, and in general gluing all those ugly-but-necessary development details together into a coherent whole.

Leiningen runs on maven, so it is theoretically able to do anything that maven can do. In practice, Leiningen is still under development so this statement hasn’t been fully proven yet, but it should handle most small and medium-sized projects with relative ease.

Let’s walk through a typical example of managing a project with leiningen.

Creating a Project

Leiningen provides a simple way of creating a structure of a project. Let’s walk through a simple application called “fahr” that converts temperatures between Fahrenheit and Celsius.

cd ~/clj/src/
lein new fahr

That created a directory structure under the new directory ‘fahr’ that looks like this:

.
|-- project.clj
|-- README
|-- src
| `-- fahr
| `-- core.clj
`-- test
`-- fahr
`-- test
`-- core.clj

Now let’s get in the new directory and add version control:

cd fahr
git init
git add project.clj src/fahr/core.clj test/fahr/test/core.clj
git commit

Before we can start swank, we need to edit the project.clj file to contain the line:

:dev-dependencies [[swank-clojure "1.2.1"]]

And then run:

lein deps
lein swank

Finally, we can connect to it from inside emacs by pressing:

M-x slime-connect

Happy Hacking!

Testing your code

Every time you start Leiningen, a JVM is created, Leiningen does its work, and then the JVM is destroyed. If you want to avoid this heavy startup cost, you may want to run it in interactive mode, as I do.

lein interactive

This is especially handy during development when you just type in ‘test’ repeatedly to quickly check how your code is progressing.

Distributing your code

If you want to build an ‘uberjar’, a package that contains the application and also clojure’s jar files as well, you can use the following:

cd ~/clj/src/
lein deps
lein compile
lein uberjar

When people want to run your application, now all they have to do is

java -jar fahr-standalone.jar

Alternatives

If leiningen was not to your liking, you may try cake, gradle, maven, or polyglot maven.

Resources:


Using Git for Version Control

Using git for version control is dead easy.

If you have never used git before, you may need to initialize your user name and email address so that commits will be under your name.

git config --global user.name "Your Name Comes Here"
git config --global user.email you@yourdomain.example.com

Once you have done that once, it will be remembered across all your projects.

Let’s assume we have a project inside ~/clj/src/myproject/ to which we want to add version control.

cd ~/clj/src/myproject
git init
git add project.clj src/file1.clj src/file2.clj ...
git commit

As you develop code, you should get in the habit of doing these two commands over and over again

git add <files>
git commit

Or using your favorite editor to accomplish the same thing. If you forget what files you have edited,

git status

And look at your development history with

git log

At the very minimum, you should know these commands:

git init # Tell git to do version control on this directory
git add . # Add all files in this directory.
git commit # Commits all changes to the files
git add file1 file2 # Add two more files to the project
git diff --cached # See what you are about to commit
git status # Another way of summarizing what you will commit
git commit -a # Commit all modified files automatically
git log # Look at the history of changes

If you want to look at an old commit as a reference, use “git checkout COMMIT”, where COMMIT is the commit’s ID number. Look around at this saved snapshot in time, and then when you are done go back to the head of the branch with “git checkout master”.

Resources:


Using Emacs for Clojure

“Emacs is probably best described as a thermonuclear text editor.”

Actually, it would be rude to call Emacs just a text editor. Emacs is to text editing as the command line is to unix: a unified interface to everything textual on the earth. The unified interface and limitless customizability via a lisp is why it still remains tremendously useful despite being more than 30 years old. If you hate repeating yourself, either in code or when typing, then emacs is the editor for you.

This mentality is why Emacs really shines when you are developing lisp code: you are using a programmable programming language (lisp) in a programmable programmer’s editor (emacs). This kind of flexibility — the ability to automate whatever you desire — is very appealing to a certain type of person.

But emacs is not particularly easy for beginners to learn. For those not familiar what to do when somebody says “type C-c C-d”, what the minibuffer is, what the .emacs file does, or what elisp is should do a little reading before continuing.

And now, for some of the customizations I use when hacking Clojure on emacs.

Firstly, there are some default annoyances of emacs that I want to remove.

(setq inhibit-startup-message t) ;; No splash screen
(setq initial-scratch-message nil) ;; No scratch message
(tool-bar-mode nil) ;; No toolbars
;; Create backup files in .emacs-backup instead of everywhere
(defvar user-temporary-file-directory "~/.emacs-backup")
(make-directory user-temporary-file-directory t)
(setq backup-by-copying t)
(setq backup-directory-alist
`(("." . ,user-temporary-file-directory)
(,tramp-file-name-regexp nil)))
(setq auto-save-list-file-prefix
(concat user-temporary-file-directory ".auto-saves-"))
(setq auto-save-file-name-transforms
`((".*" ,user-temporary-file-directory t)))

Next, I do my configuration related to Clojure, and tell it where I keep my elisp files.

(setq load-path (cons "/PATH/TO/YOURUSERNAME/clj/emacs" load-path))
(require 'clojure-mode)
(require 'slime)
(slime-setup)
(setq slime-use-autodoc-mode nil) ;; Workaround for Clojure 1.3. See http://groups.google.com/group/clojure/browse_thread/thread/692c3a93bbdf740c?tvc=2&pli=1

When actually editing code, the paredit mode is absolutely essential, and highlight-parenthesis really can be useful for helping non-lispers see how the parentheses match up.

(require 'paredit)
(require 'highlight-parentheses)
(add-hook 'emacs-lisp-mode-hook 'enable-paredit-mode)
(add-hook 'clojure-mode-hook
(lambda ()
(highlight-parentheses-mode t)
(paredit-mode t)
(slime-mode t)))
(setq hl-paren-colors
'("red1" "orange1" "yellow1" "green1" "cyan1"
"slateblue1" "magenta1" "purple"))

Switching back between Clojure’s REPL and the Clojure buffer you are editing happens often enough that you should probably map the slime-selector function to a key; I chose F12. The following lets me switch to the REPL by pressing F12 and then r, and back again using F12 and then j.


;; To go back and forth quickly between repl (r) and clojure (j)
(define-key global-map (kbd "") 'slime-selector)
(def-slime-selector-method ?j
"Go to the most recently visited clojure-mode buffer."
(slime-recently-visited-buffer 'clojure-mode))

Finally, you may like to change the default fonts and coloring to be more easy on the eyes:

(require 'color-theme)
(color-theme-tango)
(set-face-attribute 'default nil :family "courier" :height 140)

Now fire up emacs, start a Swank server, and start coding!

Workflow

It will be so much easier to code in Clojure if you know how to use Slime and paredit.

Start by reading the Slime documentation, particularly the excellent video by Marco Baringer describing how Slime can be used to work with Common Lisp code. The vast majority of the video is applicable also to writing Clojure code.

I also found it useful to work through the Editing Common Lisp examples, because the key commands for slime are the same regardless of whether you are writing CL or Clojure.


Fast-Forwarding Audio/Videos without Pitch Changes

What if we could watch movies at 1.5x or 2x speed without changing the audio pitch? This post will show you how to do exactly that on Ubuntu 10.04.

Maybe you have wished you could watch boring movies or slow-but-still-interesting lectures or interviews faster. If we use the standard fast-forward functionality from most video players, the audio pitch goes higher and higher as we play the movie faster, until the audio sounds like everyone has been inhaling helium.

But if you are an Ubuntu 10.04 user, there is a neat trick we can use to dynamically transform the audio on the fly so that people speak twice as fast, but at the same pitch. I thought I’d post this note here for the benefit of others and so I can remember how to do it in the future.

UPDATE: If you have a very recent version of mplayer, the support for variable speed playback may be already built in. Try out

mplayer -af ladspa -speed 1.5 file.avi

If that didn’t work, you’ll need to try it the longer way.

First, you’ll need to install tap-plugins:

sudo apt-get install tap-plugins

Then, you will use a command of the following form to play the file (NOTE: This won’t work just yet, read on!):

mplayer -speed x -af ladspa=/usr/lib/ladspa/tap_pitch.so:tap_pitch:0:y:-90:0 file.mp3

In the above command, x is the rate at which the file should play, with 1 being normal speed. So if you want to play at 80% of normal speed, x = 0.8, and if you want to play it at 150% of normal speed, x = 1.5. Also in the above expression, y is the modified pitch, as a percentage change, with 0 being normal. So if you want to increase the pitch by 50%, y = 50, and if you want to decrease the pitch by 50%, then y = -50.

The challenge we have is that we want to keep the pitch the same, so we need to work out the relationship between x and y so that if we decrease the speed (tempo), we increase the pitch to compensate. This relationship is given by the following equation:

y = (100-100x)/x

So if we want to play the file at 80% of normal speed, x = 0.8 and y = (100-100*0.8)/(0.8) = 25, and the command we would use to play the file becomes:

mplayer -speed 0.8 -af ladspa=/usr/lib/ladspa/tap_pitch.so:tap_pitch:0:25:-90:0 file.mp3

If we want to play the file at 200% of normal speed, x = 2 and y = (100-100*2)/2 = -50, and the command we would use to play the file becomes:

mplayer -speed 2 -af ladspa=/usr/lib/ladspa/tap_pitch.so:tap_pitch:0:-50:-90:0 file.mp3

tap-pitch only works with a pitch shift range of -50 to 100, which corresponds to speeds of 0.5x to 2.0x, although it is possible to chain the filters if you want to increase that range (so run tap-pitch on tap-pitch), but frankly watching things at faster than 2.0x is usually an exercise in futility anyway.

I usually put these two commands in my .bashrc so I can just call them on any file I want to run fast (or fastest!):

alias mplayerfast='mplayer -speed 1.5 -af ladspa=/usr/lib/ladspa/tap_pitch.so:tap_pitch:0:-33:-90:0'
alias mplayerfastest='mplayer -speed 2.0 -af ladspa=/usr/lib/ladspa/tap_pitch.so:tap_pitch:0:-50:-90:0'

Enjoy!


Anecdotal Experiences of a Dvorak Keyboard Layout Typist

I have been a Dvorak typist for the last 12 years, and would like to share my thoughts and experiences on using the layout during that time.

What is the the Dvorak layout?

Let’s look at a typical US keyboard layout, the so-called QWERTY layout. It is named for the first five letters on the upper row of the keyboard.

The QWERTY keyboard layout.

Notice that in the QWERTY layout vowels are spread all around the keyboard, and that the most commonly used consonants (t,n,s,h) are spread all around the keyboard with no particular pattern. There are allegedly two historical reasons for this:

  1. Some salesmen requested that he be able to write the word “typewriter” using only letters in the top row of the keyboard, presumably so that he could find them quickly when showing the new invention to customers.
  2. If the most commonly used letters are placed all around the keyboard, it reduces the chance that the typewriter will jam because it will take the typist more time to move their fingers between keystrokes. This naturally slows down your typing speed.

The first reason is rather arbitrary, and the second is deliberately detrimental to typing speed in the modern era of computer keyboards, for which there is no possibility of a mechanical jam.

Let’s compare QWERTY to the Dvorak layout, which was scientifically designed by Augustus Dvorak as part of a study for the US Navy on improving typing efficiency. The Dvorak layout places the most commonly used consonants under the fingers of the right hand, and the vowels on the left. Since most words have vowels somewhat evenly distributed throughout a word, the left hand and right hand frequently alternate keystrokes.

First, look at the eight most common letters in the English language:


e 12.702%
t 9.056%
a 8.167%
o 7.507%
i 6.966%
n 6.769%
s 6.327%
h 6.094%


Now look at the positions of these letters on the Dvorak layout:

The Dvorak keyboard layout.

Note how ALL of these eight most commonly used letters are on the home row, in easy reach of your fingers without even moving. The result is significantly less required finger motion and faster average typing speeds on the Dvorak keyboard.

Can you type faster with the Dvorak Keyboard?

Yes. At least, in my personal experience. In fact, I estimate conservatively that I type at least 20% faster than I would otherwise type on a qwerty layout, and my ‘burst’ speed has become much higher — the top speed bottleneck is usually my brain, not my fingers. Let’s quantify that a little in the next few paragraphs.

When I switched to the Dvorak layout (12 years ago…it’s amazing my records still exist!), I had been touch-typing in Qwerty for about five years. Being at least a nominally scientific teenager, I measured my typing progress occasionally because was curious to see how long it would take me to regain my former typing speed.

In the following results, “wpm” stands for “words per minute”, and is usually measured as the number of correct keystrokes per minute divided by five. My methodology was pretty simple: I typed sentences out of a robotics book for about 15 minutes (resting for one minute between 3 or 5 minute intervals), counted the characters in the correct words, and computed my WPM score based on that.


Original QWERTY 42WPM
Dvorak Day 3 11WPM
Dvorak Day 7 23WPM
Dvorak Day 46 34WPM
Dvorak Day 61 37WPM
Dvorak Day ~270 48WPM
Dvorak Day ~600 67WPM
Dvorak Day ~2500 71WPM


Looking at the above, you can see I’m wasn’t a terribly good touch typist to begin with, only hitting about 4-5 correct characters per second (I wonder how many times I hit the delete key?!). After switching to Dvorak, it took about 2 months to get back to my old speed, and about 9 months later I was only 14% faster.

However, over the years my typing speed has continued to increase, although it is debatable how much of this increase is a result of the layout, and how much is merely a result of increased experience. But I was surprised to take some touch typing tests recently (Day 4300?), and here are the results:

Result of 10 trials of typing.

If I don’t make any mistakes, a well-typed sentence will be closer to my maximum speed of about 120-130wpm, which I can only accomplish when writing spontaneously and not copying from another document. For example, this easy quote from Henry Ford is probably close to my maximum copying speed:

When typing

I’m not claiming this is exceptionally fast or unachievable by a QWERTY typist, but it is a significant improvement over my original typing speed, and prompted me to write this up as a data point for other people. It would be interesting to see how QWERTY typist speeds improve over the course of 12 years, or what kind of errors they are making. The majority of my errors were mistakes in the ordering of the letters, for example typing “teh” instead of “the”.

What about writing in other languages with Dvorak?

The only foreign language at which I am proficient is Japanese, so I will mention my experiences with that. Briefly, it feels like slightly more ‘work’ to type Japanese than English with Dvorak, but still feels better than the Qwerty layout because of vowel placement.

To be more specific, it is less comfortable to type in Japanese than in English with the Dvorak keyboard because the frequencies of the letters k,j, and z are much higher in Japanese than in English and you start feeling more ‘left hand dominant’ when writing. However, at least the vowels in Japanese are all on the left hand, so I suspect that Dvorak is still superior to Qwerty when using a Japanese input method editor. I can’t speak for other languages, as what little writing I have done in Italian or French has all been at a rudimentary level. Dvorak was optimized for English and it seems reasonable to expect that it may not be as suitable for other languages with different letter frequencies — although it’s hard to do worse than QWERTY’s vowel placement.

Is Dvorak better for programmers?

I’m going to say no in general — for programming, layout doesn’t seem to matter. Coding quickly is generally limited by brain speed, not finger speed. Nevertheless, there is a Programmer’s Dvorak layout, for those interested in having brackets, parenthesis, and braces closer at hand.

What about key chords and shortcuts?

Dvorak loses the popularity contest to Qwerty and it hurts in this case — most shortcuts are designed for the qwerty layout and so are more difficult to type on a Dvorak layout. While Emacs-users may not have difficulty rebinding our keys to use the proper, the fact remains that this is extra work for us, but it cannot be fixed in all cases.

Some people work around the problem by having their keyboards remap to Qwerty when the command key is held, but I have not tried this myself.

What about inconveniences when using other people’s computers?

If you are like me, you spend 99% of your time on your own personal computer, and less than 1% of the time at an unfamiliar computer. Therefore, keyboard layout is something you set once and then completely forget about.

Also, in the vast majority of cases when you have to use an unfamiliar computer, it is about 30 seconds of work to change the keyboard layout to Dvorak, although occasionally a brain-dead administrative policy may prevent you from doing this and you will be forced to use Qwerty for a few minutes.

What happens when other people try to use your computer?

You will enjoy the priceless look your friends’ faces when they try to borrow your computer for a moment and discover the letters are not where they appear. Some particularly obstinate people will try four or five times to type something in before realizing that the layout must be different.

So, Dvorak also works as a simple security measure when combined with the command line — completely clueless users will be unable to change the keyboard layout and be locked out from effectively using your computer for the 5-10 minutes it will take them to figure out how it works.

Can you still type in Qwerty after learning Dvorak?

Yes. It’s strange to me that I have retained the ability to touch-type Qwerty, even after more than 10 years of hardly using it at all. When I am forced to use a public computer or friend’s computer that cannot be remapped into Dvorak, I typically type at a rather slow ~30wpm…but it is still touch typing.

Which is more ‘comfortable’, Dvorak or Qwerty?

Although this is hard to quantify, Dvorak is much more comfortable for writing in English than Qwerty. Some doctors recommend that users suffering from Repetitive Stress Injuries (RSI) such as carpal tunnel syndrome switch to the Dvorak layout because of the reduced finger motion. I have also heard that Dvorak requires 60% less finger motion than Qwerty for typical typing tasks.

Ironically, I have heard some Qwerty typists argue that it is the increased finger motion of Qwerty which helps stave off RSI, but I can only surmise that they have no experience actually typing Dvorak — although no silver bullet, my anecdotal experience is that it is clearly less fatiguing on the fingers and wrists…when combined with a split keyboard, proper arm support, and good sitting posture, of course.

Is it worth switching to the Dvorak Layout?

It was worth it for me as a 17 year old. As a native English speaker who will be spending most of his time writing in English, even a modest 20% improvement in typing speed of my native language will continue to pay productivity dividends throughout my life.


How I Install Clojure

The following describes the packages I install when I need to set up a Clojure development environment the way I like it on a new computer running Ubuntu 10.04. These notes are mostly for my own use, but you may also find them useful.

Ubuntu Packages

We are going to need a few pieces of support software to begin development in Clojure. Assuming that we are starting from a fresh installation of Ubuntu 10.04, run the following commands in a terminal:

sudo apt-get install ant # Ant is a build tool for Java
sudo apt-get install maven2 # Maven is another build tool for Java
sudo apt-get install git-core # git is a version control system

There are many different JVMs available for Linux. By default, Ubuntu 10.04 uses OpenJDK, but many people prefer Sun’s implementation. To see what is presently installed, run:

java -version

So far, OpenJDK has worked fine for me. But, if you want to remove all evidence of OpenJDK and install the Sun implementation, try:

sudo apt-get purge openjdk
sudo apt-get install sun-java6-jdk

If you will be using Emacs, you should install these:

sudo apt-get install emacs # Emacs is the One True Editor
sudo apt-get install emacs-goodies-el # Many useful elisp files
sudo apt-get install slime # Superior Lisp Interaction ModE (SLIME)

Finally, there are some useful Java libraries which you may want to have installed:

sudo apt-get install jogl # Java Open Game Library, a useful library

Now that the packages are installed, you will want to create your directory structure and fill it with code.

Create your Clojure Directory

Everyone has their own way of keeping files organized. What follows is the directory structure I use for clojure-related things. Feel free to use whatever organization patterns you want.

~/clj/ # The home for all things clojure
~/clj/bin/ # Things executable go here
~/clj/docs/ # Things that document go here
~/clj/docs/javadoc/ # Java documentation, used by emacs
~/clj/emacs/ # For custom .el files related to clojure
~/clj/examples/ # For snippets of code collected from the 'net
~/clj/jars/ # For hand-managed .jar files
~/clj/src/ # For my own code, for other people's code
~/clj/src/clojure/ # Where clojure core code resides
~/clj/src/clojure-contrib/ # Where clojure-contrib resides
~/clj/src/leiningen/ # Where leiningen resides
~/clj/src/swank-clojure/ # Where the swank module resides
~/clj/src/MYPROJECT1 # Hypothetical MYPROJECT1 dir

The following command will create this structure for you:

mkdir ~/clj ~/clj/bin ~/clj/docs ~/clj/docs/javadoc ~/clj/emacs ~/clj/examples ~/clj/jars ~/clj/src

Populating the Directory Tree

Directories aren’t very useful without files inside them. Let’s fill the directories we just created with useful things.

First, let’s grab Clojure itself. Because features are continually being added to Clojure — as well as bug-fixes — for my purposes there is no reason not to use the latest version of Clojure. So let’s use git to get the newest version of Clojure and clojure-contrib:

cd ~/clj/src
git clone "git://github.com/clojure/clojure.git"
git clone "git://github.com/clojure/clojure-contrib.git"

Somewhat strangely, you build Clojure with the ant build tool, you build clojure-contrib with the maven build tool, but for most of the code that you will write you will use a tool called leiningen.

cd ~/clj/src/clojure
ant # Build Clojure's .jar files
cd ~/clj/src/clojure-contrib
mvn install # Build clojure-contrib's jar files

In the future, when you want to update Clojure, just pull changes from Rich’s repository:

cd ~/clj/src/clojure
git pull # Pull the latest version from the repository
ant # Rebuild clojure's .jar files
cd ~/clj/src/clojure-contrib
git pull # Pull the latest version from the repository
mvn # Rebuild clojure-contrib's .jar files

It’s a good idea to test Clojure at this point. The basic method of interaction with a Clojure (and many other lisps) during development is through a REPL (Read Eval Print Loop). REPLs are great because they let you interact with the language in a very fine-grained way, without the annoyance of having to compile each time you want to test your code.

You can fire up a REPL by adding the clojure jar to the classpath — the ‘-cp’ argument given to the JVM which specifies where in the filesystem the JVM can look for usable .jar or .class bytecode files — and calling clojure.main:

cd ~/clj/src/clojure
java -cp clojure.jar clojure.main

Voila! You should now have a Clojure REPL! Anything you type into the REPL will be read, evaluated, and the results printed immediately. This is a great way of getting feedback from the computer about your code as you go along. Try typing something into the REPL, such as this example from the Clojure Getting Started Page:

user=> (+ 1 2 3)
user=> (. javax.swing.JOptionPane (showMessageDialog nil "Hello World"))

Take a few moments to play around with your new friend. When you are done, exit the REPL by pressing Ctl+D (end of file), or if you are less polite, Ctl+C (interrupt signal) to directly kill the jvm.

Leiningen

The third and final build tool is called Leiningen. It is basically a wrapper around the maven build tool that lets us specify dependencies and build procedures using clojure code instead of xml expressions. It is trying to put a friendly face on the huge, mighty beast called maven.

Leiningen is easily installed by downloading a small script to ~/clj/bin/lein, setting it to executable, and asking it to install itself.

cd ~/clj/bin
wget http://github.com/technomancy/leiningen/raw/stable/bin/lein
chmod 755 lein
./lein self-install

Leiningen will take a few moments to download some jars and place them under ~/.m2 where maven-related files will be stored. This is normal behavior of the beast called maven.

For convenience, it’s a good idea to add the ~/clj/bin directory to your bash $PATH, so that any scripts in this folder can be executed from anywhere and we can type just “lein” instead of “~/clj/bin/lein”.

echo 'PATH=$HOME/clj/bin:$PATH' >> ~/.bashrc
source ~/.bashrc

Now you can check that Leiningen is installed:

cd ~/clj
lein version

If you see some version information, congratulations!

Emacs Files

Emacs connects very well with Clojure using Slime and Swank. In the end, the connection between you and the hardware looks like this:

User<->Emacs <-> SLIME <->Swank-clojure<->clojure<->JVM

For the unfamiliar, Slime is a program for hacking lisp that runs in Emacs, and swank is a server program that lets you interact deeply with Clojure. Breaking that down a bit:

  • Users type code into Emacs, using clojure-mode (and paredit-mode for convenience)
  • Emacs use the SLIME mode to send user’s code over a socket
  • The swank server listens on a socket, and gives it to Clojure
  • Clojure takes data from the swank thread, compiles it to bytecode
  • The JVM executes the bytecode
  • Unhandled exceptions, debugging information, etc all propogate in the other direction as needed, of course.

Now that we know what swank is — and because we installed slime using apt-get at the beginning of this guide — let’s install swank-clojure:

cd ~/clj/src
git clone git://github.com/technomancy/swank-clojure.git
git clone git://github.com/technomancy/clojure-mode.git

Although Emacs package manager ELPA can install things automatically, I prefer to manage my emacs lisp files myself for sheer simplicity.

cd ~/clj/emacs
wget "http://mumble.net/~campbell/emacs/paredit.el"
wget "http://nschum.de/src/emacs/highlight-parentheses/highlight-parentheses.el"
cp ~/clj/src/clojure-mode/clojure-mode.el ./
cp ~/clj/src/swank-clojure/swank-clojure.el ./

Finally, you will need to configure emacs to use some of these files.

Alternate Method: ELPA

Emacs, like most good operating systems (such as Ubuntu), has a package manager to help install extra functionality. Emacs’ package manager is called ELPA, and can be done from within emacs following these instructions, which amount to pasting the following in the *scratch* buffer, placing the cursor after the last parenthesis, and pressing C-j:

(let ((buffer (url-retrieve-synchronously
"http://tromey.com/elpa/package-install.el")))
(save-excursion
(set-buffer buffer)
(goto-char (point-min))
(re-search-forward "^$" nil 'move)
(eval-region (point) (point-max))
(kill-buffer (current-buffer))))

That was it. Emacs installed ELPA by itself, and you can now launch ELPA from within emacs by typing:

M-x package-list-packages

Scroll down the list that appears, tapping ‘i’ to select packages you want to install. Finally, then hit ‘x’ (for execute) to install everything at once. Useful packages you would be interested in include: clojure-mode, gist, htmlize, paredit, slime, and w3.

Resources:

  1. Bill Clementson’s post describing his clojure setup (old, but interesting).
  2. Installing Clojure, Emacs, Slime, and Swank on Ubuntu linux.

Connecting to Remote Swank-Clojure

I just saw this trick over on Asymmetrical View. It is really, really simple to connect to a remote instance of Clojure running swank.

With emacs running on your local machine, and sshd and swank-clojure running on the remote host (here shown as the IP 1.1.1.1), just make an SSH tunnel between the two PCs:

ssh -L4006:localhost:4005 1.1.1.1

Then, in your local instance of emacs, run

m-x slime-connect

And connect to port 4006 on the local machine. Bada-bing! Test it out with:

(future (println "Hello remote instance"))

I chose to map remote port 4005 to local port 4006 because I usually already have an instance of the Clojure REPL running locally on 4005.


Clojure Presentation Slides

It’s hard to motivate people to learn Clojure, even when it has many benefits over C for rapidly prototyping a new program. Most people are not willing to abandon their language of choice for a new language which may have some semantic advantages that they don’t really understand (See: blub paradox). This is fine and natural: the burden should be on the advocate to show why his or her language is better than the current status quo.

I took a different approach in my Clojure advocacy: if I can convince people that they are doing things fundamentally wrong, they will be motivated to correct their mistakes, even if they don’t understand everything I am telling them at the outset. This isn’t just a rhetorical technique; I am of the opinion that would not be an exaggeration to say that Clojure has a much more ‘correct’ view of stateful programming than C, for example. Clojure is doing it better.

So, I gave a presentation at the Italian Institute of Technology, my workplace, in which I tried to destroy three principles that most programmers hold dear:

  1. Variables (because they represent a broken model of state)
  2. Syntax (because you can use lisp, which is simpler and homoiconic)
  3. Object Method Inheritance (because you can use interfaces, which compose better)

The presentation borrows heavily from presentations and publications by Rich Hickey, Fogus, and Stuart Halloway. I just remixed the content for an informal academic presentation.

You can find the slides here. I gave a “one-idea, one slide” type presentation, so without my narration it may not be particularly useful, but I thought I would throw it up on the net anyway.


Project Euler Problem 89

Problem 89 was kind of fun: we needed to convert some sloppily written roman-numerals into their more efficient, minimal representations.

There are two tricks to doing this easily:

  1. When converting from roman numerals to decimal digits, it is simplest to process the roman numeral from right to left.
  2. Since I can only be placed before V and X, X before L and C, and C before D and M, the symmetry of these results as you move up by powers of ten suggests that we use a few simple cond statements to handle numbers from 1 to 10, and recurse to handle the increasingly higher powers of ten.

The code to implement these rules wasn’t particularly long. As usual, zipmap is very concise at creating mappings from characters to digits.

(use '[clojure.contrib.duck-streams :only (read-lines)])

(def r2n (zipmap "IVXLCDM" [1 5 10 50 100 500 1000]))

(def n2r (zipmap (vals r2n) (keys r2n)))

;; Do things in reverse and it's so much easier to solve!
(defn de-romanize
  "Returns the decimal representation of a roman numeral string s. "
  ([s] (de-romanize (reverse (map r2n s)) 0 0))
  ([s total mx] (if-let [c (first s)]
                  (if (>= c mx)
                    (recur (rest s) (+ total c) (max c mx))
                    (recur (rest s) (- total c) mx))
                  total)))

(defn romanize
  "Returns the minimal roman numeral representation of n"
  ([n]
     {:pre [(<= n 10000 )]}
     (romanize (quot n 10) (rem n 10) 1))
  ([q r x]
     (if (> x 100)
       (repeat (+ q r) (n2r x))
       (->> (concat
             (romanize (quot q 10) (rem q 10) (* x 10))
             (cond
              (< r 4) (repeat r (n2r x))
              (= r 4) [(n2r x) (n2r (* 5 x))]
              (< r 9) (concat [(n2r (* 5 x))] (repeat (- r 5) (n2r x)))
              (= r 9) [(n2r x) (n2r (* 10 x))]
              :else ""))
           (apply str )))))

(defn euler-89 [file]
  (reduce
   +
   (for [l (read-lines file)]
     (- (count l)
        (count (romanize (de-romanize l)))))))

(euler-89 "roman.txt")

You may notice that I used preconditions to indicate the romanize function only works for numbers less than 10000.


Copyright © 1996-2010 Clojure Companion Cube. All rights reserved.
Jarrah theme by Templates Next | Powered by WordPress