Fork me on GitHub
#shadow-cljs
<
2018-06-16
>
wilkerlucio14:06:42

@thheller I found a nasty issue with shadow + lein + cljs 1.10.312

wilkerlucio14:06:05

I can't use test.check generators with this combined settings

wilkerlucio14:06:59

there was some changes in dynamic var checking, not sure what exactly, but it keeps complaining that clojure.test.check.generators is not loaded, but it is

wilkerlucio14:06:12

using just shadow without lein works fine

wilkerlucio14:06:29

I just created a minimum repro, I'll open an issue with that

thheller14:06:12

hmm lein basically only constructs the classpath. are you sure there aren't any classpath issues?

wilkerlucio14:06:59

the repro is really simple, I can't see how that would be

wilkerlucio14:06:21

unless I'm blind and missing something, can you take a look?

wilkerlucio14:06:10

just preparing the repro to upload, one min

wilkerlucio14:06:41

here I get this with this code:

wilkerlucio14:06:43

alpha.cljs:70 Uncaught Error: Var clojure.test.check.generators/return does not exist, clojure.test.check.generators never required
    at alpha.cljs:70
    at cljs.spec.gen.alpha.LazyVar.cljs$core$IDeref$_deref$arity$1 (alpha.cljs:22)
    at Object.cljs$core$_deref [as _deref] (core.cljs:673)
    at Object.cljs$core$deref [as deref] (core.cljs:1449)
    at Function.cljs$core$IFn$_invoke$arity$variadic (alpha.cljs:70)
    at alpha.cljs:91
    at cljs.core.Delay.cljs$core$IDeref$_deref$arity$1 (core.cljs:10369)
    at Object.cljs$core$_deref [as _deref] (core.cljs:673)
    at Object.cljs$core$deref [as deref] (core.cljs:1449)
    at Object.cljs$spec$gen$alpha$gen_for_pred [as gen_for_pred] (alpha.cljs:148)

thheller14:06:09

I do get it as well with just shadow-cljs

thheller14:06:20

(using master and 1.10.312)

wilkerlucio14:06:34

strange, when I replace :lein true with:

:source-paths ["src"]

 :dependencies [[org.clojure/clojure "1.9.0"]
                [org.clojure/clojurescript "1.10.312"]
                [org.clojure/test.check "0.9.0"]
                [thheller/shadow-cljs "2.4.5"]]

wilkerlucio14:06:36

it works here

thheller14:06:57

clojure.test.check.generators.return$ exists so there is some renaming going on

thheller14:06:10

you can't put org.clojure/clojurescript into shadow-cljs.edn

thheller14:06:21

or rather its filtered out to always use the version shadow-cljs "prefers"

thheller14:06:58

does CLJS not rename the return?

wilkerlucio14:06:59

ah, gotcha, and how do you force shadow to use a different version?

thheller14:06:34

I don't. master is already bumped to 1.10.312. just didn't make a new release yet

thheller14:06:48

just did a lein install to use it

thheller14:06:07

it seems like everything is correct to me?

wilkerlucio14:06:25

yeah, but compiling with pure cljs main things, it works

wilkerlucio14:06:31

so I guess there is something getting off

thheller14:06:56

wonder what cljs generates

wilkerlucio14:06:59

this can be a problem to bump shadow, anyone using generators will be affected

wilkerlucio14:06:33

when I was trying to debug in #clojurescript yesterday david said this: https://clojurians.slack.com/archives/C03S1L9DN/p1529073112000560

wilkerlucio14:06:43

ring any bells?

thheller14:06:04

no, so far it just looks like a renaming issue

thheller14:06:24

return is a reserved word so it should be munged to return$

thheller14:06:44

but for some reason this is not happening for the var generation stuff

thheller14:06:05

need to figure out how to compile cljs without shadow-cljs

thheller14:06:15

not used to this cljs.main business

wilkerlucio14:06:36

I can send you a repo ready here

wilkerlucio14:06:14

{:paths ["src"]
 :deps {org.clojure/clojurescript {:mvn/version "1.10.312"}
        org.clojure/test.check {:mvn/version "0.9.0"}}}

thheller14:06:19

cljs.main -c my-app.core

wilkerlucio14:06:52

I tried here, seems the name is clojure.test.check.generators.return$

thheller14:06:57

hmm yeah the code is actually looking for that so no idea why it doesn't find it

thheller14:06:56

there is some weird code genration going on

wilkerlucio15:06:28

and we though cljs would come with no surprises 😛

thheller15:06:57

