cljs-dev

ClojureScript compiler & std lib dev, https://clojurescript.org/community/dev
Filipe Silva 2019-11-04T08:43:55.134200Z

I cleaned up the windows logs for the failing and successful run and diffed them

Filipe Silva 2019-11-04T08:46:44.134900Z

the only real difference is that the failing run didn't have a cache hit I think? It has all these extra lines

Filipe Silva 2019-11-04T08:46:52.135Z

Filipe Silva 2019-11-04T08:49:24.135700Z

then some of the file copy and compilation logs are in different order, but the total number is the same

thheller 2019-11-04T08:50:03.136400Z

would maybe help to try get it to fail with :pseudo-names true and/or source maps

thheller 2019-11-04T08:50:10.136600Z

to at least get a clue where it fails

Filipe Silva 2019-11-04T08:50:43.137300Z

then it's interesting enough that both the failed run and successful run actually fail in the same place... but one fails with a TypeError and the other one fails with a ReferenceError

Filipe Silva 2019-11-04T08:51:30.137600Z

failed run error

WARNING: 0 error(s), 65 warning(s)
Optimizing with Google Closure Compiler, elapsed time: 50287.5409 msecs
Optimizing 373 sources, elapsed time: 50927.9967 msecs
builds/out-adv/core-advanced-test.js:1130:94 TypeError: (intermediate value).Fi is not a function
Stack:
  @builds/out-adv/core-advanced-test.js:1130:94
  @builds/out-adv/core-advanced-test.js:7201:3
TypeError: Object doesn't support property or method 'Fi'
   at Anonymous function (C:\projects\clojurescript\builds\out-adv\core-advanced-test.js:1130:90)
   at Global code (C:\projects\clojurescript\builds\out-adv\core-advanced-test.js:14:3)
type test-out.txt
V8_HOME not set, skipping V8 tests
Testing with SpiderMonkey

(no "Testing ..." messages)

Filipe Silva 2019-11-04T08:51:55.138100Z

successful run error

WARNING: 0 error(s), 65 warning(s)
Optimizing with Google Closure Compiler, elapsed time: 51853.3191 msecs
Optimizing 373 sources, elapsed time: 52504.6602 msecs
builds/out-adv/core-advanced-test.js:7196:879 ReferenceError: test is not defined
Stack:
  @builds/out-adv/core-advanced-test.js:7196:879
  @builds/out-adv/core-advanced-test.js:7201:3
ReferenceError: 'test' is not defined
   at Anonymous function (C:\projects\clojurescript\builds\out-adv\core-advanced-test.js:7196:847)
   at Global code (C:\projects\clojurescript\builds\out-adv\core-advanced-test.js:14:3)
type test-out.txt
V8_HOME not set, skipping V8 tests
Testing with SpiderMonkey

(lots of "Testing ..." messages)

Filipe Silva 2019-11-04T09:00:26.138900Z

oh, there's another difference... the downloaded version of <http://ftp.mozilla.org/pub/firefox/nightly/latest-mozilla-central/jsshell-win64.zip> seems to have a difference file size

Filipe Silva 2019-11-04T14:54:22.140400Z

heya, following up on that discussion about core.async.interop last thursday on #clojurescript

Filipe Silva 2019-11-04T14:54:47.140900Z

I put up a repo with the &lt;p! macro along with a guide in https://github.com/filipesilva/async-interop

Filipe Silva 2019-11-04T14:56:01.141800Z

cc @dnolen @thheller @lilactown @didibus (as you were the most involved in this discussion)

Filipe Silva 2019-11-04T14:57:10.142600Z

the guide is in .adoc and structured so that it could go on https://clojurescript.org/, in the guides section

Filipe Silva 2019-11-04T14:57:26.143Z

meanwhile it's also published to clojars as async-interop

Filipe Silva 2019-11-04T14:58:07.143500Z

is this a good way to put forward a proposal?

2019-11-04T15:02:15.144Z

just skimmed the code, I would recommend looking into promise-chan here: https://github.com/filipesilva/async-interop/blob/master/src/main/async_interop/interop.cljs#L6 see https://clojure.atlassian.net/browse/ASYNC-103

2019-11-04T15:03:52.144400Z

additional discussion here: https://github.com/binaryage/chromex/releases/tag/v0.6.0

Filipe Silva 2019-11-04T15:05:57.145200Z

I copied that code almost verbatim from David post in https://clojurians.slack.com/archives/C03S1L9DN/p1572541632221300 (but changed the exception to throw the original error)

Filipe Silva 2019-11-04T15:06:49.145800Z

will have to read up on promise-chan, I don't know anything about it

dnolen 2019-11-04T15:11:11.146200Z

@filipematossilva I would argue that you don't want to throw the original error

dnolen 2019-11-04T15:12:39.147600Z

though it is a matter of taste - if you annotate the thing then you know it was in fact a promise error immediately and not some other kind of issue

dnolen 2019-11-04T15:13:54.148Z

one problem with promises is that you can call reject with any kind of value you like

dnolen 2019-11-04T15:14:50.148400Z

it doesn't need to be a instance of error

Filipe Silva 2019-11-04T15:41:21.148600Z

I think I see what you mean

