4

I noticed that there is no format directive which would call force-output/finish-output.

Why?

It does seem to be useful in user interaction, cf. Lisp format and force-output.

E.g., ~= could translate to finish-output, and ~:= to force-output. I don't think clear-output makes much sense in this context, but we might map ~@= to it for completeness.

PS. Cf. CLISP RFE.

Rainer Joswig
  • 136,269
  • 10
  • 221
  • 346
sds
  • 58,617
  • 29
  • 161
  • 278

1 Answers1

2

Summary from comp.lang.lisp:

An explanation from Steven Haflich

The language defines no portable way to extend the set of format directives (other then ~/.../) but that's not really the issue here. The real problem is that it is not well defined to call finish-output or similar functions at arbitrary places during printing.

If pretty-printing is in progress, the stream received by a pprint-dispatch or print-object method may be an encapsulating stream -- one that delays output temporarily until it can make decisions about white space and line breaks. (There are also potential problems if finish-output were called inside a ~< justification, but that directive is a hairball!) What would one expect finish-output to do if called inside a pretty print operation? I don't think it's well defined.

The problem isn't particular to format, of course, but a directive for finish-output from format would just add another sharp edge to the language. finish-output etc. are only safe to call when completely outside an actual or implied call to cl:write. Call it as a function at an appropriate point in your code (where you know execution isn't inside a nested write) so the intention is clear and you don't mess up printer internals.

A suggestion from Rob Warnock

Actually, no changes to format are needed. Just add this function somewhere in the COMMON-LISP-USER package:

(defun fo (stream arg colon-p atsign-p &rest params)
  (declare (ignore arg params))
  (cond
    (colon-p (force-output stream))
    (atsign-p (clear-output stream))
    (t (finish-output stream))))

Then:

(progn
  (format t "enter var: ~/fo/" nil)
  (read))
enter var: 456
456 

The problems with this (portable!) approach are

  • verbosity (~/fo/ instead of ~=)
  • need to consume a format argument (nil in the example above)
sds
  • 58,617
  • 29
  • 161
  • 278