Using throw to return a value?

Discussion of Common Lisp
Post Reply
deathbyinteger
Posts: 2
Joined: Sun Dec 20, 2009 5:50 pm

Using throw to return a value?

Post by deathbyinteger » Sun Dec 20, 2009 6:31 pm

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?

ramarren
Posts: 613
Joined: Sun Jun 29, 2008 4:02 am
Location: Warsaw, Poland
Contact:

Re: Using throw to return a value?

Post by ramarren » Mon Dec 21, 2009 12:10 am

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.

deathbyinteger
Posts: 2
Joined: Sun Dec 20, 2009 5:50 pm

Re: Using throw to return a value?

Post by deathbyinteger » Mon Dec 21, 2009 6:45 am

Thank you!

Post Reply