Fork me on GitHub
#cljs-dev
<
2020-09-04
>
thheller06:09:41

or just don't use tagged literals in code and you don't have to worry about it 😉

dominicm07:09:55

In either case, still unclear how to do that in a cljc-friendly way.

thheller07:09:05

it works basically the same as in clojure and you need to be kinda careful what you return in the reader when used in code. when used in the regular EDN reader or so it doesn't matter much since you just get whatever you returned. when used in code the compiler needs to be able to emit code that is somehow able to reconstruct the returned object. in clojure thats done via print-dup I believe and in CLJS you implement the multi-method you linked.

thheller07:09:30

thus ... don't use it in code since thats not always practical. just calling (whatever/foo 1 2 3) is pretty much always better than #whatever/foo [1 2 3]. certainly less headaches 😛

thheller07:09:37

IIRC there is some special support for records but thats about it

slipset07:09:19

and the fact that they're read with java and used in js.

mfikes11:09:18

@dominicm An example of a working CLJC-based tagged-literal project that spans Clojure and both JVM and self-hosted ClojureScript is https://github.com/mfikes/precise

dominicm11:09:14

@mfikes that has the same problem I am trying to overcome on the JVM:

user=> (read-string "#exact/ratio \"2/3\"")
(com.gfredericks.exact// (com.gfredericks.exact/string->integer "2") (com.gfredericks.exact/string->integer "3"))
It returns code instead of objects. Compare with, e.g. uuid:
user=> (read-string "#uuid \"bdd2c05b-91a3-4e67-83ca-dcbd76ebe44c\"")
#uuid "bdd2c05b-91a3-4e67-83ca-dcbd76ebe44c"

dominicm11:09:08

It seems to me that libraries need to return code for clojurescript, and objects for clj, but they have no way to distinguish.

mfikes11:09:48

Oh, that's interesting. I wasn't aware that read-string behaved that way.

mfikes11:09:04

I bet you need to bind *data-readers* when using read-string, but it has been a while since I've been down in that code

dominicm11:09:30

read-string uses default-data-readers too

mfikes12:09:17

Yeah, there is something subtle that is making inst and uuid behave differently, it seems. Hrm.

thheller12:09:04

hmm why do I get a 404 on that link?

thheller12:09:42

the issue is simply that the exact/ratio returns a code form which when encountered by the compiler will simply compile as regular code

thheller12:09:21

might be a bug if clojure doesn't do that. read-string however doesn't eval so totally normal to get the returned "code" as data

thheller12:09:51

doing it in code does require implementing the multimethod

dominicm12:09:22

I'm pretty sure that you're not intended to return a code form from data readers.

dominicm12:09:16

Not clear from the docs

thheller12:09:45

yes. the question is whether clojure does indead handle it as basically a quoted list or also compiles it happily

Alex Miller (Clojure team)12:09:54

clojure expects a tagged reader function to return an object

👍 3
bronsa12:09:10

it seems totally acceptable to me to return a quoted form from a tagged reader

bronsa12:09:25

if embedded in code it will be evaluated normally

bronsa12:09:48

just like syntax-quote returns code

bronsa12:09:35

to me returning an object vs code seem to be both valid, different, usages of tagged reader and i can't see why one would be expected over the other

bronsa12:09:08

similar to how both (defmacro x [] (Object.)) and

(defmacro y [] `(Object.))
are ok

bronsa12:09:26

the difference to me seems in what the usage of a tagged literal is supposed to be, if to be embedded in code, returning code is ok since it will be evaluated, if just for reading then obviously not

Alex Miller (Clojure team)12:09:22

I think the issue of whether you expect it to be eval'ed is important

bronsa12:09:43

the thing in cljs vs clj is that in clj objects are self-evaluating, in cljs only if the compiler knows how to

Alex Miller (Clojure team)12:09:44

if you're just calling read-string or something, then that's just read

bronsa12:09:04

but even in clj, it will only self-evaluate when running through the repl, if you try to embed them and AOT it may explode if there's no print-dup

dominicm16:09:56

Unfortunately, that emit-constant* is not part of the public compiler API. There's no way in user space to define reader literals which work with read-string and also in clojurescript.

Roman Liutikov17:09:58

Well technically cljs is just a Clojure library, so everything is possible :)

parrot 3
scknkkrer17:09:31

God, I love this language.