Reputation: 1157
(defun foo (mylist)
(with-open-file (str "out.txt"
:direction :output
:if-exists :append
:if-does-not-exist :create)
(if mylist
(progn
(format str (car mylist))
(foo (cdr mylist))))))
I have two questions. First one is that I can not write an element of a list by this expression (format str (car mylist))
, Secondly it produces another error as below.
already points to file
"out.txt", opening the file again for :OUTPUT may produce
unexpected results
Open the file anyway
Upvotes: 1
Views: 505
Reputation: 60014
This error is documented in the manual.
You are calling foo
recursively and each call opens the file again.
This can have very bad consequences.
You can fix it by moving the recursive call outside of with-open-file
:
(defun write-list-to-file-reopen (mylist destination)
(when mylist
(with-open-file (str destination
:direction :output
:if-exists :append
:if-does-not-exist :create)
(prin1 (pop mylist) str)
(terpri str))
(write-list-to-file-reopen mylist)))
but this is quite inefficient because open
is a relatively expensive operation.
A much better solution would be to iterate
(defun write-list-to-file-iterate (mylist destination)
(with-open-file (str destination
:direction :output
:if-exists :append
:if-does-not-exist :create)
(dolist (el mylist)
(format str "~S~%" el))))
or, if you are require to use recursion,
(defun write-list-to-file-recursion (mylist destination)
(with-open-file (str destination
:direction :output
:if-exists :append
:if-does-not-exist :create)
(labels ((write-list (list)
(when list
(prin1 (pop list) str)
(terpri str)
(write-list list))))
(write-list mylist))))
Function format
is relatively
heavy weight and intended for interactive pretty printing, you might
prefer to use simpler functions like write
.
Your problem is because your (format str x)
should be (format str "~S~%" x)
:
you forgot the format string.
Upvotes: 4