4

The following is perfectly valid Clojure code:

(def a (atom nil))
(def b (atom a))
(reset! a b)

it is even useful in situations where back references are needed.

However, it is annoying to work with such things in the REPL: the REPL will try to print the content of such references whenever you type a or b, and will, of course, generate a stack overflow error pretty quickly.

So is there any way to control/change the printing behaviour of atoms/refs/agents in Clojure? Some kind of cycle detection would be nice, but even the complete suppression of the deref'ed content would be really useful.

amadeoh
  • 95
  • 6
  • Wouldn't `(reset! a b)` set the deref value of `a` (already an atom) to `(atom nil)` -- making `a` an atom referring to a sub-atom referring to `nil`? – Dave Yarwood Aug 21 '14 at 19:01
  • No, in Clojure, atom represents identity, not value. What this means is that even if you do `(def a (atom 1))` and `(def b (atom 1))`, `(= a b)` returns false, and if you do `(deref a)`, you get `1`, but if you do `(reset! a 0)` followed by `(deref a)`, you get `0`. Hence in the above example, if you deref `a` you get an atom referred to by `b` (because of the `reset!` statement), and if you deref that again you get an atom referred to by `a` again, and ad infinitum. – amadeoh Aug 22 '14 at 02:03
  • Oh, I see! I was trying (wrongly) to think of it in pure functional terms and getting confused. Thanks for the explanation. – Dave Yarwood Aug 22 '14 at 12:54

1 Answers1

9

You can say

(remove-method print-method clojure.lang.IDeref)

to remove special handling of derefable objects (Atoms, Refs etc.) from print-method, causing them to be printed like so:

user=> (atom 3)
#<Atom clojure.lang.Atom@5a7baa77>

Alternatively, you could add a more specific method to suppress printing of contents of some particular reference type:

(defmethod print-method clojure.lang.Atom [a ^java.io.Writer w]
  (.write w (str "#<" a ">")))

user=> (atom 3)
#<clojure.lang.Atom@4194e059>
Michał Marczyk
  • 83,634
  • 13
  • 201
  • 212