SLIME hints #4 - slime-who-calls

June 9th, 2010

This is part of the series on SLIME functions. See the introduction for information on what SLIME is.

Just a short post today.

The slime-who-calls function (default binding "C-c C-w c") lists every function that calls the given function (default argument is the symbol under the cursor). You can press ENTER on that list to go to the listed definition. Beats using M-x rgrep for convenience, but - at least with Clojure code - it doesn't catch every call; second-order function calls aren't caught.

For those readers using Clojure, you need a pretty recent version of swank-clojure for this to work - and it seems to also list function definitions with the same name as the argument, which I think isn't correct.

SLIME hints #3b - lexical completions, also: a correction

June 4th, 2010

New code!

As I noted in yesterday's post, slime-complete-symbol normally doesn't complete locally bound "variables" (that is, function arguments and let bindings).

I've created a SLIME extension that does a pretty rough scan of the current top-level form and adds all the matching symbols in the form into the list of suggested completions. If you want to check it out, slime-complete-locals is available on github.

A correction

Also, if you missed the update on yesterday's post, make sure you add the right forms to smart-tab-completion-functions-alist - the key in that alist should be the MAJOR mode. So using slime-mode (like I did yesterday) will not work. It must be clojure-mode or whatever the major mode for your lisp editing is.

SLIME hints #3 - interactive completions and smart tabs

June 3rd, 2010

This is part of the series on SLIME functions. See the introduction for information on what SLIME is.

Today I want to address auto-completion. There are many different Emacs extensions for doing completions, but the basic functionality in SLIME is provided by the function slime-complete-symbol, which takes the symbol under the cursor and expands it, using whatever symbols are reachable at that point in the code1]. The way I have it set up is a bit tricky, though, so here's how it works:

I really prefer expansions to be bound to the TAB key. But the TAB key is also used to indent code. It's possible to have it "do what I mean", and the easiest method I found for that is to use Smart Tabs (see also the github repo).

Smart tab determines the expansion function to use based on the major mode of the current buffer*. So I've got the following in my configuration:

(require 'smart-tab) ;; make sure smart-tab.el is reachable in your load-path first
(global-smart-tab-mode 1) ;; switch on smart-tab everywhere

(setq smart-tab-completion-functions-alist
      '((emacs-lisp-mode . lisp-complete-symbol)
        (text-mode . dabbrev-completion) ;; this is the "default" emacs expansion function
        (clojure-mode . slime-complete-symbol))) ;; see update below

Now, whenever I press TAB and the cursor is at the end of a symbol, it gets expanded. If I press TAB on any other place, that indents that line.

There's a lot of stuff you can customize with expansions and auto completion, but this will give you the basics quickly and without too much hassle.

1] For Clojure code, at least, this boils down to; every symbol that is defined (or imported etc) in the current name space. This has two consequences:

  • It only applies to code that has already been loaded into the program, so you will want to compile stuff pretty much immediately once you've written or modified it.
  • It does not expand let bindings or function arguments, since those are lexically scoped and cannot be retrieved from the name space. There is probably a way to fix this, but I haven't looked into the problem that far.

* Update: the smart tab configuration must be keyed off the MAJOR mode. So slime-mode . slime-complete-symbol will not work, since slime-mode isn't a major mode. I replaced it here with clojure-mode.

SLIME hints #2 - slime-compile-and-load-file vs other slime-compile functions

May 27th, 2010

This is part of the series on SLIME functions. See the introduction for information on what SLIME is.

SLIME has a bunch of different functions that compile code from a file buffer into the running Lisp process.

I'll list a few of them here, and end with why you normally want to use slime-compile-and-load-file instead of any of the other ones.

  1. slime-eval-last-expression (default key-binding "C-x C-e") evaluates the expression right before point (the cursor). This is occasionally useful because it's a quick way to evaluate part of a larger expression. For instance, say I've got this code, with | indication the cursor position:

    (defn connection-middleware [handler]
      (fn [request]
        (with-db *db*|
          (handler request))))
    

    When I call slime-eval-last-expression, the message line at the bottom of my Emacs screen shows the value of the var *db*.

  2. slime-compile-defun (default key binding: "C-c C-c") evaluates the current definition (from the current cursor position downwards). It doesn't have to be a function definition (at least not for clojure code); all of the common (def...) forms will work. This is useful if you made a quick update to a single definition and want to load it into the current process without loading anything else.

    In other words, given the earlier code and cursor position:

    (defn connection-middleware [handler]
      (fn [request]
        (with-db *db*|
          (handler request))))
    

    Calling slime-compile-defun will evaluate the whole connection-middleware function.

  3. slime-compile-region (no default binding) evaluates whatever you've currently selected.
  4. slime-compile-and-load-file (default binding: "C-c C-k") compiles and loads the whole file.

    It's the easiest method to compile stuff since you don't need to have your cursor on any particular position, but the main reason to do this instead of, say, slime-compile-defun is that this gives you much more reasonable error messages.

    When you call any of the other compile functions, any errors you get back while compiling or later will not refer to a file and line number. This makes it a lot harder to find the error in your source code (even errors in other parts of the same file may now not refer to the right lines either, if you moved or resized your definition).

    In addition, compile errors will be noted using the standard M-n and M-p key bindings for compiler errors - in this case, using the functions (slime-next-note) and (slime-previous-note) respectively. These will navigate to the given error, and display the particular error on that line the echo buffer.

