From Newsgroup: comp.lang.lisp
Erik Naggum wrote:
Let me explain why in some detail, and start with a _severely_ simplified
definition of assoc, almost a caricature, and I renamed them alist-get
and plist-get:
(defun alist-get (alist key)
(do ((alist alist (cdr alist))
(cons (car alist) (car alist)))
((or (not alist) (and cons (eq key (car cons))))
(cdr cons))))
* (alist-get '((a . 2) (b . 3) (c . 4)) 'a)
2
* (alist-get '((a . 2) (b . 3) (c . 4)) 'b)
3
* (alist-get '((a . 2) (b . 3) (c . 4)) 'c)
4
* (alist-get '((a . 2) (b . 3) (c . 4)) 'x)
4
Wrong result.
Let's look more closely.
(defun alist-get (alist key)
(do ((alist alist (cdr alist))
(cons (car alist) (car alist)))
((or (not alist) (and cons (eq key (car cons))))
(cdr cons))
(print cons)))
* (alist-get '((a . 2) (b . 3) (c . 4)) 'c)
(A . 2)
(A . 2)
(B . 3)
4
He should have used do*:
(defun alist-get (alist key)
(do* ((alist alist (cdr alist))
(cons (car alist) (car alist)))
((or (not alist) (and cons (eq key (car cons))))
(cdr cons))
(print cons)))
* (alist-get '((a . 2) (b . 3) (c . 4)) 'c)
(A . 2)
(B . 3)
4
* (alist-get '((a . 2) (b . 3) (c . 4)) 'z)
(A . 2)
(B . 3)
(C . 4)
NIL
Let's show Naggum the right way to use "do":
(define (alist-get alist key)
(do ((xs alist (cdr xs))
(r #f (and (eqv? key (caar xs)) (cdar xs))))
((or (null? xs) r) r)))
(alist-get '((a . 2) (b . 3) (c . 4)) 'a)
2
(alist-get '((a . 2) (b . 3) (c . 4)) 'b)
3
(alist-get '((a . 2) (b . 3) (c . 4)) 'c)
4
(alist-get '((a . 2) (b . 3) (c . 4)) 'x)
#f
--
[T]he problem is that lispniks are as cultish as any other devout group and basically fall down frothing at the mouth if they see [heterodoxy].
--- Kenny Tilton
The good news is, it's not Lisp that sucks, but Common Lisp. --- Paul Graham --- Synchronet 3.21a-Linux NewsLink 1.2