Fork me on GitHub
#clojurescript
<
2022-11-09
>
cjohansen19:11:21

Is it possible to get the namespace meta data and doc string in a ClojureScript macro? (meta *ns*) gives me what I want in Clojure, but in ClojureScript, it seems to only return filename, line and column?

dnolen19:11:16

if you look at how var metadata is resolved at macroexpand time (by looking the compilation environment) it should make sense how you can do the same trick to get the ns info

cjohansen19:11:53

Uhm, where specifically should I look for this information? the cljs compiler?

cjohansen21:11:01

So (get-in @env/*compiler* [:cljs.analyzer/namespaces (symbol (str *ns*))]) gets me the doc string under :doc and lots of other things, but I can’t seem to get the ns meta?

borkdude19:11:05

I have a collection of symbols of cljs core functions.

(def syms '{_EQ_, prn ...})
These symbols are already munged. But after advanced compilation it seems some symbols get demunged! Symbols that occur in the un-optimized set but not in the optimized set:
#{_PLUS_ _EQ_ not_EQ_}
Symbols that occur in the optimized set but not in the un-optimized set:
#{= not= +} 
Any ideas of why this might happen?

borkdude19:11:18

I've seen the issue before and then I switched to strings which helped, but I haven't gotten at the root cause of this behavior

dnolen20:11:00

Seems strange

borkdude20:11:04

If I do this:

(def core-vars (conj (:vars core-config) 'goog_typeOf (symbol "_EQ_")))
then the problem gets fixed but not when I do:
(def core-vars (conj (:vars core-config) 'goog_typeOf '_EQ_))

borkdude20:11:20

it seems the symbol compile time constant gets renamed back

thheller20:11:28

uhm is this with shadow?

thheller20:11:04

it does the constants optimization in a closure compiler pass using the munged symbol as the "key" in a map

borkdude20:11:19

yes, it is with shadow

thheller20:11:44

so, they would end up as the same key I guess

thheller20:11:42

at least I think so. let me check

🙏 1
thheller20:11:36

ah no, it just emits things twice. but the variable name it creates just overwrites itself

thheller20:11:50

since that uses the munged symbol

thheller20:11:43

so you have one var cljs$cst$_foo = new cljs.core.Symbol(null, "-foo", ...) and one var cljs$cst$_foo = new cljs.core.Symbol(null, "_foo",...)

thheller20:11:53

both using cljs$cst$_foo

borkdude20:11:47

possibly I have both '= and '_EQ_ somewhere yes

borkdude20:11:21

I know this for sure since SCI has a lookup map with '= as one of the keys

borkdude20:11:33

but cherry also has a set of symbols with _EQ_

borkdude20:11:44

and those might get mixed up I guess?

thheller20:11:56

if its the same build then yes, its all done as part of :advanced over the whole code

borkdude20:11:09

yes, it's the same build

borkdude20:11:47

and a lookup like (contains? set (symbol "_EQ_")) will happen and then fail

borkdude20:11:53

@U05224H0W I would consider this a bug. Perhaps the naming cljs$cst$... can be made more robust, e.g. by using a gensym-ed symbol or so

thheller21:11:38

feel free to open an issue. too tired to do anything now

thheller21:11:51

pretty sure CLJS will have the same problem though

borkdude21:11:34

will do, thanks.

winsome21:11:38

Does anybody have an example of cljs.test/async? I'm not quite understanding how to test promise-returning functions properly.

(testing "promise-returner"
    (-> (promiser-returner data)
        (.then #(is (= {} %)))))
I suspect the result from is just isn't getting back to the deftest machinery.

p-himik21:11:37

The docstring of that macro has an example.

winsome21:11:05

I'm afraid I'm not understanding it, though. I've looked at the [async testing]( https://clojurescript.org/tools/testing#async-testing), but they all use async channels and not promises, and I don't understand how to move the is outside of the promise chain.

(testing "promise-returner"
    (let [promise (promise-returner data)]
      (async done
             (-> promise
                 (.then #(is (= {} %))))
             (done)
             0)))

winsome21:11:21

The tests don't pick up this assertion at all.

p-himik21:11:03

> I don't understand how to move the is outside of the promise chain Don't move it. Instead, move the (done) call right after all calls to (is ...), within that .then. Or within yet another .then, at the very end.

winsome22:11:23

This worked! Thank you, I could not figure out what the docstring was trying to communicate, I understand now.

👍 1