To recap, unless you want to evaluate a particular value in a source file or you're working in a "scratch" buffer with all kinds of stuff in it, you generally want to compile the whole file as a unit, since it makes the most sense if anything goes wrong.

updates: Corrected the default binding of slime-compile-and-load-file. Thanks to Don Jackson for reporting the mistake.

SLIME hints #1 - Meta-. (slime-edit-definition)

May 23rd, 2010

This is part one of the series on SLIME functions. See the introduction for information on what SLIME is.

Today's function is slime-edit-definition, which has the default key binding of Meta-.

This function is one of the most useful code-navigation tools; with the point at a function call or variable, press Meta-. and Emacs switches to the definition of that variable or function. Once you've got this in your fingers you will use it a lot. And since it uses SLIME instead of etags (for example) it works reliably for any definition that was loaded from a file (I will address this in a future post) and doesn't require any additional tools or configuration.

There's a complement function; slime-pop-find-definition-stack is bound to Meta-, and takes you back to the place you were when you called slime-edit-definition.

SLIME hints #0 - Introduction (Emacs/Lisp hacking goodness)

May 22nd, 2010

I'm starting a series of posts highlighting useful functions in Emacs/SLIME. The idea is to take one function (or a set of related functions) per post. This post is mostly here for reference in future episodes and will explain what SLIME is and why it's interesting.

What SLIME is

If you're a Lisp programmer, chances are you've seen at least some mentions of SLIME or you're already using it. If you're not, you're probably not familiar with it at all.

Basically, SLIME is an interactive Emacs mode for Lisp programming, "interactive" meaning it interacts with a running program (also called an "image" in Lisp jargon) while you're building/modifying it. There are similar modes for other programming languages (Perl, for example has at least two) but as far as I know, the concept of real "interactive" programming seems to be mostly confined to Lisp and Smalltalk and people think you're eccentric if you use it in any other language.

Why interactive modes are cool, or: where I confuse the issue on static vs dynamic. Again.

The static status quo

You're probably familiar with grand IDEs for "static" languages such as Java and C++ (and if not, you're either a hardcore "dynamic" language nerd (good for you!) or you're reading the wrong blog). With typical static languages, the idea is that the compiler will have enough information just from the source text to check variable and argument types, function or method calls, operator application, all available classes etc without running the program. This implies that a sufficiently smart program that isn't the compiler can do the same. What that means (especially for typical Java code) is that the development system will always know the ins and outs of every function call and type you're writing and can almost instantly alert you if you're misspelling a name or using the wrong argument type for a method.

Good IDEs will also use this information to let you rename or restructure functions or classes in your project with automatic updates to all the calls, for example.

The issue with dynamics

All of the above sounds cool. And it is. It just comes at the cost (typically) of having to specify all your variable and argument types, and explicitly importing those types (and the types of each element in a container type, etc) for each source file, which usually means quite a lot of your source text is just made up of type names (classes, for Java). It must be that way, because otherwise the compiler/IDE won't know what you're talking about.

This means that for languages that play loose with typing and just allow you to assign any type to any variable, or worse, redefine whatever you like (including method signatures) while the program is running you can't have any of the goodness that is the "modern IDE".

Or is it? - The revenge of dynamic languages, or: it was there all along! - sort of

The way interactive modes resolve the problem is actually quite straight forward: instead of parsing all the source text, and then making inferences about it, you can keep the program you're modifying running and then ask it what's going on. It's a technically flawed approach, for many reasons, but ("big but" joke removed) it gets the job done most of the time, and more importantly, it lets the programmer (that's you) get on with it.

