It's true that there other scenarios where you can encounter this but it
gets reported infrequently enough that I don't think these kinds of
property name collisions are common.

Still it has come up before and I think the simplest solution least likely
to adversely affect performance is to test for a def'onced unique object
instead of `true`.

David

On Sat, Oct 15, 2016 at 8:46 PM, Antonin Hildebrand <
antonin.hildebr...@gmail.com> wrote:

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

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