clojurescript

ClojureScript, a dialect of Clojure that compiles to JavaScript http://clojurescript.org | Currently at 1.10.879
2021-01-05T08:28:50.080300Z

It was only http://reagent-project.github.io/ for React then there was https://github.com/lilactown/helix ! there is also https://github.com/roman01la/uix !??

2021-01-05T08:35:41.081600Z

Would be helpful if someone who has tried out all of these and has strong opinion on them 🙂

yogidevbear 2021-01-05T09:13:51.083Z

@thegobinath I haven't used helix myself, but a work colleague has and seems to have positive things to say about it. You might have better luck asking for insights around it in #helix

2021-01-05T09:15:35.084Z

@yogidevbear for now, my idea is that, helix is a tiny library that is basically about hooks and uix is most of the other aspects of the react with its recent updates

yogidevbear 2021-01-05T09:48:11.084200Z

Possibly. I don't have personal experience with either of these projects so can't confirm either way 🙂

dnolen 2021-01-05T13:47:06.087300Z

Also, Reagent still works well, haven't tried the others

dnolen 2021-01-05T13:48:30.088100Z

One of the biggest improvements to ClojureScript UI dev wasn't a CLJS library on our project - it was Storybook - https://storybook.js.org

dnolen 2021-01-05T13:49:03.088900Z

some of this is possible w/ Devcards but Storybook has a mode optimized for React Native, so you can really "preview" the app and test the components in the simulator and on the device

dnolen 2021-01-05T13:50:29.089800Z

the other thing here was needing to work w/ devs and designers who were learning ClojureScript - but knew JS / React / CSS etc. well

dnolen 2021-01-05T13:51:19.090600Z

so we just write pure components in JS, which is fine - and then we put the app together in ClojureScript

dnolen 2021-01-05T13:51:58.091300Z

one huge benefit is that it becomes obvious what the app actually does because there's only high level code

dnolen 2021-01-05T13:52:07.091500Z

no component stuff, no styling

dnolen 2021-01-05T13:55:48.091800Z

only business logic & state

p-himik 2021-01-05T14:08:46.093Z

That's pretty cool, thanks for sharing. Before this, I was thinking of Storybook only as of another way to document and present your components.

dnolen 2021-01-05T14:52:34.093800Z

@p-himik I think Storybook is like TDD for UI, I wouldn't do another project without it

dnolen 2021-01-05T14:53:03.094400Z

the JS / ClojureScript split has a secondary benefit in that you really can't get lazy about state management since you have a hard barrier

dnolen 2021-01-05T14:53:25.094900Z

everything in Storybook has to be completely decoupled from everything, can't get lazy

dnolen 2021-01-05T14:54:15.095600Z

the end result is that there are much, much fewer bugs than in other UI projects I've worked on

dnolen 2021-01-05T14:54:41.096Z

Storybook proves the component can do what it's required to do in complete isolation

dnolen 2021-01-05T14:54:57.096700Z

and the ClojureScript bits are only about essential state management

dnolen 2021-01-05T14:55:32.097200Z

and you're not wading through irrelevant styling gunk

2021-01-05T14:56:44.097400Z

Very interresting feedback, thank @dnolen! All this set up within Krell?

dnolen 2021-01-05T14:59:13.098700Z

yes but Krell is really just a REPL, the build stuff is just plain old ClojureScript

dnolen 2021-01-05T14:59:21.099200Z

Krell is only needed when releasing because of React Native assets for advanced builds

dnolen 2021-01-05T15:00:23.099900Z

the only true custom pass

p-himik 2021-01-05T15:00:46.100600Z

I imagine if a project is 100% CLJS, it will be harder to draw that boundary between what should be a component on its own that deserves a place in a storybook and the rest.

dnolen 2021-01-05T15:01:00.101Z

all the stuff about pulling everything together is just standard tooling including leveraging :bundle

👍 1
2021-01-05T15:02:05.101900Z

Yes, that's why Krell is great, a thin layer over Reat Native 👍