Basically, what you're doing in this kind of environment is edit one or two functions in the source text, insert the new definitions into the running program and see if it works. Rinse, repeat. While you're doing that, the editor is keeping track of all the available types and functions/methods. That means you get auto-completion, source navigation etc just like a "real IDE", but without much of the hassle.

Some pointers as to what you get and with how much hassle are going to be the topics of this series.

All kinds of Lisps

Although I've used a bunch of different Common Lisp versions in the past that work with SLIME (mostly SBCL), at the moment I'm pretty much exclusively using Clojure, which is not a Common Lisp, but a fairly new addition to the Lisp language family that you can think of as a streamlined "practical" Lisp-1 if you have to. Any source/screen dumps you see on this this topic will be Clojure code unless notes indicate otherwise.

"Meta" (Emacs jargon)

If you're running Emacs on Windows or Linux, Meta is most likely the key that's typically designated "Alt" on your keyboard. On a Mac, it depends on the Emacs build, but it's probably either [alt/option/⌥] or [command/⌘]. Mainly it's just a source of confusion, but since the Emacs documentation refers to it throughout as the "Meta" key and I want to keep the actual episodes a lot shorter than this one, I will do so too in this series.

If you're still curious, the reason it's called "Meta" is that the original Lisp machines had that key. See the glorious "Space Cadet" keyboard! Marvel at its amazing modifier keys!

Using SLIME with Clojure

http://www.assembla.com/wiki/show/clojure/Getting_Started_with_Emacs should get you started if you want to use Emacs/SLIME for the Clojure language. Note that you should install swank-clojure as well if you want to use the nice SLIME stuff discussed in this series (see the 2nd to last paragraph on that page).

If you're stubborn, don't like pre-built packages and/or have your own intricate Emacs configuration like me, figure it out yourself, maybe taking some hints from my personal config.

I don't like Emacs, but I want to have a decent editor for Clojure code

See the Clojure "Getting Started" page at assembla.

Anyway, hope you find this interesting.
Joost.

Choosing your clojure startup script from Emacs/SLIME

December 3rd, 2009

The standard instructions for swank-clojure (the clojure backend to SLIME) imply you always use the same binary and/or classpath for starting your clojure code. The problem with that is that for different projects you generally want to specify at least additional classpaths and possibly even a completely different clojure version.

At the same time, most projects already contain some kind of startup/REPL script, so why not use that? swank-clojure only really needs some code that starts a repl and has the swank-clojure code in its classpath.

Below is my emacs code to do just that. Just put it somewhere in your emacs init scripts, type M-x clojure and select your startup script and away you go. The following is all my clojure-specific code, but the really "interesting" bit is the (defun clojure ...) bit.

;; this is needed because swank-clojure complains if you don't have any
;; value for this variable. When you use the clojure command it'll override
;; this value
(setq swank-clojure-binary "clj")

(require 'clojure-mode)
(require 'swank-clojure-autoload)
(require 'swank-clojure)
(require 'slime)

(add-hook 'clojure-mode-hook 'slime-mode)

(add-hook 'clojure-mode-hook 'start-paredit)

(slime-setup
 '(slime-fancy ;; turns on fancy inspector, autodoc and other useful stuff
   slime-highlight-edits)) 

(defun clojure (binary)
  (interactive "fbinary: ")
  (setq swank-clojure-binary (or binary "clj"))
  (setq slime-lisp-implementations
        `((clojure (,swank-clojure-binary) :init swank-clojure-init)))
  (slime))

My complete emacs init stuff is at http://github.com/joodie/emacs-d

Oh, before I forget: the code above does assume that you're only using SLIME with clojure and not also with other lisps. If you do need that functionality, you can probably figure out how to make it work.

Why the hell doesn’t IMovie let me save movie files?

May 24th, 2009

I like my macbook for the OS, but seriously. I just recorded 20 minutes of video and now there's no way to export it? What the bloody @!#@?

Bassline Synth sourcecode now online

March 31st, 2009

I just released the source code for the simple synthesizer, for those who are interested.

A simple synthesizer in 7.17 Kb of Flash

March 19th, 2009

Flash finally raised my curiousity by adding fully programmable audio in Flash player 10. This means you can read the currently playing audio stream to provide reasonably accurate VU meters etc, but more interesting, it means you can write your own audio-generating algorithms.

To test if flash is actually fast enough and to see if it's really possible to write flash apps using nothing but the free mxmlc compiler and emacs, I wrote a simple synthesizer in flash 10. The result is fairly pleasing.

Bassline screenshot

Check it out!