Filipe Silva 2019-11-04T15:41:32.148900Z

adding a new test for a value shows the problem

Filipe Silva 2019-11-04T15:41:37.149300Z

(deftest interop-catch-non-error
  (async done
         (let [err "Rejected"]
           (go
             (is (= err
                    (is (thrown?
                         js/Object
                         (&lt;p! (js/Promise.reject err))))))
             (done)))))

Filipe Silva 2019-11-04T15:41:49.149500Z

D:\sandbox\async-interop\.shadow-cljs\builds\test\dev\out\cljs-runtime\cljs.core.async.impl.ioc_helpers.js:106
throw e29069;
^
Rejected

Filipe Silva 2019-11-04T15:43:00.150100Z

so the gotcha here is that the macro should throw the ex-info and the consumer should do ex-cause themselves

Filipe Silva 2019-11-04T16:07:57.152200Z

@darwin I'm trying to figure if promise-chan would improve anything or fix any broken semantics, but I don't think it does?

Filipe Silva 2019-11-04T16:08:18.152700Z

as long as &lt;p! itself is called with a promise, the promise semantics stand

Filipe Silva 2019-11-04T16:08:21.152900Z

e.g. this works

Filipe Silva 2019-11-04T16:08:27.153100Z

(deftest interop-consumer-semantics
  (async done
         (go
          (let [p (js/Promise.resolve 42)]
            (is (= (&lt;p! p) 42))
            (is (= (&lt;p! p) 42))
            (done)))))

Filipe Silva 2019-11-04T16:08:58.153500Z

because the p-&gt;c function is calling .then on the promise itself

Filipe Silva 2019-11-04T16:10:34.154500Z

the resulting channel itself doesn't have promise semantics however, but I'm not sure it should either

Filipe Silva 2019-11-04T16:13:46.155400Z

I'm not sure if it's correct for the p-&gt;c function to not close the channel itself after a value though...

2019-11-04T16:16:06.157Z

I looked again and &lt;p! has correct semantics, it does not expose internal channel and each usage is creating a new channel, but if someone was using async-interop.interop/p-&gt;c directly, he could run into the issue that only one consumer wins taking result value

2019-11-04T16:17:53.157100Z

this should not work, I believe

Filipe Silva 2019-11-04T16:19:34.157500Z

correct, that hangs

2019-11-04T16:19:54.158200Z

with promise-chan it should work

Filipe Silva 2019-11-04T16:20:43.158700Z

I guess the question then is, should it hang or not? or rather, should p-&gt;c offer chan or promise-chan semantics?

dnolen 2019-11-04T16:21:02.159100Z

that's a good point - promise-chan is better

2019-11-04T16:22:04.160200Z

depends if you want to make p-&gt;c public, people might want to do something further with the channel, e.g. alts! or pipelines or something

2019-11-04T16:22:35.160800Z

but in that case they might want to implement their own p->c and not rely on your code, don’t know

dnolen 2019-11-04T16:24:12.163Z

this is just about interop

dnolen 2019-11-04T16:24:20.163400Z

you don't need lots of options in my opinion

Filipe Silva 2019-11-04T16:24:21.163500Z

tbh I don't have a very good POV on what should be the canonical usage... I just wanted to get the ball rolling on David's proposal of some official interop, and if both of you think promise-chain is better, then better it is

dnolen 2019-11-04T16:24:56.164400Z

if you want to trivially translate async/await code promise-chan is better

dnolen 2019-11-04T16:25:01.164600Z

fewer suprises

2019-11-04T16:25:52.165600Z

another argument might be that promise-chan might be also more lightweight, I have this feeling that normal channel must support “queues”, but promise-chan can just remember one value, so it is potentially lighter, but I don’t know exact impl

Filipe Silva 2019-11-04T16:26:02.165800Z

yes that was the original intention

Filipe Silva 2019-11-04T16:26:20.166Z

pushed and released

Filipe Silva 2019-11-04T16:27:24.167700Z

what should be my next steps to move the proposal along? maybe open a JIRA issue with the patches to core.async and a PR to clojurescript-site?

dnolen 2019-11-04T16:29:34.171100Z

just make a JIRA issue to core.async

2019-11-04T16:30:32.171600Z

I was playing lately with compiler extension to emit async/await hoping that Closure can take care of compiling it down to whatever needed. But then realized that because of scoping rules and the fact that await can't be used outside of async function, even if JS gets do {} expressions it's still has to be compiled into IIFE, when targeting older browsers.

2019-11-04T16:31:34.173300Z

do expressions proposal also discusses 'async do {}' blocks, but that's just too much :D

dnolen 2019-11-04T16:34:30.173600Z

I've also been looking over core.async

dnolen 2019-11-04T16:34:56.174200Z

updating ClojureScript core.async to match Clojure looks a like a pretty boring exercise - it could have been done long ago by anyone

dnolen 2019-11-04T16:35:54.175200Z

after that's done I don't think it would be very hard for someone to limit the scope of the transformation to compete w/ existing state machine compilation support for async/await

Filipe Silva 2019-11-04T21:14:25.175500Z

@dnolen here's the JIRA issue: https://clojure.atlassian.net/browse/ASYNC-230