Ongoing adventures with lisp
Can you imagine indenting code as follows in python?
    i=0, j=1
        k, l = 34, 65
            [i, k] = [k, i]
Each of these assignments corresponds to a different special form in Common
Lisp:
    (let* ((i 0)
           (j 1))
      (multiple-value-bind (k l) (values 34 65)
        (destructuring-bind (i k) '(k i)
          ...)))
Verbose and visually cluttered. When I realized returning multiple values was
turning into such a pain it was turning me off values, I created the
bind macro in response:
    (bind (i 0)
          (j 1)
          (:mv (k l) (values 34 65))
          (:db (i k) '(k i))
      :do
          ...)
Much better. Here's how I implement bind:
(defmacro bind (&rest body)
  (apply 'bind-func body))
(defun bind-func (&rest body)
  (cond ((null (first body)) (error "no :do in bind"))
        ((eq (first body) :do) `(progn ,@(rest body)))
        (t (multiple-value-bind (let-form body)
               (determine-let-form body)
             (destructuring-bind ((a b) . body) body
               (if (eq let-form 'let)
                   `(let ((,a ,b)) ,(apply 'bind-func body))
                 `(,let-form ,a ,b ,(apply 'bind-func body))))))))
(defun determine-let-form (form)
  (destructuring-bind ((a . rest) . body) form
    (cond ((eq a :db) (values 'destructuring-bind (cons rest body)))
          ((eq a :mv) (values 'multiple-value-bind (cons rest body)))
          (t (values 'let form)))))
Within lisp buffers in emacs I navigate entirely in
terms of S-expressions. C-Left and C-Right move 'horizontally' in the parse
tree to the previous or next sibling, or up the tree if that's not possible.
C-Up and C-Down move 'vertically' in the parse tree to the parent or first
child of the sexp under point. Here's how these intuitive keymappings are
implemented in my .emacs:
(defun backward-or-up-sexp ()
  (interactive)
  (if (eq (char-before (point)) ?\()
    (backward-up-list)
    (backward-sexp)))
(defun forward-or-up-sexp ()
  (interactive)
  (if (eq (char-after (point)) ?\))
    (up-list)
    (forward-sexp)))
(defun down-sexp ()
  (interactive)
  (if (member (char-after (point)) '(?\n ?\)))
    (backward-sexp))
  (down-list))
(global-set-key '(control left) 'backward-or-up-sexp)
(global-set-key '(control right) 'forward-or-up-sexp)
(global-set-key '(control up) 'backward-up-list)
(global-set-key '(control down) 'down-sexp)
...
 
footnotes
0. I prefer to use keywords rather than
argument index+indentation to highlight semantic structure.
1. For two syntactic alternatives that
don't use the 
:db and 
:mv keywords, see 
Gary King's version, coincidentally also
called bind.
 
Last updated some time in 2004