naomijub / edn-rs

[DEPRECATED]: Crate to parse and emit EDN
https://crates.io/crates/edn-rs
MIT License
81 stars 14 forks source link

Map keys should be any EDN element, not only strings #141

Closed Grinkers closed 3 months ago

Grinkers commented 8 months ago

https://github.com/edn-format/edn#maps

Note that keys and values can be elements of any type.

(clojure.edn/read-string "{{:foo 42 :bar 43} 44 {} 45}")
{{:foo 42, :bar 43} 44, {} 45}

((clojure.edn/read-string "{{:foo 42 :bar 43} 44 {} 45}") {})
45

((clojure.edn/read-string "{{:foo 42 :bar 43} 44 {} 45}") {:foo 42 :bar 43})
44
((clojure.edn/read-string "{{:foo 42 :bar 43} 44 {} 45}") {:bar 43 :foo 42})
44

((clojure.edn/read-string "{{:foo 42 :bar 43} 44 {} 45}") [])
nil

((clojure.edn/read-string "{{:foo 42 :bar 43} 44 {} 45}") "")
nil

take special note that the order of the maps being used as keys (they don't matter).

95 is going to be required to do this, as seen in the following example

((clojure.edn/read-string "{{:foo 42 :bar 43} 44 [1 2] 45}") '(1 2))
45
Grinkers commented 8 months ago

https://github.com/edn-rs/edn-rs/blob/d64f20c3079268372970398349ae5bf5b7b40f41/tests/deserialize.rs#L716 We don't support readers, so we'll have to also check equality for tagged items specifically. I haven't used tags in clojure, but I think with custom readers the following can be true

(read-string "#foo bar") -> "foobar"
(read-string "#bar foo") -> "foobar" ; a pretty ridiculous custom reader

where these two end up being equal

naomijub commented 7 months ago

https://github.com/edn-rs/edn-rs/blob/d64f20c3079268372970398349ae5bf5b7b40f41/tests/deserialize.rs#L716

We don't support readers, so we'll have to also check equality for tagged items specifically. I haven't used tags in clojure, but I think with custom readers the following can be true

(read-string "#foo bar") -> "foobar"
(read-string "#bar foo") -> "foobar" ; a pretty ridiculous custom reader

where these two end up being equal

Did you test this two readers and they return the same? THAT IS ACTUALLY CRAZY

Grinkers commented 7 months ago

https://github.com/edn-rs/edn-rs/blob/d64f20c3079268372970398349ae5bf5b7b40f41/tests/deserialize.rs#L716

We don't support readers, so we'll have to also check equality for tagged items specifically. I haven't used tags in clojure, but I think with custom readers the following can be true

(read-string "#foo bar") -> "foobar"
(read-string "#bar foo") -> "foobar" ; a pretty ridiculous custom reader

where these two end up being equal

Did you test this two readers and they return the same? THAT IS ACTUALLY CRAZY

Can be true, depending on how you arbitrarily define custom readers. Not default behavior.

https://github.com/edn-format/edn?tab=readme-ov-file#tagged-elements

It is envisioned that a reader implementation will allow clients to register handlers for specific tags. Upon encountering a tag, the reader will first read the next element (which may itself be or comprise other tagged elements), then pass the result to the corresponding handler for further interpretation

so it can really do anything..... You can do some pretty insane things. I think the point as you can essentially embed a lisp within EDN, hence the "Extensible".

Grinkers commented 7 months ago

I just checked, you can supply a custom reader to do anything. Here's an example of the insanity.

(require '[clojure.edn :as edn])

(defn foo [i] (if (= i 41) 42 "foobar"))
(defn bar [i] (str i "bar"))

;; prints "foobar"
(println (edn/read-string {:readers {'foo foo 'bar bar}} "#foo bar"))
;; prints "foobar"
(println (edn/read-string {:readers {'foo foo 'bar bar}} "#bar foo"))
;; prints "42"
(println (edn/read-string {:readers {'foo foo 'bar bar}} "#foo 41"))

I actually think we can support this, although not without breaking changes.

Grinkers commented 3 months ago

https://github.com/edn-rs/edn-rs/issues/158