Alexis Vincent 2021-01-05T15:02:38.102700Z

@dnolen given :bundle, where do you think the barriers still are between cljs and the js world? Friction wise

dnolen 2021-01-05T15:03:17.103900Z

I haven't personally encountered any issues

dnolen 2021-01-05T15:03:29.104500Z

we've written components, leveraged RN components

dnolen 2021-01-05T15:03:35.104900Z

integrated custom (iOS/Android) native modules

dnolen 2021-01-05T15:03:42.105300Z

run advanced compilation and not written a single extern

👍 1
Alexis Vincent 2021-01-05T15:04:05.106Z

Personally, I’d love to see really seamless requires between cljs and js. cljs from js and js from cljs. Is this something we might end up with?

Alexis Vincent 2021-01-05T15:04:25.106500Z

Right!

dnolen 2021-01-05T15:04:28.106600Z

the only issue is that Krell is a little rough around the edges still and hopefully can work on that

dnolen 2021-01-05T15:05:30.107800Z

cljs <-> js is really problematic because JS modules and ClojureScript namespaces are fundamentally different

Alexis Vincent 2021-01-05T15:05:36.108100Z

I’ve also wondered about esm and leveraving tools such as rollup

dnolen 2021-01-05T15:05:43.108300Z

and both require build tools

dnolen 2021-01-05T15:06:20.109Z

and ClojureScript needs it to work at the REPL which really JS users don't care about - precise hot-reloading is not really a thing post-ES6 modules

dnolen 2021-01-05T15:07:15.110200Z

I've thought about it a lot in the past but I think it's not worth the effort, but won't get in the way if someone comes w/ a good plan and patches

Alexis Vincent 2021-01-05T15:08:39.111300Z

How critical is the Closure compiler to cljs future given static analysis tools in js land?

dnolen 2021-01-05T15:09:08.111800Z

the static analysis tools in JS land still aren't that good was my impression every time I check

dnolen 2021-01-05T15:09:33.112200Z

Closure is still state of the art

Alexis Vincent 2021-01-05T15:11:07.114700Z

IS there any place for a 2 step process. cljs compile to Closure friendly but js native output, with optional closure optimisation as part of standard build tooling in a js world

dnolen 2021-01-05T15:12:00.115500Z

also Google is using more ES6 / TypeScript so perhaps Closure will make this stuff easier ...

dnolen 2021-01-05T15:12:10.115900Z

it's already a 2 step process

Alexis Vincent 2021-01-05T15:12:14.116100Z

Or is this at odds with compile chain? I’m not too clued up

Alexis Vincent 2021-01-05T15:12:30.116600Z

fair

dnolen 2021-01-05T15:12:36.116800Z

the problem is if you want a JavaScript files to depend on a ClojureScript file

dnolen 2021-01-05T15:12:40.117Z

the other way is easy

Alexis Vincent 2021-01-05T15:13:31.117700Z

Is there some literature out there about issues with that direction?

dnolen 2021-01-05T15:14:14.118700Z

I think nothing substantial

Alexis Vincent 2021-01-05T15:14:30.119100Z

Other then maybe dynamic ns declarations or late defs, doesnt a namespace look a lot like a module?

Alexis Vincent 2021-01-05T15:15:03.119400Z

^fixed

dnolen 2021-01-05T15:16:30.120200Z

yes, but the "other then maybe" is a big one

dnolen 2021-01-05T15:16:59.121Z

ES6 modules are like closures you can't get at them - ClojureScript namespaces are global objects and redefinition is trivial

dnolen 2021-01-05T15:17:39.121700Z

most of the reason you're using a Lisp is redefinition

dnolen 2021-01-05T15:18:25.122200Z

Racket works like this (which is where ES6 modules came from), and I really don't like it

dnolen 2021-01-05T15:18:49.123100Z

there's a lot of things that we do at work like REPL into a running service or a running device and do some surgical change

dnolen 2021-01-05T15:19:01.123600Z

that opaque modules close the door to

