Archive for July, 2009

Icomplete

Friday, July 31st, 2009

I like being able to see all the possible inputs in the minibuffer. It’s one of the reasons I like ido - being able to see the possible completions inline when accessing files or buffers is just incredibly helpful. Another package I use to show minibuffer completion options is icomplete, a package that comes built-in with GNU Emacs. Icomplete will display completions in the minibuffer for all the frequently-used minibuffer commands: M-x, C-h v, C-h f, and probably a lot more that I just don’t use as much.

Icomplete will display all the possible completions you can enter in the minibuffer, much as Ido does. To enable it, you call the icomplete-mode function. The re aren’t many customizations for it: The main one you want to change is either icomplete-max-delay-chars or icomplete-compute-delay. Setting either of these to 0 will force icomplete to display completions as soon as a letter is typed. Without setting one of these, for small number of typed characters icomplete will wait for some time before displaying completions. You may want this if you have a very slow computer, but for the most part the computation is inexpensive enough you don’t notice any lag.

Icomplete+ is an third-party enhancement to icomplete. Since it doesn’t come with Emacs, you’ll have to download it from here. Icomplete+ doesn’t add new functionality; rather, it enhances the display of icomplete. It does this by changing faces for the stem and the completion candidates, as well as for the keybinding for a command you are selected. It also displays the number of completions, which can be nice to know. All in all, it makes icomplete look much nicer and I’d recommend getting it. To enable what I’ve described here, just put this in your initialization:

