This is a read-only archive of lispforum.com. The forum was locked to new users and posts and is preserved here as static HTML from a database snapshot taken on 2019-09-07.

Why don't my solutions work? Specifics inside.

3 posts · 4331 views

Hi,

I'm a junior in high school learning how to program in Lisp. It's just something that I'm doing on the side, not for a course or anything. I have experience only in Java from taking the AP Computer Science class. I've just started about a week ago, and I've gotten a copy of ANSI Common Lisp and am using whatever online resources I can find. So if you guys have any suggestions for additional resources I could use or general information about what Lisp is used for nowadays or anything Lisp related, I'd be happy to listen. Anything helps. But anyways, here's my question:

I'm doing an exercise from ANSI Common Lisp that is as follows: define a function that takes a list as an argument and returns true if one of its elements is a list (using only operators introduced in chapter 2).

Here are my two solutions, neither of which work. I've seen the solution to this exercise, but I am very curious as to why my solutions don't work.
(defun islist (x) 
  (if (not (listp x))
      nil
    (or (listp (car x)) (islist (cdr x)))))
also
(defun islist (x)
  (and (listp x)
       (or (listp (car x)) (islist (cdr x)))))
If I said (islist '(a b c d)), the function should return nil, yet it always returns T. Also, my indentation may be wierd. I'm using Emacs right now and it only lets me tab a set amount per line. Whether that amount is correct or not I have no idea.

Thanks

Re: Why don't my solutions work? Specifics inside.

You need to check whether the argument X given is NIL, in which case you should return NIL.

Re: Why don't my solutions work? Specifics inside.

(defun islist (x)
  (and (listp x)
       (or (listp (car x)) (islist (cdr x)))))
Lets imagine we send it 'a as an argument. The first (listp 'a) => NIL and and will terminate
If its a list argument eg. '(a b c) '((a) b c) or even '() (listp x) will be T. Note that () which also represents false in CL is a list and thus (listp ()) => T.
To make matters even worse (cdr ()) => () so the function will never terminate.
Have you used it's sister function (consp x) which also returns T for all lists except the empty list ()/NIL, then it would work as you imagined. The following small change makes it work.
(defun islist (x)
  (and (consp x)
       (or (listp (car x)) (islist (cdr x)))))
Since there was a restriction on which functions you could use I guess a textbook example uses (not (null x)) or just (not x) instead of (consp x) but you'll loose the case where the argument is not a list at all.

I really enjoyed the book The Land of LISP so you should look it up if you're planning to learn CL.
I also enjoyed watching the video lectures of MIT programming class Structure and Interpretation of Computer Programs where they use Scheme (different dialect).

Good luck :)
I'm the author of two useless languages that uses BF as target machine.
Currently I'm planning a Scheme compiler :p