Hi,
I am doing some programming in Common LISP and am having difficulty in
getting the WITH-OPEN-FILE instruction to work. The problem is that it
creates the file I specify, but no data is written to the file.
Below is a copy of the function I am using, if anyone has any ideas on
how to make it work it would be very helpful.
NB: I am using GCLISP on a DOS based PC, and the file defaults to the
GCLISP directory.
Regards,
Denis.
(defun filestore (lprice) ; lpeice is a list of lists
(with-open-file (*standard-output* "report.tmp" :direction :output)
(print (car lprice))
(filestore (cdr lprice))))
Denis Hackett <······@eei.ericsson.se> writes:
>
> Hi,
> I am doing some programming in Common LISP and am having difficulty
in
> getting the WITH-OPEN-FILE instruction to work.
> (defun filestore (lprice) ; lpeice is a list of lists
> (with-open-file (*standard-output* "report.tmp" :direction :output)
> (print (car lprice))
> (filestore (cdr lprice))))
As the filestore function recurses, it keeps opening the same file
again and again without closing it (look at the macroexpansion of your
with-open-file form). I'm not surprised that this doesn't work.
When does this recursion terminate?
There's no reason to temporarily bind *standard-output*, and as a
matter of principle I would try to avoid it.
(defun filestore (lprice)
(with-open-file (price-file "report.tmp" :direction :output
:if-exists :supersede)
(dolist (price lprice)
(print price price-file))))
John Wiseman
Denis Hackett wrote:
> (defun filestore (lprice) ; lpeice is a list of lists
> (with-open-file (*standard-output* "report.tmp" :direction :output)
> (print (car lprice))
> (filestore (cdr lprice))))
Well, I don't understand.
1. I don't understand why it didn't crash or loop infinitely;
your recursion never terminates.
2. I don't understand why it didn't output anything;
the first thing it does after creating the file is to
send it some output.
3. It's trying to open the same file over and over, because
each time you enter "filestore" you're opening the file
again.
Try the following.
(defun filestore (lprice)
(with-open-file (*standard-output* <etc>)
(dolist (x price) (print x))))
--
Gareth McCaughan Dept. of Pure Mathematics & Mathematical Statistics,
·····@dpmms.cam.ac.uk Cambridge University, England.
In article <·············@eei.ericsson.se>,
Denis Hackett <······@eei.ericsson.se> wrote:
>Hi,
>I am doing some programming in Common LISP and am having difficulty in
>getting the WITH-OPEN-FILE instruction to work. The problem is that it
^^^^^^^^^^^
to be slightly more accurate it is an macro....
>
>(defun filestore (lprice) ; lpeice is a list of lists
> (with-open-file (*standard-output* "report.tmp" :direction :output)
> (print (car lprice))
> (filestore (cdr lprice))))
Two major problems here.
1. Completing ignoring the with-open-file construct in the above
you are left with
(defun filestore (lprice)
(print (car lprice))
(filestore (cdr lprice)))
Which should eventually lead to a stack overflow or an infinite
loop.. depending on how good the associated compiler is.
[ you may wish to appeal to one of the lisp iteration
constructs instead of recursion in this case. Although with a
sufficiently good compiler the tail construct about should result
to roughly equivalent code. ]
2. The file opened by the with-open-file instruction is opened at the
beginning and closed when the body of the macro is exited...
(with-open-file ( name .... )
;; file open
... body ... )
;; file closed
In the above code it would appear that the file is being repeatatively
opened over and over again. I'm pretty sure that won't lead to productive
results. If the body contains an call to a function the file is still
open.
(with-open-file ( name ... )
.....
(some-fcn name )
...... )
Here the opened stream is passed as an argument to some-fcn... where it
can be used as an argument to an I/O associated function (including
PRINT, e.g. (print "Hello world" output-stream ) ) .
In short you could use two function here. One to open the file.
and another that takes an opened stream and outputs the elements of the
list to that stream. The latter being called from within the with-open-file
of the first.
Minor problems ...
Personally I don't much care for dynamically scoped variables.
In the original code fragment above *standard-output* will take on
another value until the body of the with-open-file is exited.
This means that any expression that writes to standard-out during
this time will output to to the file and not to *terminal-io*.
Which is fine as long as you call your own code. This may
become problematical when you start to call other people's code. Or
your own code in the future.
? (defvar *foo* 23 )
*FOO*
? (defun sub-foo () (print "sub-foo") (print *foo*))
SUB-FOO
? (progn
(print *foo* )
(let ( (*foo* 10) )
(print *foo*)
(sub-foo))
(print *foo*)
'demo-done)
23
10
"sub-foo"
10
23
DEMO-DONE
?
Which tends to make most folks say "Huh? why did it do that?"...
However, some folks prefer such behavior... :-)
[ if the original function were decoupled into the two functions
mentioned previously. The one that "writes" the elements of the
list could just presume to use standard-output implicitly. where
if called directly from the listener would print to the listener
and if called from the "file opener, dynamic binder of standard-output"
would print to the file.
In some respect this is "nice". :-) ]
--
Lyman S. Taylor Comment by a professor observing two students
(·····@cc.gatech.edu) unconscious at their keyboards:
"That's the trouble with graduate students.
Every couple of days, they fall asleep."