Closed bobbicodes closed 11 months ago
Apparently this behavior was being caused by the pretty printer! I disabled it and now we have the "correct" wrong result:
(assoc {[1] 2} [1] 3)
=>
{[1] 2 [1] 3}
So it seems we have 2 issues here. I solved the first one with the following code:
var assoc_keys = new Set()
for (let i = 1; i < arguments.length; i += 2) {
assoc_keys.add(arguments[i])
}
var new_map = new Map()
for (const [key, value] of hm) {
if (!contains_Q(assoc_keys, key)) {
new_map.set(key, value)
}
}
for (var i = 1; i < arguments.length; i += 2) {
var ktoken = arguments[i],
vtoken = arguments[i + 1];
new_map.set(ktoken, vtoken)
}
return new_map;
It builds a new map with each element except ones which match one being passed to assoc, then sets the assoc args. Cool!
(assoc {[1] 2} [1] 3)
=>
{[1] 3}
So then we have the matter of the pretty printer. I just recently added that so I don't understand it much. But I can still reproduce it:
{[1] 2 [1] 3}
=>
{[1] 2
[1] 2}
It might be that the map is semantically invalid, so it's just printing the value of [1]
as it should. I think I'll just close this and call it expected behavior when printing maps with duplicate keys.
I was trying to figure out how to modify
assoc
to repect equality of aggregate values.The problem statement is simple: javascript's
.set()
on maps doesn't recognize keys that aren't simple values, for example, a vector:So if we call
(assoc {[1] 2} [1] 3)
, what we want is to get a new map of{[1] 3}
, not a map with a new key with duplicate keys, i.e.{[1] 2 [1] 3}
.But the actual result is even weirder...
So naturally, I started printing things to understand the different parts of execution. And to my surprise... the return value of
assoc
as printed in the console is actually the expectedly wrong value,{[1] 2 [1] 3}
.I have no idea how to explain this or correct it. And it's not like a "sweep it under the rug, maybe fix one day but maybe never" kind of thing. It's critical to the operation of a language.