cljs-dev

ClojureScript compiler & std lib dev, https://clojurescript.org/community/dev
plexus 2020-08-06T09:33:51.444600Z

@dnolen

clojure -Sdeps '{:deps {org.clojure/clojurescript {:git/url "<https://github.com/clojure/clojurescript>" :sha "42bcb07b8bf23d57f98e4617e4c4c93347f09715"} reagent/reagent {:mvn/version "1.0.0-alpha2"}}}' -m cljs.main --install-deps
no node_modules gets created, npm is never called

plexus 2020-08-06T09:35:35.445200Z

because in the code path that the patch touches npm-deps will be nil rather than a map

plexus 2020-08-06T09:39:50.445900Z

in this case I also get an error on earlier versions of clojurescript, but at least it's shelling out to npm

npm ERR! 404 Not Found - GET <https://registry.npmjs.org/@cljs-oss%2fmodule-deps> - Not found

plexus 2020-08-06T11:40:42.446800Z

I finally got around to trying out emitting require statements from a macro, the thing we talked about a while back (https://clojurians-log.clojureverse.org/cljs-dev/2020-05-29/1590760413.380700)

plexus 2020-08-06T11:41:25.447500Z

ran into two issues, the first one is small and I can submit a patch for that https://github.com/plexus/require-from-macro-test

plexus 2020-08-06T11:42:54.448900Z

the second issue is that the required namespaces are not actually getting compiled. Is that something that could/should work, or is it up to me to do that as part of the macro?

thheller 2020-08-06T11:43:58.449600Z

require needs to be completely static and cannot be emitted dynamically like that. no macroexpansion takes place when the files are first read to gather the ns data.

thheller 2020-08-06T11:45:37.450600Z

require was only meant to work in files that don't have a ns in the first place but are still completely static

plexus 2020-08-06T11:53:40.451100Z

@thheller David specifically suggested trying this approach, see the referenced conversation

thheller 2020-08-06T11:57:38.453100Z

yeah I saw. to get this working however you need to change a bunch of machinery and I'm not sure calling the compiler API from within a macro isn't going to lead to crazy issues.

plexus 2020-08-06T12:22:23.453700Z

https://clojure.atlassian.net/browse/CLJS-3273

plexus 2020-08-06T12:23:47.454700Z

I guess we're about to find out 🙂 this issue is for the first issue which I think is straightforward, and is separate from the question how/where/if those required namespaces should get compiled.

dnolen 2020-08-06T12:31:14.455400Z

@plexus ok, make a issue w/ that repro - I guess I haven't run into this because I don't run that with :npm-deps empty

dnolen 2020-08-06T12:32:32.455800Z

@thheller I wasn't suggesting dynamic require, that can never work

dnolen 2020-08-06T12:34:03.457200Z

@plexus the other issue is interesting, I would say unexpected since original use case (`user.cljs` and other free floating scripts) should trigger compilation of required namespaces? Any issue should talk about this more fundamental problem

thheller 2020-08-06T12:36:47.459100Z

well at what point is it a "dynamic require"? I'd say the example from Arne is dynamic

dnolen 2020-08-06T12:36:53.459300Z

that is, it should in fact work (`ns*` adding things to compilation work)

dnolen 2020-08-06T12:37:16.459800Z

@thheller dynamic how? it's happening from a macro, not at rutnime

thheller 2020-08-06T12:39:40.462Z

as in you need to macroexpand to discover new requires "dynamically". who knows what other side-effects those macroexpansions may trigger

dnolen 2020-08-06T12:42:30.462900Z

not a big deal

dnolen 2020-08-06T12:42:52.463400Z

we already have stuff like that - as long as people understand the limitations doesn't seem like there's anything to be concerned about

dnolen 2020-08-06T12:43:17.464Z

i.e. mostly useful for testing - which is what @plexus was wanting this for

thheller 2020-08-06T12:45:15.465600Z

I understand but it makes things really annoying for tools (eg. Cursive) but also the build aspects like caching, parallel-compile, etc

dnolen 2020-08-06T12:45:44.466400Z

for testing use can't matter since this is at the entry point

thheller 2020-08-06T12:45:45.466700Z

well not actually sure about Cursive. maybe it already expands macros.

dnolen 2020-08-06T12:45:49.466800Z

nor parallel compile

dnolen 2020-08-06T12:46:12.467400Z

all existing limitations apply, it's gotta be a require right after ns form

dnolen 2020-08-06T12:46:19.467700Z

so I don't see it adding much complexity either

dnolen 2020-08-06T12:47:31.468Z

I think for entry points it's actually probably something of a win

dnolen 2020-08-06T12:47:42.468500Z

since we're never going to do custom reader conditionals

dnolen 2020-08-06T12:48:02.469300Z

so this approach could get you other benefits to configure a build at the entrypoint

dnolen 2020-08-06T12:48:23.469600Z

since you can't do this stuff in ns directly

dnolen 2020-08-06T12:52:29.471800Z

interestingly ...

dnolen 2020-08-06T12:52:42.472500Z

given all the restrictions it might be possible to solve the caching issue?

dnolen 2020-08-06T12:52:51.472900Z

that would be a big win, since then you're not limited to entry point

thheller 2020-08-06T12:54:17.474300Z

I don't think that solving build related things in side-effecting macros is a good idea

dnolen 2020-08-06T12:55:00.475200Z

to be clear - this isn't new stuff anyway

dnolen 2020-08-06T12:55:23.476Z

how people use stuff that should work is up to them - we can make it better

thheller 2020-08-06T12:55:24.476100Z

heck even a simple CLJ function that just returns a "dynamic" ns form that tools can invoke to figure out the "entries" is probably better

dnolen 2020-08-06T12:55:42.476500Z

like I said - not interested in new ideas

dnolen 2020-08-06T12:55:51.476800Z

just making sure there's a way with stuff we've already done

dnolen 2020-08-06T12:56:41.477900Z

most of what @plexus has mentioned are just bugs

thheller 2020-08-06T12:56:51.478400Z

so unless I'm completely out of touch with the CLJS codebase there is still a parse-ns that reads forms only until it encounters none ns or ns*. it then stops and analzyes the deps it found

thheller 2020-08-06T12:57:29.479300Z

and then starts actual compilation

dnolen 2020-08-06T12:57:41.479700Z

parse-ns is just a general helper

dnolen 2020-08-06T12:57:55.480200Z

analyze uses, compile uses, the build stuff uses it

dnolen 2020-08-06T12:58:11.480400Z

but yeah, that's how it works

plexus 2020-08-06T13:03:52.481700Z

ok, I'll make a ticket for the :npm-deps issue, I'm not sure what the conclusion is for compiling the required files. Do I get it right that you're saying it is intended to work, and the current behavior is a bug?

thheller 2020-08-06T13:06:31.482700Z

well I guess the only issue I have with this is that is breaks some assumptions about caching I have built into shadow-cljs (eg. if the file doesn't change its ns info and requires don't either)

thheller 2020-08-06T13:07:04.483300Z

but I guess I can easily adapt that or just automatically opt of of caching in files that have ns* forms

dnolen 2020-08-06T13:07:48.484300Z

@plexus well what I want to know is why this doesn't already work

dnolen 2020-08-06T13:08:08.485100Z

i.e. you make a file a w/o a namespace that (require ...) at the top

thheller 2020-08-06T13:08:19.485600Z

but it maybe opens the doof for some more "dynamic" require and not solving those via build config (eg. (require-in-dev-only '[re-frame-10x.whatever :as x]))

dnolen 2020-08-06T13:08:30.485700Z

that should already work

dnolen 2020-08-06T13:08:52.486300Z

@thheller yes, I'm not saying you can't carried away but I think there are some easy problem you could solve w/o build tool support

dnolen 2020-08-06T13:09:29.487100Z

@plexus the whole point of (require ...) was so that you could compile scripts that don't declare ns

dnolen 2020-08-06T13:09:50.487900Z

so I'm assuming we tested this at some point so maybe there's a narrower thing that's not working here

plexus 2020-08-06T13:09:53.488Z

right but in this case there's ns + require

dnolen 2020-08-06T13:10:04.488400Z

ok so that's what I want to know 🙂

plexus 2020-08-06T13:10:15.488900Z

ns to pull in the macro which then does the require

dnolen 2020-08-06T13:10:18.489Z

minimal case showing require works fine, and ns + require doesn't

dnolen 2020-08-06T13:10:24.489200Z

the macro stuff doesn't matter really

thheller 2020-08-06T13:10:52.490100Z

assuming that this is still the relevant code then it just stops when it finds ns and doesn't look further https://github.com/clojure/clojurescript/blob/f5f9b79f6f446cef768e190971cf67fc78bf5b93/src/main/clojure/cljs/analyzer.cljc#L4439

dnolen 2020-08-06T13:10:52.490200Z

or if the macro part does matter - of course include that

plexus 2020-08-06T13:10:55.490500Z

sure

dnolen 2020-08-06T13:11:01.490900Z

@thheller oh right

dnolen 2020-08-06T13:11:08.491700Z

I see

dnolen 2020-08-06T13:11:16.492Z

the issue is that ns stops, ns* doesn't

dnolen 2020-08-06T13:11:33.492400Z

or perhaps ns* star does too - anyways don't remember

dnolen 2020-08-06T13:11:38.492600Z

@plexus let me know 😉

thheller 2020-08-06T13:11:45.492800Z

ns* recurs so that continues

dnolen 2020-08-06T13:12:28.493300Z

so that's the issue, I think if you solve that, that ns will continue if ns* exists

dnolen 2020-08-06T13:12:30.493500Z

it will work

thheller 2020-08-06T13:13:28.494500Z

well then it always analyzes the second form in each file and immediately discards it in most cases which may cost a bit of perf. probably not a big deal though.

dnolen 2020-08-06T13:14:05.495300Z

yeah, I think reading a few more form probably isn't going to matter much though

plexus 2020-08-06T13:14:17.495500Z

cool, thanks! I'll try to come up with a patch

dnolen 2020-08-06T13:14:58.495700Z

👍:skin-tone-4:

dnolen 2020-08-06T13:19:09.497400Z

@thheller definitely looks like your CLJS patch yesterday was fine and our CI setup is borked - I think what happened was that if the cache expires then WebKit master gets pulled down? will try to repro that locally and then start pinning WebKit to a known good sha that we can bump periodically

thheller 2020-08-06T13:23:29.499400Z

yeah I saw. failure looked too weird to be related to my patch 😛

mfikes 2020-08-06T13:24:20Z

I've added a separate ticket for the CI issue and was also going to take a peek if nobody else gets to it first: https://clojure.atlassian.net/browse/CLJS-3274

dnolen 2020-08-06T13:24:29.000200Z

@mfikes thanks!!!

mfikes 2020-08-06T13:32:05.001500Z

FWIW, CI is still passing in the older Travis-based tests which also make use of JSC, so a JSC regression on master (or whatever is being used in GitHub actions tests) seems to be a good theory.

dnolen 2020-08-06T13:32:39.002Z

@mfikes were you pinning to a version? or to a build you had made and reusing?

mfikes 2020-08-06T13:33:56.002400Z

@dnolen Maybe this pins it sufficiently: https://github.com/clojure/clojurescript/blob/master/.travis.yml#L14

dnolen 2020-08-06T13:34:52.003400Z

ah huh, you know I couldn't get that to work which is why I used the OS X runner

dnolen 2020-08-06T13:35:19.004Z

@mfikes fwiw, it might be nicer to track WebKit since then we can test against newer JS features when that makes sense?

dnolen 2020-08-06T13:35:27.004300Z

my impression is that version of WebKit in gtk might be old?

dnolen 2020-08-06T13:35:47.004700Z

given that this literally worked last week

dnolen 2020-08-06T13:35:56.005200Z

maybe we should just need to specify that sha to that time

mfikes 2020-08-06T13:36:14.005700Z

Yeah... I'm also running a side test in CI to see what JSC is actually returning from tap&gt;. Maybe we can catch something ahead of time and file a ticket with JSC

plexus 2020-08-06T15:03:10.007400Z

adding a recur to cljs.analyzer/parse-ns for :ns makes the basic case of (ns foo.bar) (require 'foo.baz) work, I'll submit a patch for that. The next problem is that when creating the require via a macro the macroexpansion fails, get-expander* fails to find the macro var

plexus 2020-08-06T15:06:36.008300Z

if I change it to use a requiring-resolve then it works, so this is the last thing blocking me. suggestions on how to actually fix this are welcome.

plexus 2020-08-06T15:13:32.008600Z

@dnolen here's the ticket for --install-deps https://clojure.atlassian.net/browse/CLJS-3275

plexus 2020-08-06T15:14:14.009100Z

might be enough to change it to (or (nil? npm-deps) (map? npm-deps))

dnolen 2020-08-06T15:14:38.009300Z

@plexus patch for that welcome

dnolen 2020-08-06T15:15:03.009800Z

@plexus further back - finding what macro var?

dnolen 2020-08-06T15:16:16.010700Z

a snippet would clarify things a bit

plexus 2020-08-06T15:25:40.011400Z

(ns foo.bar (:require-macros [foo.baz :refer [macro-that-requires]]))
(macro-that-requires)

thheller 2020-08-06T15:32:35.012400Z

that should solve itself if foo.baz does the proper self require and you just (ns foo.bar (:require [foo.baz :refer [macro-that-requires]]))

thheller 2020-08-06T15:36:42.012700Z

oh wait no. it doesn't actually analyze the deps at that point

dnolen 2020-08-06T15:40:09.013100Z

@plexus but what is not being resolved? the macro?

plexus 2020-08-06T15:43:27.013700Z

yes, the macro is not loaded yet when it's trying to be expanded, this causes an NPE

(.findInternedVar ^clojure.lang.Namespace
              #?(:clj (find-ns nsym) :cljs (find-macros-ns nsym)) sym)

plexus 2020-08-06T15:45:16.014500Z

@thheller the self-requires works in that the compilation succeeds, but the build is invalid, the namespace that the macro requires isn't compiled

plexus 2020-08-06T15:48:44.014900Z

where exactly are macro namespaces loaded? does the analyzer do that?

plexus 2020-08-06T15:50:56.015400Z

(signing off soon but I'll continue with this tomorrow. thanks for all the help!)

dnolen 2020-08-06T16:02:33.015900Z

@plexus ah right, there's the ns-side-effects pass in the analyzer

mfikes 2020-08-06T20:43:22.016500Z

FWIW, the CI tests are failing in JSC because it returns undefined for setTimeout. Details in https://clojure.atlassian.net/browse/CLJS-3274

dpsutton 2020-08-06T21:07:27.017100Z

interesting, i'm seeing SO posts saying that JSC doesn't implement setTimeout, setInterval, and clearTimeout