cljs-dev

ClojureScript compiler & std lib dev, https://clojurescript.org/community/dev
borkdude 2019-11-08T10:07:13.203Z

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?

borkdude 2019-11-08T10:15:57.203500Z

Compiling also seems to work:

$ clj -R:cljs/dev -m cljs.main -t node -c test.imports
$ node out/main.js
#object[Object 123]

borkdude 2019-11-08T10:16:14.203800Z

So maybe I can just close the issue? Or are there other problems?

borkdude 2019-11-08T11:04:43.204200Z

^ @thheller you might know

thheller 2019-11-08T11:10:19.205Z

dunno. I guess its fine if it already works? I didn't actually test it šŸ˜›

borkdude 2019-11-08T11:13:49.205600Z

maybe it doesn't work with things that are not inferred as a class using :ctr...

thheller 2019-11-08T11:15:46.206300Z

I just tested in shadow-cljs and that has none of the new inference stuff since it still uses 1.10.520

thheller 2019-11-08T11:15:51.206500Z

so seems fine

borkdude 2019-11-08T11:16:02.206700Z

ah ok. a no-op issue then

borkdude 2019-11-08T11:16:35.207Z

I'll assign dnolen to let him be the judge to close it

2019-11-08T11:37:20.208300Z

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 %))

2019-11-08T11:40:41.209800Z

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

thheller 2019-11-08T11:47:41.211200Z

IIRC the .catch rewrite code loses :tag info. at least I have a vague memory of something like that.

thheller 2019-11-08T11:50:16.211800Z

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)))

2019-11-08T11:50:37.212200Z

warns with any random method call, not just catch

2019-11-08T11:51:46.212900Z

also warns for both lines in the above sample

thheller 2019-11-08T11:53:04.213400Z

hmm ok. may just be a missed case for externs inference

2019-11-08T11:53:17.213700Z

wtf, warns here as well

(defn f [g]
  (.-hello ^js/Promise (g (inc 1))))

thheller 2019-11-08T11:55:26.214Z

(defn f [g]
  (let [^js/Promise x (g (inc 1))]
    (.-hello x)))

thheller 2019-11-08T11:55:28.214200Z

this too?

thheller 2019-11-08T11:55:43.214400Z

shouldn't right?

2019-11-08T11:57:44.215700Z

yeah this one is fine, except that it complains about hello prop not known on Promise type, but that’s expected

thheller 2019-11-08T11:58:49.216300Z

I rewrote the . handling in shadow-cljs partly because of some externs inference quirks. I can't remember the details though.

2019-11-08T12:10:35.216700Z

filed a ticket for that https://clojure.atlassian.net/browse/CLJS-3181

2019-11-08T12:27:03.218200Z

@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)

mfikes 2019-11-08T12:27:37.218500Z

Oh, maybe there is a bug there?

mfikes 2019-11-08T12:28:03.219Z

Ahh, a bug that you can see only with the apply feature you have?

mfikes 2019-11-08T12:28:21.219500Z

(Otherwise the macro takes care of things.)

2019-11-08T12:29:02.220100Z

yeah, apply, comp and partial

mfikes 2019-11-08T12:29:27.220900Z

Perhaps, with higher order inference, there will be core functions other than str that need adjustment as well.

2019-11-08T12:31:29.222300Z

I wonder if Closure Library type information added to cljs could solve the issue with str, since it’s return value is .toString?

2019-11-08T12:31:41.222700Z

otherwise we’d need return type hint

mfikes 2019-11-08T12:32:16.223600Z

Yeah, that’s an interesting general thing: Anyone calling (.toString x)…

mfikes 2019-11-08T12:48:07.225800Z

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 šŸ™‚

1
mfikes 2019-11-08T12:49:15.226900Z

(This could be huger than we might initially think.)

2019-11-08T12:52:27.228700Z

Could be interesting to have compiler optimization that rewrites (apply str args) as (clojure.string/join args) or something along those lines?

2019-11-08T12:53:38.230400Z

I think with apply we end up with two iteration cycles, one in apply and other in str fn

mfikes 2019-11-08T12:53:40.230500Z

In my opinion, yes, those are essentially intrinsics. There are a handful, now, done at the emission stage.

mfikes 2019-11-08T12:54:16.231100Z

(If we end up with more, it might make sense to factor out an intrinsics templating engine of some sort?)

mfikes 2019-11-08T12:55:16.231600Z

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.)

thheller 2019-11-08T17:28:03.233700Z

@dnolen @mfikes before wrapping up the next release please consider including https://clojure.atlassian.net/browse/CLJS-3077

šŸ‘ 1
borkdude 2019-11-08T17:30:56.234200Z

talking about wrappers. would it be possible to make MetaFns less wrapped, so they become callable from JS?

šŸ™ 2
dnolen 2019-11-08T18:33:12.234600Z

I don't really see any way to make that work

dnolen 2019-11-08T18:33:27.234900Z

but if somebody has a good idea let me know

dnolen 2019-11-08T18:33:40.235300Z

but my opinion is that if you're using MetaFn interop is not your primary concern

dnolen 2019-11-08T18:36:17.235900Z

@thheller the patch could use a better description

dnolen 2019-11-08T18:36:28.236300Z

so you use the second pass when you know there won't be a recur?

thheller 2019-11-08T19:59:19.238Z

@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.

thheller 2019-11-08T19:59:53.238700Z

there is no added "second pass"?

dnolen 2019-11-08T20:10:10.239300Z

@thheller but how can you know you're in a loop if the recur is deep in the body?

thheller 2019-11-08T20:11:49.239700Z

the analyzer figures that out? the emit* :fn just checks later

thheller 2019-11-08T20:12:17.240Z

+                 (when (or in-loop (seq recur-params))
+                   (mapcat :params loop-lets))

thheller 2019-11-08T20:12:26.240300Z

(seq recur-params) will be true-ish

dnolen 2019-11-08T20:13:41.240600Z

oh right this is just during emission

dnolen 2019-11-08T20:13:51.240900Z

ok will review it more closely when I have time

šŸ‘ 1
Filipe Silva 2019-11-08T23:53:17.241800Z

would be cool if https://clojure.atlassian.net/browse/ASYNC-230 was in the release as well

Filipe Silva 2019-11-08T23:54:27.242700Z

was also thinking of adding to the guide how promise.all/race/allSettled can be done with go blocks tomorrow