compilationlispcommon-lispsbcl

Simple repl function being compiled "out of order" with sbcl


I have this simple program

(defun testing-func ()
  (print "@Repl has Started@")
  (loop (print (eval (read)))))

(sb-ext:save-lisp-and-die #P"output-test"
   :toplevel #'testing-func
   :executable t)

Whenever I call testing-func in the REPL, it works correctly; like so:

CL-USER> (testing-func)
@Repl has Started@
1 ;;input

1 2 ;; 1 is output, 2 is input

2 3 ;; 2 is output, 3 is input

3 ;; 3 is output

but after compiling with sbcl --load testing-func.lisp, I get an output which is "out of order" with the inputs.

@Repl has Started@
1 ;; input
  ;; output
2 ;; input
1 ;; output
3 ;; input
2 ;; output

I really don't know why or how this could happen. I've also tried to get rid of the loop and strictly order by using recursion with use of let* or funcall but the same phenomenom occurs, which means that I have a fundemental misunderstanding about the compilation.


Solution

  • It has nothing to do with compilation.

    Common Lisp Streams can be buffered. You need to make sure that output is reaching the user, before you let the user type in.

    See the functions FORCE-OUTPUT and FINISH-OUTPUT in Common Lisp. FINISH-OUTPUT causes any pending output to be written to the output device and then returns.

    You need to call FINISH-OUTPUT after the output, you want to reach the output device, is done.

    (defun testing-func ()
      (print "@Repl has Started@")
      (print '---)
      (terpri)      
      (loop (finish-output)
            (print (eval (read)))
            (print '---)
            (terpri)))