Arc

January 30, 2008

Just noticed an early version of arc has been released, certainly worth a look.

http://www.paulgraham.com/arc0.html

Advertisements

Climacs Milestone

January 6, 2008

Troels Henriksen rewrote the Climacs redisplay engine improving performance beyond compare. While there is alot of improvement still needed in terms of performance, features and polish, this change will make it viable for more people to use Climacs as a primary editor, so hopefully development will start to move faster.

If you haven’t tried Climacs or you were put off by its sluggish performance, now is a good time to try it out.

Human Order Sorting

December 15, 2007

There’s a post over at lispcast about developing a “human order sort” function for strings using Common Lisp. This is a very
handy utility to have, the final code looks like this:

(defun human-sort (list &key
                   (string-comparison #'string-lessp)
                   (number-comparison #'<)
                   (numbers-before-strings-p t))
  (sort list
        (make-list-comp (make-alpha-num-comp string-comparison
                                             number-comparison
                                             numbers-before-strings-p))
        :key #'split-alpha-num))

(defun make-list-comp (fun)
  (labels ((f (a b)
             (cond
               ((null b) nil)
               ((null a) t)
               ((funcall fun (first a) (first b)) t)
               ((funcall fun (first b) (first a)) nil)
               (t (f (rest a) (rest b))))))
    #'f))

(defun make-alpha-num-comp (string-comp
                            num-comp
                            nums-before-strings-p)
  #'(lambda (a b)
      (cond
        ((and (stringp a) (stringp b)) (funcall string-comp a b))
        ((and (numberp a) (stringp b)) nums-before-strings-p)
        ((and (stringp a) (numberp b)) (not nums-before-strings-p))
        ((and (numberp a) (numberp b)) (funcall num-comp a b)))))

(defun split-alpha-num (string)
  (pcond:pcond
   ((equal "" string)
    nil)
   ((:re "^(\\d+)(.*)" string ((#'parse-integer num) rest))
    (cons num (split-alpha-num rest)))
   ((:re "^(\\D+)(.*)" string (alpha rest))
    (cons alpha (split-alpha-num rest)))))

Unfortunately, the function SPLIT-ALPHA-NUM depends on PCOND which I’d rather not use. So I rewrote SPLIT-ALPHA-NUM using only standard Lisp:

(defun split-alpha-num (string)
  (mapcar #'parse-integer-if-integer
          (split-sequence-at-boundary #'digit-char-p string)))

(defun parse-integer-if-integer (string)
  (or (parse-integer string :junk-allowed t) string))

(defun split-sequence-at-boundary (predicate sequence)
  (labels ((split1 (start predicate complement)
             (let ((end (position-if predicate sequence :start start)))
               (if end
                   (cons (subseq sequence start end)
                         (split1 end complement predicate))
                   (list (subseq sequence start))))))
    (cond ((zerop (length sequence)) nil)
          ((funcall predicate (elt sequence 0))
           (split1 0 (complement predicate) predicate))
          (t
           (split1 0 predicate (complement predicate))))))

This version is longer, but it also produces SPLIT-SEQUENCE-AT-BOUNDARY which could potentially be reused in other contexts.

Alpha blending

December 7, 2007

Tom Forsyth writes about the magic of premultiplied alpha. If you use blending by cut & pasting examples but don’t know really know what you’re doing then it’s a must read. The rest of his blog is highly recommended too, notwithstanding the use of twiddlywiki.

Lambda Shortcut

November 29, 2007

I recently reread the Tutorial on Good Lisp Programming Style by Peter Norvig and Kent Pitman. One thing that surprised me was the suggestion that it “may be appropriate sometimes” to use read macros to shorten lambda expressions:

(reduce #'+ numbers :key #L(if (oddp _) (* _ _) 0))

I’ve always avoided using that idiom because it’s non standard, but seeing it in such a highly regarded style guide is enough for me to add it to my bag of utilities. Here’s my definition:

(set-dispatch-macro-character   #\# #\L #'(lambda (stream sub-character infix-parameter)
             (when infix-parameter
               (error "#~a does not take an integer infix parameter."
                      sub-character))
             `#'(lambda (,(intern "_"))                   ,(read stream t nil t))))  (I'd like to know how to prevent wordpress from mangling my code)

Practical Common Lisp

September 27, 2007

So I set up a blog and then promptly forgot about it, not a good start. I’ll endeavour to post once a month from now. Anyway, gigamonkey was asking for some link love for his book which was the real impetus behind this post.

Common Lisp tutorial
Lisp tutorial

According to Donald Knuth, Peter is now destined to write many more books, so I’ll take this opportunity to say ‘More Practical Common Lisp’ is a catchy title.

(princ “Hello world!”)

July 5, 2007

This blog will mostly be about Common Lisp.