2010-01-16 15 views
11

Non capisco perché questo codice si comporta in modo diverso in diverse implementazioni:Lisp formato e forza uscita

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

In CLISP si comporta come ci si aspetterebbe, con la richiesta stampata seguita dalla lettura, ma in SBCL legge, quindi uscite. Ho letto un po 'su internet e cambiato:

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

Questo, ancora una volta, funziona bene in CLISP, ma in esso SBCL ancora recita, poi uscite. Ho anche provato a separarlo in un'altra funzione:

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

E legge ancora, quindi emette. Non sto usando correttamente force-output o è solo un idiosincrasia di SBCL?

risposta

22

È necessario utilizzare FINISH-OUTPUT.

Nei sistemi con flussi di uscita bufferizzati, alcune uscite rimangono nel buffer di uscita finché il buffer di uscita non è pieno (quindi verrà automaticamente scritto nella destinazione) o il buffer di uscita viene espulso in modo esponenziale.

Common Lisp ha tre funzioni per questo:

  • FINISH-OUTPUT, tenta di garantire che tutto l'output è fatto e poi ritorna.

  • FORCE-OUTPUT, avvia l'uscita rimanente, ma IMMEDIATAMENTE restituisce e NON attese che venga eseguito tutto l'output.

  • CLEAR-OUTPUT, tenta di eliminare qualsiasi output in sospeso.

Anche il T in FORCE-OUTPUT e FORMAT non sono, purtroppo, lo stesso.

  • force-output/finish-output: T è *terminal-io* e NIL è *standard-output*

  • FORMAT: T è *standard-output*

questo dovrebbe funzionare:

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

grazie, ha funzionato! –

+0

Un'altra opzione, come per [Practical Common Lisp] (http://www.gigamonkeys.com/book/practical-a-simple-database.html), consiste nell'utilizzare il globale '* query-io *' invece di t o nulla. – lindes