Lisp формат и выходной сигнал

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

(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

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

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

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

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

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

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

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

  • FORCE-OUTPUT/ FINISH-OUTPUT: T - * terminal-io * и <код > NIL - * standard-output *

  • FORMAT: T есть * standard-output *

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

  (формат t "asdf" )
(финиш-ноль); обратите внимание на NIL
(setq var (чтение))
Код>