Alexis Vincent 2021-01-05T15:19:29.124100Z

Fair. Static esm exports would be an issue for compile time optimisation maybe, But why would exporting a dynamic namespace as default esm export not be suitable?

dnolen 2021-01-05T15:20:15.125Z

that is an interesting bridging idea

Alexis Vincent 2021-01-05T15:20:18.125200Z

so importing from a cljs namespace gives you a live blob

Alexis Vincent 2021-01-05T15:21:10.126700Z

and then having a second path like cljsRequire(“x.y.m”) for live stuff

dnolen 2021-01-05T15:21:21.126800Z

but I think there's lot of annoying details / non-obvious problems here

dnolen 2021-01-05T15:22:01.127500Z

but I think there's also enough stuff in ClojureScript right now to just try it

dnolen 2021-01-05T15:22:32.127900Z

writing custom passes is not that hard - https://github.com/vouch-opensource/krell/blob/master/src/krell/passes.clj

Alexis Vincent 2021-01-05T15:23:12.128900Z

^ fair, I guess I just dont have a good idea about how the compiler works. But I’ll check it out!

dnolen 2021-01-05T15:24:06.130100Z

https://www.youtube.com/watch?v=Elg17s_nwDg

dnolen 2021-01-05T15:24:24.130700Z

is a good intro

Alexis Vincent 2021-01-05T15:24:45.130900Z

I’m starting to build more into nodejs and I want to be able to integrate more natively into the ecosystem. npm publish cljs libs etc. Have people on the team writing in TS.

Alexis Vincent 2021-01-05T15:24:48.131100Z

etc

Alexis Vincent 2021-01-05T15:25:20.131800Z

Thanks! Will look into that.

Alexis Vincent 2021-01-05T15:27:02.133100Z

Not just node, but browser as well. Really feel like theres untapped value in those ecosystems, that we’re missing out on in clj(s) land

Alexis Vincent 2021-01-05T15:28:05.134100Z

:bundle and shadow-cljs go a long way to bridging the gap. But theres always work to be done

dnolen 2021-01-05T15:41:29.136Z

there's a big maybe there

Alexis Vincent 2021-01-05T15:41:41.136600Z

@dnolen Another idea re js<-cljs could be a default as suggested above, but when static defs are expected, a ns metadata tag could suggest static esm exports rather then the live default thing

dnolen 2021-01-05T15:41:44.136700Z

using JS is not that bad anymore IMO, could be improved a little

dnolen 2021-01-05T15:41:57.137100Z

the other problem w/ using CLJS from JS is how meaningful is it

dnolen 2021-01-05T15:42:11.137500Z

those fns will be bridging stuff

dnolen 2021-01-05T15:42:17.137700Z

because of the data exchange problem

dnolen 2021-01-05T15:42:46.138Z

ClojureScript data structures are not arrays and not objects

dnolen 2021-01-05T15:43:01.138400Z

and fns that can be called from JS must marshal to EDN to be idiomatic

dnolen 2021-01-05T15:43:16.138900Z

so this won't be core fns, only bridging fns

Alexis Vincent 2021-01-05T15:47:52.141700Z

Fair, but I think using cljs as a lib language can offer a bunch. I expose a cljs stuff to TS engineers in Kepler 16, and often they’re manipulating cljs data-structures from TS (they’re just opaque lib datastructures)

Alexis Vincent 2021-01-05T15:48:16.142300Z

I’d also love to be able to easily publish cljs libs that expose js interfaces

Alexis Vincent 2021-01-05T15:48:32.142700Z

And have that work in downstream compiler chains

Alexis Vincent 2021-01-05T15:49:01.143100Z

Without bundling cljs every time.

Alexis Vincent 2021-01-05T15:49:40.143700Z

Considering cljs lang as an npm lib that is simply required,

Alexis Vincent 2021-01-05T15:50:47.144800Z

So that cljs libs can use js libs that use cljs libs. And then someone wants to ship that to the browser and so they compile and optimise it downstream somewhere

