This happens because there is a singleton for the empty case of most persistent 
collection types (in both Clojure and Clojurescript). A literal for an empty 
collection will emit a reference to the corresponding singleton.

E.g.:

(identical? {} {}) => true
(identical? #{} #{}) => true
etc.

Since specify! mutates its argument (in this case the empty-collection 
singleton), you see the behavior you see.

Note you won't necessarily get the empty-singleton in *every* empty case:

(identical? {} (dissoc {:a 1} :a)) => false


specify! is a very useful escape hatch to augment js objects with protocols 
from clojure land, but you should use it with caution. specify (no !) is safer 
because it uses the prototype chain to add new properties (the original object 
is unaltered).

On Friday, October 31, 2014 9:11:04 PM UTC-5, Marcus Lewis wrote:
> Hi, I got bit by some pretty surprising behavior:
> 
> 
> my.ns> (defprotocol IFoo)
> my.ns> (satisfies IFoo {})
>   false
> my.ns> (specify! {} IFoo)
> my.ns> (satisfies IFoo {})
>   true
> 
> 
> The IFoo specification leaks onto all other equal-valued instances. As a 
> result, one of my functions was overwriting this specification for all 
> existing instances with a single specify!.
> 
> 
> Non-empty collections behave as expected:
> 
> 
> 
> 
> my.ns> (defprotocol IFoo)
> my.ns> (satisfies IFoo {:a "a"})
>   false
> my.ns> (specify! {:a "a"} IFoo)
> my.ns> (satisfies IFoo {:a "a"})
>   false
> 
> 
> Thoughts? Known issue?

-- 
Note that posts from new members are moderated - please be patient with your 
first post.
--- 
You received this message because you are subscribed to the Google Groups 
"ClojureScript" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/clojurescript.

Reply via email to