0

Suppose I got this code segment:

(defparameter *islands* '((1 9 8 5) (6 4 2 3)))

(defun edge-pair (a b)
  (unless (eql a b)
    (list (cons a b) (cons b a))))

(defun connected-with-bridges (islands)
  (when (cdr islands)
    (append (edge-pair (caar islands) (caadr islands))
            (connected-with-bridges (cdr islands)))))

Now, if I pass in the interpreter (SBCL):

(connected-with-bridges '((1 9 8 5) (6 4 2 3)))

The result is:

((1 . 6) (6 . 1))

It won't crash. However, if I pass in:

;; '(6 4 2 3) is actually (cdr '((1 9 8 5) (6 4 2 3)))
(caar '(6 4 2 3)) 

It will crash. According to (connected-with-bridges) function, the cdr of the list *islands* will be kept passing in until it can not longer proceed. The first time when *islands* is passed into (connected-with-bridges), the list will be '((1 9 8 5) (6 4 2 3). However, as the recursion goes, the 2nd time will be '(6 4 2 3), which in the (append) function, it will have:

(append (edge-pair (caar '(6 4 2 3)) (caadr '(6 4 2 3)))
                (connected-with-bridges (cdr islands)))

It obviously is crashed if I run it alone in the interpreter, but not with if it is ran inside (append), which is inside (connected-with-bridges).

Amumu
  • 17,924
  • 31
  • 84
  • 131

2 Answers2

2
;; '(6 4 2 3) is actually (cdr '((1 9 8 5) (6 4 2 3)))

No. Try it.

(caar '(6 4 2 3) (caadr '(6 4 2 3))

That's not valid Lisp.

Lisp will also not 'crash'. It will just signal an error.

SBCL also is not an interpreter. It uses a compiler.

Rainer Joswig
  • 136,269
  • 10
  • 221
  • 346
  • I know it's not valid, and it should have error, since `(car '(6 4 2 3))` returns 6 already. The line `(caar '(6 4 2 3) (caadr '(6 4 2 3))` is simply just an explanation of what is passed into the function. Perhaps I should remove it. However, if i pass the original *islands* into the function, it won't have error, or even if I pass `(6 4 2 3)` into (connected-with-bridges), there's no error. About SBCL, what's the interface where I can interact called? – Amumu Mar 05 '12 at 19:14
  • 1
    @Amumu The interface where you interact is called the REPL (read-eval-print loop). – John Pick Mar 05 '12 at 19:27
  • Ok I get it. It's '((6 4 2 3) NIL). Forgot about it. Well, I am learning Lisp, so you should give a direct answer. I thought you were talking to me about syntax error. And, I know the REPL, but what's it actually? It seems like an interpreter to me, but it's actually not? Does it compile the code behind than bring the result back to me? But still, thanks for the answer thought. – Amumu Mar 06 '12 at 00:51
  • In a compiled Lisp, that is exactly what happens. Normally you don't really have to concern yourself with whether or not the code typed on the REPL is compiled or not as the result is the same anyway. – Elias Mårtenson Mar 07 '12 at 10:29
2

(caar '(6 4 2 3)) signals an error cause you are trying to do (car 6), and 6 is not a list.

Inside your function, you dont have (caar '(6 4 2 3)), but(caar '((6 4 2 3))).

Look how cdr works: (cdr '((1 9 8 5) (6 4 2 3)))) => '((6 4 2 3)), not '(6 4 2 3) So... (caar '((6 4 2 3))) => 6, and (car '(6 4 2 3)) => 6

Do you see your mistake?

Spec
  • 817
  • 5
  • 7
  • Ah, I see. So, it's '((6 4 2 3)), not '((6 4 2 3)), so the 3rd time is (cdr '((6 4 2 3)) is NIL, and it's valid. I see now. Thanks. Sorry for the late response, I have just been back. – Amumu Mar 06 '12 at 00:46