I am trying to roundtrip some EDN in cljs with records and it doesn’t work:
(cljs.tools.reader.edn/read-string (pr-str (->SerRatio 1 2)))
No reader function for tag roklenarcic.math.SerRatio.
=> :repl/exception!
The pr-str part outputs what you’d expectYou have to supply a map of readers as the second argument, otherwise read-string can’t possibly know about custom data types
But it’s a record… shouldn’t it know about that?
But it’s “your” record :)
SerRatio in this case. You can have many other record types
Stuff like this should work in Clojure, IIRC. But not in ClojureScript because there's no global registry of FQN->constructor for records.
Due to DCE and minification most of the names are shortened, so your foo.bar.SerRatio ends up as just some x somewhere - no way to reconstruct it dynamically.
interesting, I think this can work
const recordsReg = { 'foo.bar.SerRatio': x } // x -> foo.bar.SerRatio
with some compile time introspection the registry can be populated with type name, and actual value is just a referencebut yeah this will break DCE
everything registry based is going to retain stuff after advanced compilation (spec etc)
Ok, well I went with Transit instead of EDN now
I remembered that existed
transit is better though
I mean it’s similar and it’s another library in the stack, I don’t like adding too much of those
but its more performant and compact than EDN, so I pretty much always use it
It’s more compact? The JSON thing looks like it has quite a bit of extra characters, but that’s just my feeling, I didn’t measure it
well depends on size of the payload, but the larger the structure the bigger the "savings"
could I be using msgpack for shuttling from clj to cljs
you can, but I never have. it'll be slower as well probably.
I wonder if it’s better
I wonder how that looks if the payload is compressed?
doesn't look good, also parsing perf in a browser is not that great
might be still a good option for streaming
IIRC those benchmarks from Peter were done also in a browser. But it could be some custom code for Sente, I haven't checked.
And of course, benchmark results could also greatly depend on both payload size and the actual data.
It's one thing to serialize+compress (repeat 1000000 {:some-key 1}) and another (repeatedly 1000000 (fn [] {(random-keyword) (rand-int 1000)})).
yeah but nobody ever uses (random-keyword) keys 😉
I took json payload from this generator https://json-generator.com/ looks like a typical api response you'd have on the client side
Well, yes and no. Depends on what you send.
It could be that you only pass some specific datums around - not many keywords, just user-generated data.
Or UUIDs with barely anything else.
Maybe you decided to save some bandwidth and not pass any keywords around and rely on zipmap on client/server with a known set of keys.
Hard to come up with accurate comparisons without representative data from a specific use case.
The Peter's benchmark was on some data that I had - looong vectors of maps with the same keywords across all maps. Not everyone will have such payload. But mine payload was arguably optimal for Transit and compression, and yet msgpack ended up winning with Peter's code.
Are wrapped objects to be expected when using proxy with non-primitives?
proxy is recursive, the maps will also be proxy-wrapped, hence the object printing
Ah, that explains it then. This is not a suitable use case then unless you’re happy unwrapping at a later stage.
It seems that this includes nil, which doesn’t appear to map to null.
I think cljs.proxy originated as a more efficient clj->js alternative, which is also recursive
nil and null should be the same