On Sep 12, 2014, at 2:36 PM, Mark Engelberg <mark.engelb...@gmail.com> wrote:

> As far as I know, Clojure doesn't give you a whole lot of control over how 
> things print at the REPL

The built-in clojure repl has some customization options. You can run a repl 
with a custom reader and printer, for example.

The one below shows the type and value returned by the reader and the type and 
value printed by the printer for each interaction. 

It would be better if it were able to show more meaningful logical types rather 
than concrete types. Showing the concrete type brings up some subtleties 
though. Often in clojure when we say "list" we mean "object that implements 
clojure.lang.IPersistentList" or equivalently "object for which list? returns 
true". However, when we explain that "lists" get special treatment for 
evaluation, it's actually broader than that. Objects that implement 
clojure.lang.ISeq (ones for which seq? returns true) get the special handling. 
This includes clojure.lang.Cons and clojure.lang.LazySeq. The output of macros 
can easily end up including these other kinds of ISeqs and it's important that 
the generated code still evaluate as expected.

The value returned by the reader is interesting when using reader macros like 
', #', #", and #(. The expansion into the equivalent clojure code or object 
happens within the reader.

--Steve

(defn run-visible-repl []
  (let [print-with-type #(prn %1 (type %2) %2)
        reader-print #(print-with-type :reader %1)
        printer-print #(print-with-type :printer %1)
        init #(println "\nvisible repl\nenter (quit) to exit")
        prompt #(do (print "\nvisible repl: ") (clojure.main/repl-prompt))
        read #(let [obj (clojure.main/repl-read %1 %2)]
                (if (= obj '(quit))
                  %2
                  (doto obj reader-print)))
        print printer-print]
    (clojure.main/repl :init init :prompt prompt :read read :print print)))
 
user=> (run-visible-repl)
 
visible repl
enter (quit) to exit
 
visible repl: user=> 1
:reader java.lang.Long 1
:printer java.lang.Long 1
 
visible repl: user=> 1.0
:reader java.lang.Double 1.0
:printer java.lang.Double 1.0
 
visible repl: user=> 1.
:reader java.lang.Double 1.0
:printer java.lang.Double 1.0
 
visible repl: user=> 1e5
:reader java.lang.Double 100000.0
:printer java.lang.Double 100000.0
 
visible repl: user=> \a
:reader java.lang.Character \a
:printer java.lang.Character \a
 
visible repl: user=> "a"
:reader java.lang.String "a"
:printer java.lang.String "a"

;; all self-evaluating up to this point

visible repl: user=> 'a
:reader clojure.lang.Cons (quote a)
:printer clojure.lang.Symbol a

visible repl: user=> (doc +)
:reader clojure.lang.PersistentList (doc +)
-------------------------
clojure.core/+
([] [x] [x y] [x y & more])
  Returns the sum of nums. (+) returns 0. Does not auto-promote
  longs, will throw on overflow. See also: +'
:printer nil nil
 
visible repl: user=> #(+ 3 %)
:reader clojure.lang.Cons (fn* [p1__3386#] (+ 3 p1__3386#))
:printer user$eval3387$fn__3388 #<user$eval3387$fn__3388 
user$eval3387$fn__3388@33fe788a>
 
visible repl: user=> #'run-visible-repl
:reader clojure.lang.Cons (var run-visible-repl)
:printer clojure.lang.Var #'user/run-visible-repl
 
visible repl: user=> [1 (+ 1 1) (* 1/3 9)]
:reader clojure.lang.PersistentVector [1 (+ 1 1) (* 1/3 9)]
:printer clojure.lang.PersistentVector [1 2 3N]
 
visible repl: user=> (defn plus3 [x] (+ 3 x))
:reader clojure.lang.PersistentList (defn plus3 [x] (+ 3 x))
:printer clojure.lang.Var #'user/plus3
 
visible repl: user=> (quit)
nil
user=>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to