Alexis Vincent 2021-01-05T15:51:01.145300Z

Like what happens in js world

dnolen 2021-01-05T15:51:32.145900Z

one wacky idea would be to write a tool that just takes ClojureScript and converts it into a series of ES6 modules and you publish that

dnolen 2021-01-05T15:51:38.146100Z

I'd be curious to see what problems you run into

dnolen 2021-01-05T15:51:54.146800Z

this could probably be done w/ compiler passes as I said above

Alexis Vincent 2021-01-05T15:52:00.147Z

Right!

Alexis Vincent 2021-01-05T15:52:36.147500Z

I could also imagine publishing clojurescript as a library to npm

dnolen 2021-01-05T15:53:02.147900Z

yes that would be the point

Alexis Vincent 2021-01-05T15:53:20.148300Z

right

Alexis Vincent 2021-01-05T15:54:32.149500Z

I misunderstood what you meant. But thats exactly it

dnolen 2021-01-05T15:58:15.149900Z

happy to see someone try that and help tweak whatever needs to be done to support that

dnolen 2021-01-05T15:58:46.150700Z

would also be interesting as it would allow better measurements between Closure and other JS tooling for ClojureScript specifically

Alexis Vincent 2021-01-05T16:01:03.152800Z

I’d support the same. Potentially financially, or time this year. Going to be building out more clj/cljs infrastructure this year for Kepler 16. Would be glad to have some of that feed back into the broader ecosystem

Alexis Vincent 2021-01-05T16:02:02.153300Z

My own time is limited. But might get some time to play

Alexis Vincent 2021-01-05T16:03:43.154200Z

I’m looking to hire someone full time into infrastructure mid 2021. Happy to commit some time to this effort

Alexis Vincent 2021-01-05T16:04:23.154600Z

Good to know we would have some of your support

dnolen 2021-01-05T16:06:42.155100Z

happy to help make things possible

lilactown 2021-01-05T16:24:03.156600Z

In helix’s docs there’s a page “Why Helix?”

lilactown 2021-01-05T16:24:43.158Z

Is there anything I could add that would make if clearer what it’s for?

uneman 2021-01-05T16:31:58.158700Z

I'm wondering why aclone is coping elements with dotimes? Isn't Array.slice much faster? https://github.com/clojure/clojurescript/blob/r1.10.773-2-g946348da/src/main/cljs/cljs/core.cljs#L432

dnolen 2021-01-05T16:40:30.159300Z

@namenu historically, no - not consistently across every JS engine

dnolen 2021-01-05T16:41:11.160100Z

we haven't measured recently should do that

Alexis Vincent 2021-01-05T16:47:24.160600Z

@dnolen Thanks for the video. Good intro

clyfe 2021-01-05T20:35:53.163400Z

Cont'd from https://ask.clojure.org/index.php/9949/macro-that-uses-cljs-async-and-clojure-async-how-to, cljs needs a designated, no-hack, future-proof way to answer compiling-cljs? when compiling clj for cljs use.

clyfe 2021-01-05T20:41:16.163700Z

Some sort of reader conditionals on macro time.

dnolen 2021-01-05T20:59:15.164900Z

@claudius.nicolae probably we could add something to env map, every macro gets that

dnolen 2021-01-05T20:59:40.165500Z

that said, very little in the analyzer has changed in a long time and I don't expect it to

clyfe 2021-01-05T21:24:28.168400Z

@dnolen Although I put it in this room, my view is that it's something clojure (as a language) should do - expand the reader conditionals to work in clj macros somehow (not necessarily that, but the point is made).

clyfe 2021-01-05T21:25:04.168900Z

Folks already use most often (:ns &amp;env) presence as a flag (which could potentially be breaking in the future)

clyfe 2021-01-05T22:09:39.169800Z

Probably because https://groups.google.com/g/clojurescript/c/iBY5HaQda4A thread.

dnolen 2021-01-05T23:43:29.172600Z

We can make a ClojureScript specific key to avoid the case where Clojure might use :ns, I don’t see anything else happening