(icomplete-mode 1)
(setq icomplete-compute-delay 0)
(require 'icomplete+)

Refactoring Configurations

Wednesday, July 29th, 2009

I felt my init.el file was getting too bloated, so I ended up doing a fair amount of refactoring on it. I moved essentially all the code from init.el into a few directories I made in .emacs.d. Structuring your customizations is pretty important if you ever either need to go back to change them or find them to suggest to others; I do both of these a fair amount, so I spend a fair amount of time organizing my files. I probably ended up erring on the side of too many horizontal files, but I think it should be OK for now.

My .emacs.d directory now has four main elisp directories: customizations, major-modes, minor-modes, and utilities. It also has temporary information, documentation, Clojure, and hopefully everything I need to just be able to check it out and have my full working setup. The customizations and utilities directory are currently flat; They contain small files described for what they modify or are for. For example, the Ibuffer customizations I recently suggested are in ibuffer.el. This does sometimes pose organizational problems; Should changing an variable customizing a minor-mode on entering a major-mode be a customization of the minor-mode or major-mode? I currently go for the major-mode, but this could change if I ever have problems finding anything.

Major-modes and minor-modes contain precisely what they describe; All the major and minor modes I have downloaded. Packages that modify other major modes, such as dired+, do not go in these directories; they still go in the customizations file. These two directories can be arbitrarily nested - I just put the modes in however they are distributed.

After moving all the customizations out of init.el, I had the following left:

(let ((default-directory "~/.emacs.d/"))
  (add-to-list 'load-path default-directory)
  (normal-top-level-add-subdirs-to-load-path))
 
(defun load-directory (dir)
  (mapcar '(lambda (x)
             (load-file x))
          (directory-files dir t "\\.el$")))
 
(load-directory "~/.emacs.d/customizations/")
(load-directory "~/.emacs.d/utility/")

The first let expression is a simplification of something I blogged about a while ago; It will add all subdirectories of ~/.emacs.d/ to the load-path; this is necessary so that I don’t have to do manual manipulation of the load-path.

The second function is one I wrote to support my refactorings. It will load every elisp file in a directory. It doesn’t support subdirectories, but this wouldn’t be too hard to add if I ever need it. I then just load up my customizations and utility functions and am good to go. I highly recommend doing something similar to this; Splitting your customizations from one big file and aggregating similarities makes it much easier to manage your configuration.

Book Review: The Seasoned Schemer

Monday, July 27th, 2009

The Seasoned Schemer and it’s predecessor The Little Schemer, by Daniel Friedman and Matthias Fellstein, are two of the best books for learning Scheme and functional programming out there. These books are not like any other technical books you have ever read; the format is downright weird. The book is more of a conversation between an instructor and student about a set of problems than anything else, with the instructor on the left half of the page and student on the right. This is the same format that the rest of the books in this series have, such as The Little Schemer, The Reasoned Schemer, and A Little Java, A Few Patterns.

Like The Little Schemer, The Seasoned Schemer starts out easy and quickly advances the difficulty. You are expected to remember the things from The Little Schemer, so you should probably read that book first, even if you have some Scheme experience. The book starts of with introducing new variables with let and letrec, and went on the explain closures, modify state (with set!), and call-cc. The last chapter involves writing a Scheme interpreter without using data structures, just functions. +1

While the answers to all the questions asked in the book are right there, you do want to take your time and solve them yourself. Some of the things covered in this book are quite complicated and hard to understand if you only read the solutions and not find them yourself, like the derivation of the applicative-order imperative Y combinator. The book isn’t too long, so it should only take you a week or so to finish it anyway, and working through the exercises really helps your understanding. This series is actually one of my favourites for learning scheme; I would highly recommend reading it, even if you aren’t going to be doing much Scheme programming, just to expand your horizons.

Emacs Utility Functions

Saturday, July 25th, 2009

I’ve ended up migrating a few of my old functions back to my new setup, as well as creating a few newer ones. These are the ones I’ve added recently - maybe they’ll be useful to you, as well.

I’ve been doing a few book reviews recently, and instead of having to manually add in links I just wrote a function to generate a link based on the ASIN I give it. If you end up using something like this, you’ll probably want to change it so that it links to your Amazon Associate’s account, although I won’t complain if you don’t.

(defun insert-amzn-product (asin)
  "Inserts a link(image + text to an Amazon product using the ASIN"
  (interactive "MAsin:")
  (insert
   (concat "<iframe src=\"http://rcm.amazon.com/e/cm?t=randmusiofaso-20"
           "&o=1&p=8&l=as1&asins="
           (replace-regexp-in-string "\\n" "" asin)
           "&fc1=000000&IS2=1&lt1=_blank&m=amazon&lc1=0000FF&"
           "bc1=000000&bg1=FFFFFF&f=ifr\" style=\"width:120px;height:240px;\""
           "scrolling=\"no\" marginwidth=\"0\" marginheight=\"0\""
           "frameborder=\"0\"></iframe>")))

I like to be able to know how many words are in a buffer, so I found the following function somewhere online. It just runs ‘wc -w’ as a shell command on the contents of the current buffer, which outputs the number of words.

(defun wc nil
  "Count words in buffer"
  (interactive)
  (shell-command-on-region (point-min) (point-max) "wc -w"))

I sometimes use different editors on the same files, and end up having broken indentation a lot of the time this happen. I wrote iwb (for indent-whole-buffer) to fix indentation problems.

(defun iwb ()
  "Indents the entire buffer"
  (interactive)
  (indent-region (point-min) (point-max) nil))

This function I picked up from Steve Yegge’s blog. It prompts for a directory and then moves the buffer you are editing and the associated file to that directory

(defun move-buffer-file (dir)
  "Moves both current buffer and file it's visiting to DIR."
  (interactive "DNew directory: ")
  (let* ((name (buffer-name))
	 (filename (buffer-file-name))
	 (dir
	  (if (string-match dir "\\(?:/\\|\\\\)$")
	      (substring dir 0 -1) dir))
	 (newname (concat dir "/" name)))
    (if (not filename)
	(message "Buffer '%s' is not visiting a file!" name)
      (progn
	(copy-file filename newname 1)
	(delete-file filename)
	(set-visited-file-name newname)
	(set-buffer-modified-p nil) 	t))))

Eproject

Friday, July 24th, 2009

Eproject.el is a simplistic project management tool. It doesn’t have much functionality, but what it does have is just what I want: a fast way to switch between files in a project. Eproject also comes with a few other utilities, like the ability to keep track of project metadata, or a utility that opens all files in a project. However, there are two main uses: project-specific hooks and ido-based switching on other project files.

Eproject doesn’t define project types for you; you have to do this yourself. For example, to define a java project you could have the following project definition:

(define-project-type java (generic)
 (look-for "build.xml")
 :relevant-files ("\\.java" ))

Whenever you open a java, this will first look for a build.xml somewhere up the source tree. All files above that in the source tree that match the relevant-files regexp. If the file you opened is in the project, eproject-minor-mode will turn on. You can also define projects to inherit from other projects to look for metadata; inheriting from (generic) will provide all metadata you need for a complete project. You can also define your own selector, using something other than look-for and a regex, although this solution is usually pretty good.

Eproject-minor-mode will bind two additional keys - C-x C-f, and C-x C-b. C-x C-f will call eproject-find-file, which will present an ido menu containing all the files in the project - quite handy if you need to switch to a file in a different directory. C-x C-b will open an ibuffer window containing only files in the current project - I haven’t yet used this, but it will allow you to do things like query-replace over your entire project.

How do you enable eproject? Well, after downloading it and adding it’s location to your load-path, just say:

(require 'eproject)

For more information on it, check out the github page at http://github.com/jrockway/eproject/tree/master. There’s also a lot of usage documentation in the top of eproject.el that you might want to read to get a better idea of how it works.

Book Review: Beautiful Code

Thursday, July 23rd, 2009




I just finished reading Beautiful Code, from O’Reilly. It isn’t like most technical books; like the others in the ‘Beautiful’ series, it’s more a collection of essays on a topic than a book. This is probably a better format than a book for these types of issues - there isn’t really one way for code to be beautiful, and so O’Reilly figured that the best way to transmit what beautiful code is was to get a wide range of opinions.

Beautiful Code has 33 essays by different - and very talented - software developers. Some of the more famous ones are Brian Kernighan, Matz, andd Greg Kroah-Hartman. Whether you read the essays in order or sporadically doesn’t matter - There is no dependence on previous chapters in any of the essays. Essays are on average less than 20 pages long, making them easily readable in short sittings. The overarching topic is code, not architecture, although some of that makes it in the book as well, so almost every chapter has code fragments that are being discussed.

Not all of the essays are going to be interesting to every person, although I still read all of them. For example, I didn’t particularly enjoy the essays on code written in bioinformatics packages. I do suspect that every person will like a different subset of the essays, and enough of them are incredibly good to make the book well worth reading.

My favourite essays in the book would have to be Brain Kernighan’s ‘A Regular Expression Matcher’, Andrew Kuchling’s chapter on Python’s dictionary implementation, and Andreas Zeller’s essay on delta debugging. These were very informative and gave very good examples of what beautiful code is, as well as in the last case a very cool idea for automated debugging. There were no more than five essays I was really not interested in, leading to a very interesting read.

All in all, Beautiful Code is well worth reading. It has contributions from the C, Lisp, Emacs, Haskell, Perl, and Python communities, as well as others. It gives a wide range of things to consider when making code beautiful, and many of the chapters explain very interesting concepts, such as implementing scheme’s hygienic macros, instead of small code samples that aren’t used anywhere outside the book. I’m glad I read it.



Dired

Wednesday, July 22nd, 2009

Dired is Emacs’s very powerful directory browsing and management package. To use it, just type ‘C-x d’ and select a directory; the directory will be displayed in a dired buffer. In this dired buffer, you can mark files either with ‘m’ or by more advanced option, such as by regexp. You can perform very powerful commands such as renaming groups of files by regexp. Dired is actually a huge package, so I’ll only go into a few of the most useful parts of it here; you really should read the manual on it.

Dired can perform operations on either individual files or groups of files that you have marked. The main ways of marking files are by selecting individual files and pressing ‘m’ (’u’ unmarks), or ‘% m’, which prompts for a regexp and matches all files matching that regexp. There are also options for marking temporary files, all directories, symlinks, etc.

Dired also lets you operate on either the current file, if no files are marked, or all marked files. The most useful operation is ‘Q’, which does a query-replace on all selected files. You can copy or move groups of files using ‘C’ and ‘R’. You can also execute shell commands on them, using !. This prompts you for a shell command to execute; if you say something without a ‘*’, such as just ‘cat’, it will run the shell command and display the output in a different buffer. Otherwise, a ‘*’ in the command will be replaced with the filenames.

Like I said, there is a huge amount to Dired, and so you should explore it on your own to find out what is available. If you have menus enabled, you can explore those to find out some of the options.

There are also two additional packages that you probably want, both of which come with GNU Emacs. Dired-x adds additional functionality to dired. Really, I mostly just use it for it’s ability to provide default shell commands to execute on files, but this is enough (actually, looking at the documentation, there’s a few other things I use that are actually from it. Just goes to show how well it integrates with dired). To enable dired-x features, add the following to your initialization file:

(require 'dired-x)

The other package you will want to install is wdired, which allows you to edit dired buffers and have the changes reflected in the filesystem. Once you enter wdired-mode, you can edit filenames using all you emacs commands, and they will be saved - including into any subdirectories added by adding ‘/’ to the filepath. If you set the permissions like I do, you can also edit the permissions. You need some way to get to wdired-mode from dired, so add the following to your .emacs file to be able to just press ‘r’ in dired mode. Once you are finished in wdired-mode and want to save your changes, simply do ‘C-x C-s’ like you are saving a regular buffer and you will switch back to dired.

(require 'wdired)
(setq wdired-allow-to-change-permissions 'advanced)
(define-key dired-mode-map	      	      (kbd "r")		'wdired-change-to-wdired-mode)

I use dired a lot, and so find it very annoying when my dired buffers get out of sync with my filesystem. I help fix this problem using the following pieces of advice around the major buffer-switching and buffer-displaying code. Once switching or displaying the buffer, it refreshes the buffer contents if it is dired-mode. This isn’t perfect - if the filesystem gets out of sync while you are in the dired buffer, it will remain out of sync until you switch to a different buffer - but I haven’t had problems with that so far.

(defadvice switch-to-buffer-other-window (after auto-refresh-dired (buffer &optional norecord) activate)
  (if (equal major-mode 'dired-mode)
      (revert-buffer)))
(defadvice switch-to-buffer (after auto-refresh-dired (buffer &optional norecord) activate)
  (if (equal major-mode 'dired-mode)
      (revert-buffer)))
(defadvice display-buffer (after auto-refresh-dired (buffer &optional not-this-window frame)  activate)
  (if (equal major-mode 'dired-mode)
      (revert-buffer)))
(defadvice other-window (after auto-refresh-dired (arg &optional all-frame) activate)
  (if (equal major-mode 'dired-mode)
      (revert-buffer)))

That’s all the customizations I have for dired currently, but there are still other packages that don’t currently come with Emacs that customize it further, such as dired+. I’d recommend going here and looking for further customizations you like, as well as reading the dired manual to find more information on it.

Updating Imenu for Java 1.5

Tuesday, July 21st, 2009

NOTE: In the following regex’s, some strings are broken into two lines. This is due to a C-M character that renders as a newline in wordpress - It looks like ^M in emacs.

While coding in Java for work, I realized that the default imenu indexing for java was not sufficient. I usually use Imenu for jumping to a function in the same file (as opposed to CTags or something like that), and it didn’t load every function into the index. After some experimentation, I found that the problem occurred when either generic types were used or annotations were on the parameters of the functions. Since I’ve started using the @NonNull annotation and Findbugs frequently, this was a problem.

After digging around Imenu’s preferences, it seems the problem was in the variable imenu-generic-expression. If no function is specified for imenu-extract-index-name-function (which is not by default in Java-mode),
imenu-generic-expression is used to determine the name of the function. The implementation is essentially to go to the end of the buffer, repeatedly call beginning-of-defun, and use the regex stored in imenu-generic-expression to parse out the function name. This regex is originally set somewhere in the Emacs code base as the following for java-mode:

"[[:alpha:]_][][.[:alnum:]_]+[ 	\n
]+\\([[:alpha:]_][[:alnum:]_]+\\)[ 	\n
]*([ 	\n
]*\\([][.,[:alnum:]_]+[ 	\n
]+[][.,[:alnum:]_][][.,[:alnum:]_ 	\n
]*\\)?)[.,[:alnum:]_ 	\n
]*{"

Realizing that I would have to modify this regexwas not very encouraging, but breaking it into separate pieces and puzzling over the meaning came up with the following commented regex. While still ugly, it is at least no longer as confusing:

(concat
    "[[:alpha:]_]"                    ;start of type
    "[][.[:alnum:]_]+"                 ;end of type
    "[ \t\n
]+"                      ;whitespace
    "\\([[:alpha:]_][[:alnum:]_]+\\)" ;captured function name
    "[ \t\n
]*"                      ;whitespace
    "("                               ;start of arg list
       "[ \t\n
]*"                   ;whitespace
       "\\("
           "[][.,[:alnum:]_]+"        ;type
           "[ \t\n
]+"               ;whitespace
           "[][.,[:alnum:]_]"         ;start of var name
           "[][.,[:alnum:]_ \t\n
]*" ;end of var name, space
       "\\)?"
    ")"                               ;end of arg space    "[.,[:alnum:]_ \t\n
]"*"         ;throws declarations and whitespace
    "{"                               ;open brace

With this done, it was fairly easy to transform into a regex that accepted generics and annotations by adding <, >, space, and @ in the appropriate places. While this will find some malformed functions, I’m OK with this - It still has to be located at the beginning of a function for a name to come up, in which case even if I made a type I want to be able to jump there. The modified regexp ended up looking like this:

(concat
    "[[:alpha:]_]"                       ;start of type
    "[][.[:alnum:]_<> ]+"                ;type
    "[ \t\n
]+"                         ;whitespace
    "\\([[:alpha:]_][[:alnum:]_]+\\)"    ;funname
    "[ \t\n
]*"                         ;whitespace
    "("
    "[ \t\n
]*"                         ;whitespace
       "\\("                             ;argument list
 
           "[][.,[:alnum:]_@<> ]+"       ;annotations/type
           "[ \t\n
]+"                  ;whitespace
           "[][.,[:alnum:]_]"            ;start of var name
           "[][.,[:alnum:]_@<> \n\t
]*" ;end of var name
       "\\)?"
     ")"
    "[.,[:alnum:]_ \t\n
]*"             ;more whitespace, throws declarations
    "{"                                  ; begin fun
   )
)

