Oh, interesting. I knew it was changing *some* state but I didn't realize
it was actually changing the binding of the rest-serialize var.  Thanks =)


On Tue, Dec 10, 2013 at 4:09 PM, Kevin Downey <redc...@gmail.com> wrote:

> extend mutates some state (the protocol definition), so what is happen
> here is comp is returning a new function built from the value of the
> rest-serialize var (the protocol function before the extend changes it)
> and the value of the deref var.
>
> I have not verified this, but I suspect if you use (fn [x]
> (rest-serialize (deref x))) instead of the comp version, you will get
> the behaviour you expected
>
> On 12/10/13, 11:50 AM, Michael Blume wrote:
> > 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!
> >
>
>
> --
> And what is good, Phaedrus,
> And what is not good—
> Need we ask anyone to tell us these things?
>
>

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