I'm looking at the slash import issue now (CLJS-3177, https://clojure.atlassian.net/browse/CLJS-3177), that we discussed a few days ago:
$ cat import.cljs
(ns test.imports
(:import [goog.math Integer]))
(println (Integer/fromString "123"))
$ clj -m cljs.main -re node -i src/test/import.cljs
#object[Object 123]
It seems this already works?Compiling also seems to work:
$ clj -R:cljs/dev -m cljs.main -t node -c test.imports
$ node out/main.js
#object[Object 123]
So maybe I can just close the issue? Or are there other problems?
^ @thheller you might know
dunno. I guess its fine if it already works? I didn't actually test it š
maybe it doesn't work with things that are not inferred as a class using :ctr
...
I just tested in shadow-cljs and that has none of the new inference stuff since it still uses 1.10.520
so seems fine
ah ok. a no-op issue then
I'll assign dnolen to let him be the judge to close it
Getting WARNING: Cannot infer target type in expression (. (g (inc 1)) catch identity)
for this code. Looks like a bug?
Happens in both master and 1.10.520
(defn f [g]
(-> ^js/Promise (g (inc 1))
(.catch identity)))
(f #(.resolve js/Promise %))
The warning is gone when g
is replaced with core fn or any defn, or when inner expression (inc 1)
is replaced with random value for example 1
IIRC the .catch
rewrite code loses :tag
info. at least I have a vague memory of something like that.
try if it warns for the other variant too
(defn f [g]
(.catch ^js/Promise (g (inc 1)) identity)
(. ^js/Promise (g (inc 1)) (catch identity)))
warns with any random method call, not just catch
also warns for both lines in the above sample
hmm ok. may just be a missed case for externs inference
wtf, warns here as well
(defn f [g]
(.-hello ^js/Promise (g (inc 1))))
(defn f [g]
(let [^js/Promise x (g (inc 1))]
(.-hello x)))
this too?
shouldn't right?
yeah this one is fine, except that it complains about hello
prop not known on Promise type, but thatās expected
I rewrote the .
handling in shadow-cljs partly because of some externs inference quirks. I can't remember the details though.
filed a ticket for that https://clojure.atlassian.net/browse/CLJS-3181
@mfikes shouldnāt cljs version of cljs.core/str
have string
return tag? Its [x & ys]
method has tag any
(probably because of .toString
call as return value)
Oh, maybe there is a bug there?
Ahh, a bug that you can see only with the apply
feature you have?
(Otherwise the macro takes care of things.)
yeah, apply
, comp
and partial
Perhaps, with higher order inference, there will be core functions other than str
that need adjustment as well.
I wonder if Closure Library type information added to cljs could solve the issue with str
, since itās return value is .toString
?
otherwise weād need return type hint
Yeah, thatās an interesting general thing: Anyone calling (.toString x)
ā¦
Based on @roman01laās focus: Addressing apply
, comp
, and partial
might open up huge swaths of type inference where you have chains of function composition where the inference chain breaks with the current compiler implementationāthis could fix that aspect š
(This could be huger than we might initially think.)
Could be interesting to have compiler optimization that rewrites (apply str args)
as (clojure.string/join args)
or something along those lines?
I think with apply
we end up with two iteration cycles, one in apply
and other in str
fn
In my opinion, yes, those are essentially intrinsics. There are a handful, now, done at the emission stage.
(If we end up with more, it might make sense to factor out an intrinsics templating engine of some sort?)
Here is where the intrinsics are implemented: https://github.com/clojure/clojurescript/blob/master/src/main/clojure/cljs/compiler.cljc#L1140 (There are more in JIRA tickets, IIRC.)
@dnolen @mfikes before wrapping up the next release please consider including https://clojure.atlassian.net/browse/CLJS-3077
talking about wrappers. would it be possible to make MetaFn
s less wrapped, so they become callable from JS?
I don't really see any way to make that work
but if somebody has a good idea let me know
but my opinion is that if you're using MetaFn
interop is not your primary concern
@thheller the patch could use a better description
so you use the second pass when you know there won't be a recur?
@dnolen it tracks whether it is in a loop or not. if in a loop it "captures" the locals in an extra wrapper fn, if not it doesn't need to.
there is no added "second pass"?
@thheller but how can you know you're in a loop if the recur is deep in the body?
the analyzer figures that out? the emit* :fn
just checks later
+ (when (or in-loop (seq recur-params))
+ (mapcat :params loop-lets))
(seq recur-params)
will be true-ish
oh right this is just during emission
ok will review it more closely when I have time
would be cool if https://clojure.atlassian.net/browse/ASYNC-230 was in the release as well
was also thinking of adding to the guide how promise.all/race/allSettled can be done with go blocks tomorrow