On Sep 12, 2014, at 2:36 PM, Mark Engelberg <[email protected]> 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 [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
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 [email protected].
For more options, visit https://groups.google.com/d/optout.