2010-01-16 15 views
11

No entiendo por qué este código se comporta de manera diferente en diferentes implementaciones:Lisp formato y fuerza de salida

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

En CLISP se comporta como era de esperar, con el símbolo impreso, seguido de la lectura, pero en SBCL lee, luego salidas. He leído un poco en internet y lo cambió:

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

Esto, de nuevo, funciona bien en CLISP, pero en SBCL que todavía lee, entonces las salidas. Incluso traté de separarlo en otra función:

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

Y aún así se lee y luego se emite. ¿No estoy usando force-output correctamente o es solo una idiosincrasia de SBCL?

Respuesta

22

Necesita usar FINISH-OUTPUT.

En los sistemas con flujos de salida con búfer, parte de la salida permanece en el búfer de salida hasta que el búfer de salida esté lleno (luego se escribirá automáticamente en el destino) o el búfer de salida se vacía explícitamente.

Common Lisp tiene tres funciones: para que

  • FINISH-OUTPUT, trata de asegurar que toda la producción se hace y luego regresa.

  • FORCE-OUTPUT, inicia la salida restante, pero INMEDIATAMENTE devuelve y NO espera a que se realice toda la salida.

  • CLEAR-OUTPUT, intenta eliminar cualquier salida pendiente.

También el T en FORCE-OUTPUT y FORMAT por desgracia no son lo mismo.

  • force-output/finish-output: T es *terminal-io* y NIL es *standard-output*

  • FORMAT: T es *standard-output*

esto debería funcionar:

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

gracias, eso funcionó! –

+0

Otra opción, según [Practical Common Lisp] (http://www.gigamonkeys.com/book/practical-a-simple-database.html), es utilizar el '' query-io * 'global en lugar de t o nil. – lindes