[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: bug in assoc



As McGeer@ucbkim points out, the code for assoc is (in common0.l):

(def assoc
  (lambda (val alist)
	  (do ((al alist (cdr al)))
	      ((null al) nil)
	      (cond ((null (car al)))
		    ((not (dtpr (car al)))
		     (error "bad arg to assoc" al))
		    ((equal val (caar al)) (return (car al)))))))

The reason for the reported strange behavior of assoc is as simple as
it is obscure!  First a couple hints:
 - This code is inside the executable franz interpreter and therefore
   runs compiled.
 - The same strangeness is exhibited by assq, which is C-coded inside
   the Franz kernel.
 - Both the cdr of a dtpr and the value of an atom are stored at offset
   zero within their respective structures.  The car and plist
   similarly share the same offset within their structures.
 - If you try to run the above assoc definition interpreted, it will
   properly fail to work, or rather, it will complain about a bad arg
   to car.
 - Of course, c[ad]r in the interpreter carfully check their arguments;
   In the compiler, they simple indirect through pointers for maximum
   speed.

Finally, in case by now it isn't absolutely clear to everyone what is
going on, assoc is (sort of) comparing val against the plist of bar and
subsequently foo, and then each time automagically effectively doing a
symeval on the atom to continue scanning down the "cdr" of the alist.

Moral:  Although the interpreter tries pretty hard to do the dynamic
typing and implied typechecking for which lisp is famous, type checking
in compiled code is often a myth.  Correct code only necessarily works
correctly when given corrent arguments.

Steve Haflich
MIT Experimental Music Studio
smh%mit-ems@mit-mc
{decvax!genrad, ihnp4!mit-eddie}!mit-ems!smh