Формат Lisp и принудительный вывод - PullRequest
12 голосов
/ 16 января 2010

Я не понимаю, почему этот код ведет себя по-разному в разных реализациях:

(format t "asdf")
(setq var (read))

В CLISP он ведет себя так, как и ожидалось, с напечатанной подсказкой, за которой следует чтение, но в SBCL он читает: , затем выводит. Я немного прочитал в Интернете и изменил его:

(format t "asdf")
(force-output t)
(setq var (read))

Опять же, это прекрасно работает в CLISP, но в SBCL все еще читает, затем выводит. Я даже пытался разделить его на другую функцию:

(defun output (string)
   (format t string)
   (force-output t))
(output "asdf")
(setq var (read))

И он все еще читает, затем выводит. Правильно ли я не использую force-output или это просто особенность SBCL?

1 Ответ

24 голосов
/ 16 января 2010

Вам нужно использовать FINISH-OUTPUT.

В системах с буферизованными выходными потоками некоторые выходные данные остаются в выходном буфере до тех пор, пока выходной буфер не будет заполнен (тогда он будет автоматически записан в место назначения) или пока выходной буфер не будет очищен.

Common Lisp имеет три функции для этого:

  • FINISH-OUTPUT, пытается убедиться, что все выходные данные выполнены, и ТО возвращает.

  • FORCE-OUTPUT, запускает оставшийся вывод, но НЕМЕДЛЕННО возвращается и НЕ ожидает завершения всех выводов.

  • CLEAR-OUTPUT, пытается удалить любой ожидающий вывод.

Кроме того, T в FORCE-OUTPUT и FORMAT, к сожалению, не совпадают.

  • force-output / finish-output: T равно *terminal-io* и NIL равно *standard-output*

  • FORMAT: T is *standard-output*

это должно работать:

(format t "asdf")
(finish-output nil)   ;  note the NIL
(setq var (read))
...