Share your thoughts in the 2024 State of Clojure Survey!

Welcome! Please see the About page for a little more info on how this works.

+1 vote
in ClojureScript by

This looks like a bug in ClojureScript 1.11.54 :

(conj {} [:a 1] '([:b 2] [:c 3]) '([:d 4]))

In Clojure on the JVM this is an error:

cljs.user> (conj {} [:a 1] '([:b 2] [:c 3]) '([:d 4]))
{:a 1, :b 2, :c 3, :d 4}
cljs.user> :cljs/quit
nil
user> (conj {} [:a 1] '([:b 2] [:c 3]) '([:d 4]))
Execution error (ClassCastException) at user/eval17754 (REPL:25).
class clojure.lang.PersistentVector cannot be cast to class java.util.Map$Entry (clojure.lang.PersistentVector is in unnamed module of loader 'app'; java.util.Map$Entry is in module java.base of loader 'bootstrap')
by
The fact that something _works_, doesn't meant that it's a bug. It also doesn't mean that it's intended behavior and can be relied upon. In this case it's probably just a happenstance.
by
Well in this case the code that works makes little sense from the data standpoint.

Conj can conj a vector of two elements onto a map with precise semantics.  Conjing lists of vectors shouldn't work.

In other words (conj {} [[:a 1] [:b 2]]) is fine because we're conjing a vector of two vectors and have {[:a 1] [:b 2]} as a result.

However, (conj {} '([:a 1] [:b 2])) shouldn't be fine, because it's not a vector.

And conjing just '([:d 4]) onto a map doesn't make any sense at all and should not work, yet it works in CLJS. Especially since conjing [[:d 4]] doesn't work.

It's almost like CLJS doesn't care if it is a list of elements or just elements:

    (conj {} [[:a 1] [:b 2]] '([:c 3] [:d 4]))
    => {[:a 1] [:b 2], :c 3, :d 4}
by
Something working in a particular way doesn't have to make sense. If something isn't documented somewhere, it's undefined behavior by definition. "Shouldn't be fine" - and it is not fine indeed, if it's not documented. Not every single invalid or undefined behavior throws, especially in Clojure[Script].
by
> If something isn't documented somewhere, it's undefined behavior by definition.

It's the opposite actually. Undefined behavior is prescribed to be unpredictable by language. That's how we know that it's an undefined behavior that should not be relied upon, but that it's not a bug.

What you're saying is unspecified behavior, which is usually a result of something being overlooked, either in the docs or in the implementation. In the case of this ticket, I suspect the latter.

I don't know why you try to mitigate the problem though. If that's a bug in the compiler it may be within protocol implementation which can be a serious problem.
by
> Undefined behavior is prescribed to be unpredictable by language

If you read more discussions with the core team, undocumented is usually treated as undefined. That's now how they view things, at least under my interpretation and given my memory.
E.g. see this good comment by Sean Corfield: https://groups.google.com/g/clojure/c/yMHHHuK44pE/m/LeBhqdq6BQAJ
Or this by Alex Miller that explicitly talks about UB in the context of a lack of documentation for something particular: https://groups.google.com/g/clojure/c/VwA2Un2NMxc/m/tptww3xZBwAJ
Or this: https://groups.google.com/g/clojure/c/HtK4pqsr--8/m/KbWvq8CFCQAJ
And many, many others, all around the media.

> unspecified behavior

Clojure leaves a *lot* unspecified. The language itself doesn't have any specification or a standard, only docs (that don't document every single thing that exists), some spec definitions, and the reference implementation. It has been explicitly stated before that specifying everything is not a goal.

As an example calling `keys` or `vals` or iterating over the same map object will return items in the same order. But a different map object that is equal to the first one might return them in different order. And a map in CLJS will almost definitely return values in an order different from the one in CLJ.

> If that's a bug in the compiler it may be within protocol implementation which can be a serious problem.

That would be a different discussion, if that were the case.

Please log in or register to answer this question.

...