Unfortunately, this problem is not specific to `js->clj` only.

I believe in general under :advanced optimizations, any object which was 
created or modified by a code which 
was not subject of the same closure compiler optimization pass could 
exhibit similar problems when used with ClojureScript core functions like 
`satisfies?`.

That also includes working with external data (your case), and working with 
objects created/modified by adding properties by string names.

To illustrate, I created a screenshot of cljs type instance with two 
protocols, to see the internals in dev mode:
https://dl.dropboxusercontent.com/u/559047/cljs-protocol-internals-01.png
In the selected text I highlighted part of generated code for `satisfies?` 
call.

ClojureScript adds/checks $cljs prefixed properties to objects. These 
internal properties get renamed by closure compiler.
So any object which happens to have one of those renamed names 
independently added as their property will potentially confuse functions 
like `satisfies?`.

Possible solutions I see:

1. use string names for clojurescript internal properties, and avoid 
clashes by using "unique-enough" prefix even in advanced mode - still not 
safe solution, but would minimize clash chances

or 

2. start tracking which objects belong to cljs land, have one 
"unique-enough" string name as a marker, clojurescript functions like 
satisfies? would check this marker before proceeding further. Still dirty, 
one could clobber cljs properties by modifying a cljs-land-object from 
unaware Javascript code. And this would probably change behaviour of some 
existing code.

or

3. use prototypal inheritance and "hide" all ClojureScript internal 
properties in a new link in the prototype chain, plain javascript objects 
would miss this link so it could be easily detected, properties would not 
clash even if they got same names. ClojureScript functions like satisfies? 
would properly
walk the chain and read properties from proper link which belongs only to 
ClojureScript. Ale we would not need any special "magic" marker - the 
Javascript type of the link in prototype would safely identify it.
I believe this would be correct solution. But I guess, this would be too 
dramatic change in ClojureScript internals and might break a lot of other 
things I currently don't understand. Also performance could get a hit.

Better ideas, anyone? :-)

ps. don't use :advanced mode when programming atomic reactors in 
ClojureScript ;-p

On Saturday, October 15, 2016 at 10:59:14 PM UTC+2, John Szakmeister wrote:
>
> On Sat, Oct 15, 2016 at 2:49 PM, David Nolen <dnolen...@gmail.com 
> <javascript:>> wrote: 
> > This issue is somewhat to be expected if you're going to use `js->clj`. 
> This 
> > issue has nothing to do with ClojureScript compiler versions - you just 
> got 
> > lucky before. Google Closure will collapse properties, but some of these 
> > collapsed properties are going to be used to determine protocol 
> membership. 
> > That's it. 
>
> Wow.  I did not that expect that at all.  It makes sense, but it's 
> unfortunate. 
>
> > I suggest just avoiding `js->clj` and using your own simple helper for 
> > recursively converting JSON into Clojure values. Changing the 
> (admittedly 
> > questionable) behavior of `js->clj` will only lead to more breakage. 
>
> I'll definitely look at alternatives.  It'd be nice if js->clj had 
> documentation on this shortcoming though, and perhaps pointers to 
> better alternatives. 
>
> Thanks for the help David! 
>
> -John 
>

-- 
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/d/optout.

Reply via email to