I have a protocol RestSerializable to represent data that can be serialized 
to json from a REST interface.

(defprotocol RestSerializable
  (rest-serialize [this]
   "Convert to something Cheshire can JSONify"))

By default, things are left alone

(extend Object
  RestSerializable
  {:rest-serialize identity})

But I want atoms and the like to be transparent when serialized

(extend clojure.lang.IDeref
  RestSerializable
  {:rest-serialize (comp rest-serialize deref)})

I would expect this to mean that, say, 

(-> 42 atom atom atom atom rest-serialize)

would just unwrap to 42, but in fact it only unwraps the outer atom and 
leaves the inner ones alone.

Here's where it gets weird though. If I just evaluate the extend 
clojure.lang.IDeref form again, rest-serialize suddenly gains the ability 
to unwrap *two* layers of atoms. Eval it again and it can unwrap *three*. 
Kinda feels like the exercises in Little Schemer when they're building up 
to the Y Combinator.

Here's my REPL session demonstrating this (not shown, but I've verified 
this behavior is the same in Clojure 1.5.1 and Clojure 1.6.0-alpha3)

$ lein repl
nREPL server started on port 46049 on host 127.0.0.1
REPL-y 0.2.1
Clojure 1.5.1
    Docs: (doc function-name-here)
          (find-doc "part-of-name-here")
  Source: (source function-name-here)
 Javadoc: (javadoc java-object-or-class-here)
    Exit: Control+D or (exit) or (quit)
 Results: Stored in vars *1, *2, *3, an exception in *e

user=> (defprotocol RestSerializable
  #_=>   (rest-serialize [this]
  #_=>    "Convert to something Cheshire can JSONify"))
RestSerializable
user=> 

user=> (extend Object
  #_=>   RestSerializable
  #_=>   {:rest-serialize identity})
nil
user=> 

user=> (extend clojure.lang.IDeref
  #_=>   RestSerializable
  #_=>   {:rest-serialize (comp rest-serialize deref)})
nil
user=> (-> 7 atom atom atom rest-serialize)
#<Atom@56153406: #<Atom@a0aa211: 7>>
user=> (-> 7 atom atom atom rest-serialize)
#<Atom@3c19a5b0: #<Atom@37cce4a3: 7>>
user=> (-> 7 atom atom atom rest-serialize)
#<Atom@9f6e629: #<Atom@308092db: 7>>
user=> (extend clojure.lang.IDeref
  #_=>   RestSerializable
  #_=>   {:rest-serialize (comp rest-serialize deref)})
nil
user=> (-> 7 atom atom atom rest-serialize)
#<Atom@7fb48906: 7>
user=> (-> 7 atom atom atom rest-serialize)
#<Atom@41e224a5: 7>
user=> (extend clojure.lang.IDeref
  #_=>   RestSerializable
  #_=>   {:rest-serialize (comp rest-serialize deref)})
nil
user=> (-> 7 atom atom atom rest-serialize)
7
user=> (quit)
Bye for now!

-- 
-- 
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/groups/opt_out.

Reply via email to