I am trying to learn Common Lisp by reading Paul Graham's Ansi Common Lisp and using the EEC325 course critical functions and check functions and lectures. I created Emacs with Slime and SBCL
The problem in exercise 8 of chapter 8 is:
Define a function that takes a list and prints it in dotted notation:
> (showdots ' ( abc)) (A . (B . (C . NIL))) NIL
I made the following function so that the result is a string, and it works well for cases, but does not print, which is the main goal of the exercise.
(defun show-dots (lst) (cond ((atom lst) (format nil "~A" lst )) ((consp lst) (format nil "(~A . ~A)" (show-dots (car lst)) (show-dots (cdr lst))))))
The problem is that it creates a line that does not print the line but works
CS325-USER> (SHOW-DOTS '(ABC)) "(A . (B . (C . NIL)))" CS325-USER> (SHOW-DOTS '(A (BC))) "(A . ((B . (C . NIL)) . NIL))" CS325-USER> (SHOW-DOTS '(A . B)) "(A . B)" CS325-USER> (SHOW-DOTS NIL) "NIL" CS325-USER> (SHOW-DOTS '(NIL)) "(NIL . NIL)"
The test is awaiting printing, so it actually fails, but it is obvious that problems arise when printing the result
(run-tests show-dots) SHOW-DOTS: (SHOW-DOTS '(ABC)) failed: Should have printed "(A . (B . (C . NIL)))" but saw "" SHOW-DOTS: (SHOW-DOTS '(A (BC))) failed: Should have printed "(A . ((B . (C . NIL)) . NIL))" but saw "" SHOW-DOTS: (SHOW-DOTS '(A . B)) failed: Should have printed "(A . B)" but saw "" SHOW-DOTS: (SHOW-DOTS NIL) failed: Should have printed "NIL" but saw "" SHOW-DOTS: (SHOW-DOTS '(NIL)) failed: Should have printed "(NIL . NIL)" but saw "" SHOW-DOTS: 0 assertions passed, 5 failed.
so I thought that the only thing I have to do is print this line after creation, but it doesnβt work, and I donβt understand why
1) attemp
(defun show-dots (lst) (cond ((atom lst) (format t "~A" lst )) ((consp lst) (format t "(~A . ~A)" (show-dots (car lst)) (show-dots (cdr lst))))))
with these results
CS325-USER> (SHOW-DOTS '(ABC)) ABCNIL(NIL . NIL)(NIL . NIL)(NIL . NIL) NIL CS325-USER> (SHOW-DOTS '(A (BC))) ABCNIL(NIL . NIL)(NIL . NIL)NIL(NIL . NIL)(NIL . NIL) NIL CS325-USER> (SHOW-DOTS '(A . B)) AB(NIL . NIL) NIL CS325-USER> (SHOW-DOTS NIL) NIL NIL CS325-USER> (SHOW-DOTS '(NIL)) NILNIL(NIL . NIL) NIL
so I said βOKβ, this is the crazy first line and its print
(defun show-dots (lst) (format t (cond ((atom lst) (format nil "~A" lst )) ((consp lst) (format nil "(~A . ~A)" (show-dots (car lst)) (show-dots (cdr lst)))))))
but the result is not correct
CS325-USER> (SHOW-DOTS '(ABC)) ABCNIL(NIL . NIL)(NIL . NIL)(NIL . NIL) NIL CS325-USER> (SHOW-DOTS '(A (BC))) ABCNIL(NIL . NIL)(NIL . NIL)NIL(NIL . NIL)(NIL . NIL) NIL CS325-USER> (SHOW-DOTS '(A . B)) AB(NIL . NIL) NIL CS325-USER> (SHOW-DOTS NIL) NIL NIL CS325-USER> (SHOW-DOTS '(NIL)) NILNIL(NIL . NIL) NIL
So, I said ok, let's create a local variable, put a line there and print it, but it doesn't work again
(defun show-dots (lst) (let ((str (cond ((atom lst) (format nil "~A" lst )) ((consp lst) (format nil "(~A . ~A)" (show-dots (car lst)) (show-dots (cdr lst))))))) (format t str)))
and the result is incorrect
CS325-USER> (SHOW-DOTS '(ABC)) ABCNIL(NIL . NIL)(NIL . NIL)(NIL . NIL) NIL CS325-USER> (SHOW-DOTS '(A (BC))) ABCNIL(NIL . NIL)(NIL . NIL)NIL(NIL . NIL)(NIL . NIL) NIL CS325-USER> (SHOW-DOTS '(A . B)) AB(NIL . NIL) NIL CS325-USER> (SHOW-DOTS NIL) NIL NIL CS325-USER> (SHOW-DOTS '(NIL)) NILNIL(NIL . NIL) NIL
So, I really want to understand what is happening here, maybe this is something stupid, but I do not understand.
thank you for your time