From: Bruno H. <br...@cl...> - 2018-11-11 23:50:18
|
Sam asked: > I discovered > that `with-open-file' is implemented differently in CLISP and SBCL: > > (LET ((A (OPEN "f"))) > (DECLARE (SYSTEM::READ-ONLY A)) > (UNWIND-PROTECT (MULTIPLE-VALUE-PROG1 (PROGN (PRINT 1 A)) (WHEN A (CLOSE A))) > (WHEN A (CLOSE A :ABORT T)))) > > vs > > (LET ((A (OPEN "f")) (#:G368 T)) > (UNWIND-PROTECT (MULTIPLE-VALUE-PROG1 (PROGN (PRINT 1 A)) (SETQ #:G368 NIL)) > (WHEN A (CLOSE A :ABORT #:G368)))) > > The second version produces a marginally smaller bytecode (probably > unimportant) and seems slightly more aesthetic (calls CLOSE only once). > > Why did you choose the first version? I did so for reliability. When the disk gets full, this produces an error condition. Most often, the error condition will occur during the body that produces output. But recall that a file-stream is most often buffered, and that means that some output is still waiting in the buffer until the final (CLOSE A) call; if the disk full error only occurs in this last file system access, * the clisp variant will execute the protection clause (CLOSE A :ABORT T) and thus do as specified in ANSI CL [1]: "the file system is left, so far as possible, as if the file had never been opened." * the sbcl variant will not execute (CLOSE A :ABORT T) and thus leave a file on the (full) disk that is truncated. WITH-OPEN-FILE was designed to avoid leaving truncated files on disk, and an implementation should better achieve this goal in 100%, not 99%, of the cases. Bruno [1] http://www.ai.mit.edu/projects/iiip/doc/CommonLISP/HyperSpec/Body/mac_with-open-file.html |