Page 1 of 1

Using throw to return a value?

Posted: Sun Dec 20, 2009 6:31 pm
by deathbyinteger
Hi. I suppose I should say I'm new to lisp first.

I found the following code in Maxima (src/commac.lisp) and was wondering why it was written this way...

Code: Select all

(defun appears (tree var)
  (cond ((equal tree var)
	              (throw 'appears t))
             ((atom tree) nil)
             (t  (appears  (car tree) var)
	         (appears (cdr tree)  var)))
    nil)

(defun appears1 (tree var)
  (cond ((eq tree var)
            	 (throw 'appears t))
	    ((atom tree) nil)
	    (t
	       (appears (car tree) var)
	       (appears (cdr tree) var)))
      nil)

(defun appears-in (tree var)
  "Yields t if var appears in tree"
  (catch 'appears
    (if (or (symbolp var) (fixnump var))   ; (fixnump var) is (typep var 'fixnum)
	(appears1 tree var)
	(appears tree var))))
I understand what it is doing (I think), but I don't understand why it was done with a throw (and a special case for eq?) rather than a naive

Code: Select all

(defun appears-in (tree var)
  (cond ((equal tree var) t)
            ((atom tree) nil)
            (t (or (appears-in (car tree) var) (appears-in (cdr tree) var)))))
I thought maybe a performance hack? I tried using (time (appears-in ...)) with long and deeply nested lists, but there didn't seem to be much difference. Can anyone tell me why the code was written this way? (Also, is there a standard function for this sort of thing?)

Thanks alot.

P.S. Apologies for the awful indentation. How do I make <pre> tags?

Re: Using throw to return a value?

Posted: Mon Dec 21, 2009 12:10 am
by ramarren
deathbyinteger wrote:I found the following code in Maxima (src/commac.lisp) and was wondering why it was written this way...
As the sourceforge page says: "Maxima is a descendant of Macsyma, the legendary computer algebra system developed in the late 1960s at the Massachusetts Institute of Technology." And much of the later development predates Common Lisp as well, which was standarized only in 1994. Much of the code in Maxima is archaic (which is not to say it doesn't work, because mathematics doesn't change, and Common Lisp contains lots of legacy stuff for a reason), because often even the code written recently is done to conform to those coding standards.

These days I would recommend not constructing trees from cons cells, since that only gives the not-so-good impression that Lisp doesn't have other datastructures, which perhaps is not a reason to care, but still, using structures/classes is often clearer. For trees there is even a TREES library.

Re: Using throw to return a value?

Posted: Mon Dec 21, 2009 6:45 am
by deathbyinteger
Thank you!