On Thu, Feb 19, 2009 at 4:51 PM, mikel <mev...@mac.com> wrote:
>
> If I can implement a custom printing function that gets called on
> generic functions, that presupposes that I have some way to tell that
> an object is a generic function. So, yes, if I solve the problem, then
> the problem is solved. :-)

Hm, perhaps I was unclear.  I've been playing with a little patch to
allow you to attach a print fn to anything that can hold metadata:

  (defmacro do-writes [w & exprs]
    (let [wsym (gensym)]
      `(let [~wsym ~(with-meta w {:tag 'java.io.Writer})]
        ~@(for [e exprs]
            `(.write ~wsym (str ~e))))))

  user=> #^{:custom-print #(do-writes %2 "#<foo: " (:a %) ">")} {:a 1 :b 2}
  #<foo: 1>

To extend further my already over-extended example from earlier:

  (import '(clojure.lang IFn IDeref IMeta))

  (defn make-thing [a b]
    (let [state (atom {})]
      (proxy [AFn IDeref IMeta]
             [{:custom-print
                 #(do-writes %2 "#<thing: a " a ", b " b ": " @@% ">")}]
        (deref [] state)
        (invoke
          ([] "no arg")
          ([x] "one arg")))))

  (def thing (make-thing 1 2))

  (swap! @thing assoc :z 1)

  user=> thing
  #<thing: a 1, b 2: {:z 1}>

All that and no need for an AOT compilation step first.

I've attached a patch to support the :custom-print metadata, in case
anyone wants to play with it.

> I think the only amenity that leaves unaccounted-for is the minor
> matter of some sort of fastidiousness about having GenericFunction
> as a peer of MultiFn, but truthfully, I'm not sure there's really
> any reason to want that.

Both extend AFn, so I think they're siblings even if one of them has a
goofy name.

--Chouser

--~--~---------~--~----~------------~-------~--~----~
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
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
-~----------~----~----~----~------~----~------~--~---

commit cfe7088f295886337c127a78d289676612133121
Author: Chouser <chou...@n01se.net>
Date:   Fri Feb 20 12:03:15 2009 -0500

    Support :custom-print

diff --git a/trunk/src/clj/clojure/core.clj b/trunk/src/clj/clojure/core.clj
index ecd417d..f83f585 100644
--- a/trunk/src/clj/clojure/core.clj
+++ b/trunk/src/clj/clojure/core.clj
@@ -1979,7 +1979,12 @@
 
 (def #^{:private true} print-initialized false)
 
-(defmulti print-method (fn [x writer] (class x)))
+(defmulti print-method
+  (fn [x writer]
+    (if (:custom-print ^x)
+      :custom-print
+      (class x))))
+
 (defmulti print-dup (fn [x writer] (class x)))
 
 (defn pr-on
diff --git a/trunk/src/clj/clojure/core_print.clj b/trunk/src/clj/clojure/core_print.clj
index 9ec08df..5469b1b 100644
--- a/trunk/src/clj/clojure/core_print.clj
+++ b/trunk/src/clj/clojure/core_print.clj
@@ -68,6 +68,9 @@
           (pr-on m w))
       (.write w " "))))
 
+(defmethod print-method :custom-print [o, #^Writer w]
+  ((:custom-print ^o) o w))
+
 (defmethod print-method nil [o, #^Writer w]
   (.write w "nil"))
 

Reply via email to