if((((typeof clojure !== 'undefined') && (typeof clojure.test !== 'undefined')) && ((typeof clojure !== 'undefined') && (typeof clojure.test !== 'undefined') && (typeof clojure.test.check !== 'undefined') && (typeof clojure.test.check.quick_check !== 'undefined')))){

thheller15:06:33

((typeof clojure !== 'undefined') && (typeof clojure.test !== 'undefined')) is tested twice

thheller15:06:24

shadow-cljs generates this though

thheller15:06:27

if((((typeof clojure !== 'undefined') && (typeof clojure.test !== 'undefined')) && ((typeof clojure !== 'undefined') && (typeof clojure.test !== 'undefined') && (typeof clojure.test.check !== 'undefined')) && ((typeof clojure !== 'undefined') && (typeof clojure.test !== 'undefined') && (typeof clojure.test.check !== 'undefined') && (typeof clojure.test.check.generators !== 'undefined') && (typeof clojure.test.check.generators["return"] !== 'undefined')))){

thheller15:06:42

quadruple checked

thheller15:06:54

clojure.test.check.generators["return"] this fails

thheller15:06:21

not yet sure why shadow generates different code

thheller15:06:23

the compiler hacks were gonna get me at some point 😉

wilkerlucio15:06:43

just curious now, how do you find the compiled code? there is a way in chrome to go from source mapped to compiled source?

thheller15:06:44

just open the file in the editor. just searched for the never required error and went from there

wilkerlucio15:06:02

ok, more a brute force thing 🙂

thheller15:06:43

ok the exists? thing is definitely weird and messes with how shadow-cljs handles js/stuff

thheller15:06:18

ok got an idea to fix it

🤞 4
thheller15:06:55

haha the cljs.spec.gen.alpha/dynaload macro does the work that the new exists? macro does. thats why the check is done twice

wilkerlucio15:06:51

(and ~@checks (c/exists? ~s))

wilkerlucio15:06:06

seems like it

thheller15:06:40

meh if I fix it the simple way I create another bug again 😞

wilkerlucio15:06:29

is that some shadow hack that is not going well with the new exists??

thheller15:06:33

basically the problem is that clojure.test.check.generators/return gets turned into clojure.test.check.generators.return$ but js/clojure.test.check.generators.return is turned into clojure.test.check.generators["return"]

thheller15:06:49

and the new exists? macro turns all vars into js/

thheller15:06:58

no idea why that is

thheller15:06:40

js/ has special treatment in shadow-cljs because of the JS interop it does

thheller15:06:20

JS code in npm doesn't munge .return or so but the CLJS compiler does when you try to access it

wilkerlucio15:06:07

I was reading the commits, seems like it was to fix some self-hosting thing

wilkerlucio15:06:24

so that might be way they keep touching on JS, since it's all self-hosting have access too

thheller15:06:05

this wasn't self host related

thheller15:06:24

(exists? this.ns.does.not.exist) would fail previously

thheller15:06:37

the first impl just had to be fixed for self-host later

thheller15:06:49

I'm just trying to make sense of WHY the js/ is added

thheller15:06:15

(core/defmacro exists?
  "Return true if argument exists, analogous to usage of typeof operator
   in JavaScript."
  [x]
  (if (core/symbol? x)
    (core/let [x     (core/cond-> (:name (cljs.analyzer/resolve-var &env x))
                       (= "js" (namespace x)) name)
               segs  (string/split (core/str (string/replace (core/str x) "/" ".")) #"\.")
               n     (count segs)
               syms  (map
                       #(vary-meta (symbol "js" (string/join "." %))
                          assoc :cljs.analyzer/no-resolve true)
                       (reverse (take n (iterate butlast segs))))
               js    (string/join " && " (repeat n "(typeof ~{} !== 'undefined')"))]
      (bool-expr (concat (core/list 'js* js) syms)))
    `(some? ~x)))

thheller15:06:18

this is the current impl

thheller15:06:31

if I change it to

(core/defmacro exists?
  "Return true if argument exists, analogous to usage of typeof operator
   in JavaScript."
  [x]
  (if (core/symbol? x)
    (core/let [x     (core/cond-> (:name (cljs.analyzer/resolve-var &env x))
                       (= "js" (namespace x)) name)
               segs  (string/split (core/str (string/replace (core/str x) "/" ".")) #"\.")
               n     (count segs)
               syms  (map
                       #(vary-meta (symbol (string/join "." %))
                          assoc :cljs.analyzer/no-resolve true)
                       (reverse (take n (iterate butlast segs))))
               js    (string/join " && " (repeat n "(typeof ~{} !== 'undefined')"))]
      (bool-expr (concat (core/list 'js* js) syms)))
    `(some? ~x)))

thheller15:06:40

it works just the same and fixes the shadow issue

thheller15:06:56

literally just remove the "js" in the symbol call

thheller15:06:05

I don't get why its there

thheller15:06:26

js/ will also cause shadow to generate externs and I think CLJS as well

thheller15:06:31

I don't get it 😛

thheller15:06:11

I really need to learn cljs.main. someone should verify that the exists? calls not actually generate externs via externs inference. I think they might.

wilkerlucio15:06:23

maybe we should bring that to #cljs-dev ?

thheller15:06:38

nah I'd rather verify first

thheller15:06:47

ah I get why the "js" is there now

thheller15:06:53

(exists? cljs.core/return) "(typeof cljs.user.cljs !== 'undefined') && (typeof cljs.core !== 'undefined') && (typeof cljs.core.return$ !== 'undefined')"

thheller15:06:52

seems like the cljs.analyzer/no-resolve is ignored for some reason and js/ is just an easy way to force it to not resolve

thheller16:06:37

meh this messes with my externs inference. will need to think about it

wilkerlucio16:06:33

thanks for checking it out