clojurescript

ClojureScript, a dialect of Clojure that compiles to JavaScript http://clojurescript.org | Currently at 1.10.879
2020-11-13T00:18:54.164100Z

Aye itโ€™s static children. Thanks!

2020-11-13T00:19:37.164500Z

Thanks!

borkdude 2020-11-13T11:37:18.166300Z

With core.async, does one still need to load cljs.core.async.macros manually?

borkdude 2020-11-13T11:37:51.166900Z

(ns repro
  (:require-macros [cljs.core.async.macros :refer [go alt!]])
  (:require [clojure.core.async :as async]))
Can one also write (async/alt! ...) now without requiring the macro namespace?

borkdude 2020-11-13T11:38:04.167300Z

I'm asking for @amorokh but I'm also curious myself.

thheller 2020-11-13T11:58:20.168200Z

(:require [clojure.core.async :as async :refer (go alt!)]) is fine, as is async/alt!. no need for .macros unless you are on a really old version.

borkdude 2020-11-13T11:58:46.168500Z

^ @amorokh

2020-11-13T11:59:08.168700Z

ah, great, thanks!

Chris Joslyn 2020-11-13T15:59:48.174600Z

I have a clojurescript library filled with reagent components. Another project I work on uses plain old React, and it wants to consume those components. I figure, essentially, I have to find a compiler that has a target that knows how to make commonjs modules. At first I tried shadow-cljs to do that. It might have worked, but when rendering the components that I have imported I see a lot of this:

Objects are not valid as a React child (found: object with keys {children}). If you meant to render a collection of children, use an array instead.
So. two part question: 1. Am I barking up the wrong tree with shadow? Is there an alternative I should try? 2. If โ€œnoโ€ to question 1, then (a shot in the dark here) do you have any leads what the problem might be?

Chris Joslyn 2020-11-13T16:16:09.175200Z

No. I had not seen this document. Iโ€™ll check it out.

borkdude 2020-11-13T16:23:01.175600Z

Why is the LazyVar in CLJS cljs/spec/gen.alpha/cljc not just a delay? https://github.com/clojure/clojurescript/blob/5e88d3383e0f950c4de410d3d6ee11769f3714f4/src/main/cljs/cljs/spec/gen/alpha.cljc#L15

cap10morgan 2020-11-13T17:42:33.178300Z

From the Closure compiler docs, it sounds like dead code elimination works at the function level (i.e. if you don't call a function, its definition will be eliminated from the final bundle). But in my own testing with CLJS (with tools-deps and target-bundle), it seems like it works at the namespace level. If I require a namespace (not even use it), that entire namespace and all code that it transitively requires gets included. Is that the expected behavior?

thheller 2020-11-13T17:45:53.179900Z

are you testing with :advanced optimizations? there are some exceptions that aren't removed by DCE but it does work at a function level

cap10morgan 2020-11-13T17:46:01.180200Z

yes

thheller 2020-11-13T17:46:43.181Z

as far as CLJS is concerned requiring a namespace will pull in all of it and its dependencies. :advanced may move stuff between "namespaces" and delete unused stuff.

thheller 2020-11-13T17:47:46.182Z

but for examples multimethods are never removed by DCE. so if you have code that has a defmulti and defmethod then that is never removed and all the code they call isn't either.

cap10morgan 2020-11-13T17:48:47.183200Z

nope, just regular functions. just requiring a namespace is adding hundreds of KBs to my final advanced optimizations JS bundle

cap10morgan 2020-11-13T17:49:05.183600Z

I would have expected it to all be eliminated by DCE

cap10morgan 2020-11-13T17:49:11.183900Z

since I'm not calling any of the fns yet

thheller 2020-11-13T17:50:23.185100Z

hard to say. depends very much on what the code actually does.

thheller 2020-11-13T17:50:48.185700Z

DCE definitely does work and if the code is written with that in mind it will be removed entirely

cap10morgan 2020-11-13T17:51:28.186200Z

Is there any way to get more insight into the decisions the closure compiler is making there and why?

thheller 2020-11-13T17:52:42.187300Z

it is kinda hard to debug or even tell what code is actually staying alive. in shadow-cljs there are build-reports which make this a whole lot easier but there is nothing comparable for :target :bundle https://shadow-cljs.github.io/docs/UsersGuide.html#_build_report

thheller 2020-11-13T17:54:36.188900Z

as far as the closure compiler there is no way I'm aware of to debug this in more detail

thheller 2020-11-13T17:55:21.189400Z

besides :pseudo-names true to actually even tell what any of the code even is of course ๐Ÿ˜›

thheller 2020-11-13T17:55:56.189900Z

it might be that you require some namespaces that require JS code (eg. react, react-dom). that won't be removed either.

cap10morgan 2020-11-13T17:58:32.191Z

yeah there is some of that, but it is closure-compatible so I've tried running it through the closure compiler too and the final bundle size didn't change. could be I just screwed that up somehow though. really hard to tell what closure is doing. ๐Ÿ™‚

cap10morgan 2020-11-13T17:58:51.191500Z

thanks for the insight, though. very useful.

thheller 2020-11-13T18:01:07.192400Z

"final bundle size didn't change" doesn't sound like you are using :advanced? or what are you comparing it too? :advanced will definitely make everything much much smaller even if it doesn't "remove" any code?

cap10morgan 2020-11-13T18:01:39.192900Z

I am using advanced, in the before and after of that test.

cap10morgan 2020-11-13T18:01:55.193200Z

advanced is much smaller than the other optimizations, to be sure

cap10morgan 2020-11-13T18:02:15.193700Z

I'm just trying to figure out why I'm seeing this unexpected behaviour w/r/t DCE

thheller 2020-11-13T18:05:10.194400Z

yeah its kinda tough to tell why something isn't removed. requires a lot of digging through pseudo-named code to figure out and avoiding the pitfalls

dnolen 2020-11-13T18:55:17.195200Z

@cap10morgan understanding and leveraging DCE in a precise way is a bit of black art

dnolen 2020-11-13T18:55:39.195700Z

but if you're transitively depending on React or JS stuff, it's pretty much expected to balloon your bundle

dnolen 2020-11-13T18:56:08.196200Z

you can't eliminate that stuff, and code that uses stuff that Google can't see isn't safe to eliminate

dnolen 2020-11-13T18:57:24.196900Z

if you do some simple tests with pure ClojureScript code you'll see that pretty much what you would expect from DCE is true

dnolen 2020-11-13T18:58:32.198300Z

because everything written in pure ClojureScript barring multimethods and specs (which mutate a global store) are free floating JS fns or JS types which can be understood by Closure