This still leaves the problem of having this be automatically defined in java-mode, but any experienced emacs user will know how to do this: hooks! Specifically, adding a function that sets imenu-generic-expression to the correct value to java-mode-hook will automatically execute whenever a java buffer is entered.

(add-hook 'java-mode-hook '(lambda ()
 (setq imenu-generic-expression
 `((nil
    ,(concat
    "[[:alpha:]_]"                       ;start of type
    "[][.[:alnum:]_<> ]+"                ;type
    "[ \t\n
]+"                         ;whitespace
    "\\([[:alpha:]_][[:alnum:]_]+\\)"    ;funname
    "[ \t\n
]*"                         ;whitespace
    "("
    "[ \t\n
]*"                         ;whitespace
       "\\("                             ;argument list
           "[][.,[:alnum:]_@<> ]+"       ;annotations/type
           "[ \t\n
]+"                  ;whitespace
           "[][.,[:alnum:]_]"            ;start of var name
           "[][.,[:alnum:]_@<> \n\t
]*" ;end of var name
       "\\)?"
     ")"
    "[.,[:alnum:]_ \t\n
]*"             ;more whitespace, throws declarations
    "{"                                  ; begin fun
   )
 1)
  ))))

Why the old regex is still in emacs itself I don’t know: It is obviously from Java 1.4, which didn’t have templates or annotations, but Java 1.5 has been out for a while. This new version will catch all the occurrences that would be caught by the old regex, so don’t worry about compatibility issues. I submitted a patch to fix this to the emacs-devel mailing list - this seems like something that should be fixed in the main distro - so we’ll see whether or not this will make it in or not.

Initial Thoughts on Clojure

Monday, July 20th, 2009

So if you’ve been following my blog, you know that I’ve been playing around with Clojure. I’ve written enough of it to feel comfortable writing my initial thoughts on it, so here they are.

The Good
Clojure has good interoperability with Java, so calling most Java libraries is quite easy. This is it’s main selling point, of course: many people have issues with Lisp not having standard libraries and so not being portable across implementations, but Clojure comes with a full set of libraries built-in. The java interop is natural, with you being able to either call java methods on objects with the class you are operating on at the start of the argument list:

(. 3 toString)

Or at the start:

(.toString 3)

The first is used more widely, especially with the .. macro that allows you to chain calls on functions:

(.. 3 toString getBytes)

Is equivalent to

(.getBytes (.toString 3))

Clojure also uses few parentheses than other lisps: forms which don’t really need parenthesis around them, such as let or cond, have had their extraneous parens removed. Instead of

(cond ((> num 0) 1)
        ((< num 0) -1)
        ((= num 0) 0))

In clojure, you have:

(cond (> num 0) 1
       (< num 0) 0
       (= num 0) 0)

which I find easier to scan. Clojure’s use of vectors and [] to specify bindings also helps reading the code, allowing you to more quickly see where the bindings begin and end. These additions just make the language easier to read.

The way to specify multiple argument lists for Clojure functions is clear, although a bit verbose. I like the python method of being able to specify default arguments in the argument list directly, but Clojure’s is pretty good as well. The way it works is that defn has a form where you can specify what hapens for each argument list, e.g.

     (defn make-rectangle
       ([width height] {:width width :height height})
       ([width] (make-rectangle width width)))

This function will accept either 1 or 2 arguments, defaulting to the second argument being the value of the first if it is not provided. This pattern follows the Java/C# pattern of implementing method overloading, where the methods with fewer arguments call the primary overloaded method.

Clojure makes creating simple anonymous functions easy with the #( reader macro. It’s simple: #( will start an anonymous function where the arguments are reference by %n, where ‘n’ is the nth argument. % alone stands for the first argument. For example:

(defn make-eql [num]
      #(= num %))

Just returns an anonymous function that will compare its argument to num. While for more complicated anonymous functions you will need to use the fn special form, in most cases I find that anonymous functions do not need to be very complex.

Clojure has only one namespace for functions and variables, like Scheme and unlike Common Lisp. This is the main reason I prefer working in Scheme to CL, so the fact that Clojure decided to use only one namespace is amazing. Not having to funcall every variable that has a function stored in it makes me happy.

Clojure has syntax for a few data structures, namely lists(of course), vectors, maps, and sets. These are implemented as functions, which saves a great deal of effort. Instead of having to do something like

(elt [1 2 3] 1)

to get the element at index 1, in Clojure you would just do

([1 2 3] 1)

Similarly for maps: To define and use these, you can just do

(def my-map {:foo 1 :bar 2})
(my-map :bar)

Since I had to use maps extensively while working in Clojure so far, this easy syntax for them is very nice. This is actually true of pretty much all languages - hashmaps are one of the most useful data types.

The Bad
There is, unfortunately, a fair amount of things that make Clojure a pain to work in. Most egregious of these are the error messages you get when something fails - which is precisely when you need the most information. For example, here’s one error message I got while developing the AVL tree in it’s entirety:

java.lang.IllegalArgumentException: Don't know how to create ISeq from: Integer
No Line Number

No message.
  [Thrown class java.lang.ClassCastException]

Restarts:
 0: [ABORT] Return to SLIME's top level.

Backtrace:
[No backtrace]

I never actually managed to figure out why this was occurring, instead rewriting the offending section in a different way. While a lot of the errors gave more information than this one(which isn’t hard), many of them didn’t provide any *useful* information, such as the following backtrace:

  0: clojure.lang.LazySeq.sval(LazySeq.java:47)
  1: clojure.lang.LazySeq.seq(LazySeq.java:56)
  2: clojure.lang.RT.seq(RT.java:439)
  3: clojure.core$seq__3750.invoke(core.clj:103)
  4: clojure.core$print_sequential__5992.invoke(core_print.clj:42)
  5: clojure.core$fn__6077.invoke(core_print.clj:136)
  6: clojure.lang.MultiFn.invoke(MultiFn.java:161)
  7: clojure.core$pr_on__4779.invoke(core.clj:2019)
  8: clojure.core$pr__4782.invoke(core.clj:2029)
  9: clojure.lang.AFn.applyToHelper(AFn.java:173)
 10: clojure.lang.RestFn.applyTo(RestFn.java:137)
 11: clojure.core$apply__3860.doInvoke(core.clj:390)
 12: clojure.lang.RestFn.invoke(RestFn.java:428)
 13: clojure.core$pr_str__5146.doInvoke(core.clj:2761)
 14: clojure.lang.RestFn.invoke(RestFn.java:413)
 15: swank.core$send_repl_results_to_emacs__450.invoke(core.clj:54)
 16: swank.commands.basic$eval__969$listener_eval__971.invoke(basic.clj:55)
 17: clojure.lang.Var.invoke(Var.java:346)
 18: user$eval__10400.invoke(NO_SOURCE_FILE)
 19: clojure.lang.Compiler.eval(Compiler.java:4601)
 20: clojure.core$eval__4610.invoke(core.clj:1730)
 21: swank.core$eval_in_emacs_package__453.invoke(core.clj:58)
 22: swank.core$eval_for_emacs__530.invoke(core.clj:126)
 23: clojure.lang.Var.invoke(Var.java:354)
 24: clojure.lang.AFn.applyToHelper(AFn.java:179)
 25: clojure.lang.Var.applyTo(Var.java:463)
 26: clojure.core$apply__3860.doInvoke(core.clj:390)
 27: clojure.lang.RestFn.invoke(RestFn.java:428)
 28: swank.core$eval_from_control__456.invoke(core.clj:65)
 29: swank.core$eval_loop__459.invoke(core.clj:70)
 30: swank.core$spawn_repl_thread__591$fn__622$fn__624.invoke(core.clj:179)
 31: clojure.lang.AFn.applyToHelper(AFn.java:171)
 32: clojure.lang.AFn.applyTo(AFn.java:164)
 33: clojure.core$apply__3860.doInvoke(core.clj:390)
 34: clojure.lang.RestFn.invoke(RestFn.java:428)
 35: swank.core$spawn_repl_thread__591$fn__622.doInvoke(core.clj:176)
 36: clojure.lang.RestFn.invoke(RestFn.java:402)
 37: clojure.lang.AFn.run(AFn.java:37)
 38: java.lang.Thread.run(Thread.java:619)

(OK, I promise not to include any more full stack traces). I got this stack trace while testing tree insertion. Do you notice anything funny about the stack trace? It’s pretty easy to miss if you aren’t looking for it, so don’t feel bad if you don’t. This actually has no references to code that I wrote. The entire thing is refers to clojure, java, and swank functions, none of which I care about, instead of the stack trace for the code *I* wrote, which I did. I did manage to find out where this was happening: Apparently, if an error is thrown in the body of a ‘for’ loop, the trace information from the body of the for is lost. To try this yourself, evaluate the following:

(defn foo []
  (throw (java.lang.Exception.)))
(for [x '(1)]
     (foo))

And see the lack of a call to foo in your stack trace.

This is a consistent problem across Clojure’s errors: many errors from it don’t provide even a line number when called from SLIME. This isn’t even just a few of them, either; it looks like every error that deals with syntax doesn’t tell you the line number of where the error occurred This happens when you use () for binding instead of [], when you have an extraneous paren somewhere in your code(these can be pretty annoying to find without a line number), when your if has too many arguments, etc. While trying these on clojure.lang.repl *does* give information about line numbers, This information doesn’t appear to be part of the exception and so isn’t shown when you error from something you can actually use.

This issue is the main problem I have with clojure. The lack of usable information on errors can just make it a pain to work with, even though I like the language itself. I’m not sure how the REPL displays line numbers, and my SLIME *is* connecting to the same jar file I used to get line numbers for syntax errors, so apparently there is something built-in that can’t be taken advantage of by external editors, which is very unfortunate. Even the errors which do have line numbers and stack traces make the information difficult to find by burying it with all of the calls to ‘eval’ and such that clojure uses behind the scenes.

A more minor issue is that Clojure lacks forward declaration, so you have to (declare) everything up at the top if you want to be able to rearrange code however you want. This isn’t a huge deal, but it can get pretty annoying.

The lack of implied tail-call optimization bugs me, but it’s something I can live with. It isn’t too difficult to remember to use recur or trampoline, and I can understand why it might be better to have to programmer specify all the time they want to do TCO, instead of having the compiler figure it out for a subset of these calls. I would like the JVM to introduce a whatever new bytecode is necessary so that implied TCO is possible in all cases, though. This didn’t come up in my projects, but it could have if I had tested on a tree with, oh, 2^1024 or so nodes.

I would also like Clojure to have programmable reader macros, even though it wouldn’t have helped much on this project. The clojure designers realize that reader macros can be very useful - they have a few built-in to the reader, such as for sets, anonymous functions, and regexs - but do not allow regular programmers the luxury of defining their own. I understand why, and for the most part it’s a philosophical difference, so this isn’t that big of a deal to me.

Overall, I do like Clojure, despite it’s terrible error messages. It also looks like the Clojure guys are aware this is an issue and trying to fix it, as well, so hopefully this will be a lot better soon. I’m definitely going to keep using Clojure at least a bit, though I’m not sure whether I’ll make it one of my primary programming languages yet.

Ibuffer: Dired for Buffers

Sunday, July 19th, 2009

Ibuffer is a massive improvement on the buffer-menu function which is brought up by C-x C-b.It allows dried-like manipulations of your buffers, as well as font locks and sorting. It’s actually better than buffer-menu in pretty much every way, so if you haven’t switched to using it instead, I would highly recommend it. One of the more useful things it lets you do are: file buffers by major-mode, and then performing a replace-regexp on all marked files. You can select buffers by major mode using %m, and Q with then start a query-replace.

Another useful feature of ibuffer is it’s filtering, with ‘/’ as a prefix. Once you open ibuffer, you can filter the results down and operate on subgroups of buffers. For example, /n emacs will only show buffers in with ‘emacs’ in the buffer-name. You can also change the sort order with ’s’. Like Dired, * and % prefixes work for marking buffers.

Setting ibuffer up is relatively easy, although there is a ton of configuration you can do if you want. I’ll tell you about what I do, which is fairly minimal, but M-x customize-group ibuffer will give you all the ways to customize ibuffer. To use ibuffer instead of buffer-menu, add the following to your initialization:

(require 'ibuffer)

This just loads ibuffer. It comes with GNU Emacs, so you should already have the library without having to download it.

(setq ibuffer-default-sorting-mode 'major-mode)

This options control how lines in the ibuffer window are grouped. By specifying the sorting mode as ‘major-mode, I indicate that I want ibuffer to group buffers of the same type together. Another common sorting order is ‘recency, which orders them from most recently viewed to last viewed. Other options include ‘lexographic, ‘buffer-size, and ‘file-name.

(setq ibuffer-always-show-last-buffer t)
(setq ibuffer-view-ibuffer t)

These lines specify to ibuffer which buffers should be in the ibuffer menu. The first line specifies that it should always show the last buffer we were in, even if it would usually hide it. The second line specifies that the *Ibuffer* buffer itself should be in the buffer list - I just like having a complete list of my buffers to start with.

(global-set-key  (kbd "C-x C-b")        'ibuffer-other-window)

Since ibuffer is so much better than buffer-menu, you should just replace the C-x C-b keybinding to call ibuffer instead of buffer-menu.