From: Denis Hackett
Subject: LISP 'WITH-OPEN-FILE
Date: 
Message-ID: <3382FDAB.60F0@eei.ericsson.se>
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))))

From: John Wiseman
Subject: Re: LISP 'WITH-OPEN-FILE
Date: 
Message-ID: <arx67wcn9rm.fsf@gargoyle164.cs.uchicago.edu>
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
From: Gareth McCaughan
Subject: Re: LISP 'WITH-OPEN-FILE
Date: 
Message-ID: <86iv0cak8n.fsf@g.pet.cam.ac.uk>
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.
From: Lyman S. Taylor
Subject: Re: LISP 'WITH-OPEN-FILE
Date: 
Message-ID: <5m0t8a$fo@pravda.cc.gatech.edu>
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."