a REPL with structured output (for programs) reads forms to eval from in-reader (a LineNumberingPushbackReader) Closing the input or passing the form :repl/quit will cause it to return Calls out-fn with data, one of: {:tag :ret :val val ;;eval result, or Throwable->map data if exception thrown :ns ns-name-string :ms long ;;eval time in milliseconds :form string ;;iff successfully read :exception true ;;iff exception thrown } {:tag :out :val string} ;chars from during-eval *out* {:tag :err :val string} ;chars from during-eval *err* {:tag :tap :val val} ;values from tap> You might get more than one :out or :err per eval, but exactly one :ret tap output can happen at any time (i.e. between evals) If during eval an attempt is made to read *in* it will read from in-reader unless :stdin is supplied Alpha, subject to change.