
ClojureScript 1.10.741 - Jeaye
https://clojurescript.org/news/2020-04-24-release
======
jwr
To the entire ClojureScript team: thank you so much for all the great work
that you are putting into ClojureScript!

Without ClojureScript and Clojure, I would not have been able to build and
maintain my SaaS app as a solo founder. The incidental complexity would have
crushed me. Using a single language to write code, with model (domain) code
effortlessly and fluidly shared or moved between "server-side" and "client-
side" is a game-changer.

While I don't care that much about NPM, I am extremely happy with the progress
that ClojureScript is making. Thank you!

~~~
uxcolumbo
I like reading these kind of stories.

I'm trying to learn more about Clojure / CLJS for web development
specifically, but there are so many different tools to pick from and as a
beginner it can be hard to know where to start.

And then I'm also reading about Phoenix (Elixir) and how that's better for web
dev.

If you don't mind - can you tell a bit more about your Clojure story, when you
started using it and your setup?

Or maybe you have a blog, where you wrote about this already?

I'm not an experienced programmer, hence the naive questions.

~~~
cultofmetatron
I'm building my startup in phoenix.

First of all I wanna say that Clojure is a fantastic language and if the dials
on my particular needs were different, I would have gone with Clojure and am
considering clojurescript for a subproject paired with an elixir backend.

When I started the project, realtime over WebSockets were a huge
consideration. Additionally, we weren't doing anything revolutionary from a
computer science perspective. Phoenix came in with a clear story for all the
work I wanted to accomplish.

There were well accepted and documented libraries for doing authentication and
a really nice library for accessing the database.

The language has few gotchas and is relatively easy to learn. I have no doubt
I could take a good js or python developer and have them be proficient within
2-3 weeks. Thats a big deal for when we are ready to onboard more people.

The elixir language feels a lot like clojure with a ruby like syntax. you have
maps(structs) and a similar theme of 100 functions on one data structure. When
sketching an idea, I can build my data structure out as a map and delegate to
functions based on specific properties within the structure just the same as
you would in Clojure. The language supports hygenic macros though I have been
content with using the ones provided by absinthe and the kernel.

Phoenix itself is Extremely composable. Yes there are some constraints imposed
by the language but no where near what you'd find in a more magical framework
like ruby. In every case I've run into, I've been able to granularly pull and
modify whatever functionality I've needed. middleware for instance is oriented
around plug. Plug consists of a struct that contains data pertaining to the
http request and response. ALL middleware is a function that takes a plug
struct and returns a plug struct. Its about as composable as you're going to
get. The end result is a very stable system that is really easy to reason
about.

The biggest advantage, however, has been the deployment and infrastructure
story. OTP is fantastic and lets us create workers about as easily as you
could create a controller in rails. This is big. for our mvp, we don't need to
setup redis or rabbitmq nor deal with the headaches of configuring them in
prod. I can create a pubsub worker that responds to events and broadcasts data
to the users in real-time and stay completely within phoenix.

Of course it has its downsides. For one, its definitely not my language of
choice if I was doing image processing or constraint solving. At some point,
we are going to create other microservices that handle those kinds of tasks
better and when it happens, we'll have to pull in rabbitmq or kafka. Obviously
phoenix can't have isomorphic apps like you would find with clojure and
javascript.

TLDR: if you're trying to do something really novel, go with clojure. Its a
much more flexible language with some really neat libraries that you'll need
to learn to integrate yourself. If what you're doing is CRUD but with
realtime, elixir will give you a great base ecosystem with sensible defaults
to get off the ground fast.

~~~
bcrosby95
There is another type of application where Elixir/Erlang really shines. The
most obvious example of this type of application is a web based game where you
have thousands of instances of the game running at once. The concurrency and
isolation model is pretty much a perfect fit for this.

I was trying to hack something together in Java that wouldn't kill the
database. Queries to table x would bottleneck, then table y. Add some caching
here and there as each problem cropped up. But the obvious design in Elixir
just removed most of the problems - each instance of the game works as its own
set of processes and each instance holds what it needs in memory. It's not
that I couldn't have arrived at this model with Java eventually, but it
doesn't exactly lead you there, and a language like Elixir/Erlang was
basically built with this in mind so everything is a lot easier to accomplish
than with something like Java.

I really think everyone should learn either Elixir or Erlang. There are
certain applications where OTP and BEAM just makes everything so much easier
than the alternatives. If you have the right problem it can be an insanely
productive language.

~~~
cultofmetatron
I had one case where I needed to store account data and ended up storing it in
a gen server object for each account which pushed its state to all devices
logged into that account. It was so easy to build I forgot about it but this
4-hour project would have taken over a week if I had done it in any other
language.

------
drcode
This link explains the new Webpack support in more detail:
[https://clojurescript.org/news/2020-04-24-bundle-
target](https://clojurescript.org/news/2020-04-24-bundle-target)

Though that post is pretty good, I wish someone could create a more ELI5
version of the post for people who aren't knee-deep in javascript packaging
systems. Can someone just answer some newb questions for me?

1\. I know there's a website where people store javascript packages in "npm"
which can be viewed here:
[https://www.npmjs.com/package/browse](https://www.npmjs.com/package/browse).
Does this new clojurescript functionality let me USE all those packages in
clojurescript? What are the precise limitations? In what cases do I still want
to use cljsjs? (another thing that is confusing to me, tbh)

2\. Does this new clojurescript functionality let me CREATE new npm packages
and put them on the main npm site? What is "webpack" exactly and how does it
relate to npm? If so, what are the precise limitations?

I swear I know a fair amount of stuff on other programming subjects, I just
have a blind spot when it comes to javascript packaging and packages, so this
info is really appreciated!

~~~
swannodette
1\. NPM is analogous to Maven for Java. Yes the ClojureScript bundler target
lets you use anything you've installed from NPM into your project's
`node_modules` directory. Not many limitations because we wash our hands of
dealing with this stuff - use whatever popular bundler solution you prefer.

2\. Not for creating NPM packages, just consuming them. Webpack lets you use
dependencies from NPM and package them up into a single JS (or code-split)
asset to be used on a webpage. Note, we have no integration to any particular
bundler. You could just as easily run Metro for React Native on the output and
build a mobile app.

~~~
cutler
Have you considered Parcel, going forward? It seems to be a lot lighter and
easier than Webpack.

~~~
swannodette
We have no specific integration with Webpack, so you can consider anything
since we haven't chosen for you :)

------
manishsharan
Somebody please write a book on Clojurescript, reframe and tooling -- its
about time. There are so many books on Clojure but very few on Clojurescript
and most of the existing Clojurescript books are too old and have not kept up.

I prefer learning new languages by reading books about them.

~~~
simongray
Web Development with Clojure (3rd edition) comes out later this year. It's got
both Clojure and ClojureScript in it. In fact, even Clojure books that aren't
focused on web development tend to have a ClojureScript section in them.

ClojureScript Unraveled is being updated continuously and is available for
free online: [https://funcool.github.io/clojurescript-
unraveled/](https://funcool.github.io/clojurescript-unraveled/)

But honestly, you can use Clojure books to learn ClojureScript too. They're
basically the same language, with a few minor differences based on underlying
differences in the hosts (JS and JVM). I tend to write most of my code in CLJC
style, which can be compiled for either platforms.

~~~
manishsharan
The complexity with Clojurescript is in the tooling ecosystem. With Clojure ,
you only have the repl. However, with clojurescript, your have figwheel,
shadocljs etc etc. I gave up on setting that up correctly with my IDE( Visual
Studio).

~~~
simongray
Shadow CLJS is very easy to set up and there's a whole book's worth of
documentation: [https://shadow-
cljs.github.io/docs/UsersGuide.html](https://shadow-
cljs.github.io/docs/UsersGuide.html)

You don't need figwheel (or any other tool) if you just want to write
ClojureScript. You can get a ClojureScript browser REPL like this (mac
example):

    
    
       brew install node
    
       npm install -g shadow-cljs
    
       shadow-cljs browser-repl
    

I get that it's going to be hard if you want to integrate stuff into an IDE
that doesn't support ClojureScript. I use IntelliJ with the Cursive plugin
(free version) and use `deps.edn` for dependencies since it's supported
directly in Cursive.

------
tartoran
Reading about cljs I ended up watching some videos on youtube. I for one
didn’t know cljs is so fun:
[https://m.youtube.com/watch?v=VbIawuoYAVY](https://m.youtube.com/watch?v=VbIawuoYAVY)

~~~
jmchuster
Have you seen figwheel?
[https://www.youtube.com/watch?v=KZjFVdU8VLI](https://www.youtube.com/watch?v=KZjFVdU8VLI)

------
bgorman
If Clojurescript can actually work with Webpack and external modules under
advanced compilation that is pretty amazing progress. Probably the biggest
improvement in half a decade.

~~~
piercebot
Unless I'm misunderstanding the ClojureScript team posts, one of the
motivations for tight webpack integration is that not every npm module is
compatible with advanced compilation.

From the article[0]:

> But after nearly three years since we first shipped Node module processing
> via Closure, it’s apparent that too few of the most popular libraries can be
> subjected to advanced optimizations. While we still believe there’s promise
> here, the ClojureScript community will have to show the rest of the world
> the way by developing compelling JavaScript libraries that can be readily
> consumed by popular JavaScript tools, yet still be subjected to Closure’s
> phenomenal tree shaking and code splitting when building with ClojureScript.

0: [https://clojurescript.org/news/2020-04-24-bundle-
target](https://clojurescript.org/news/2020-04-24-bundle-target)

~~~
christophilus
Is this likely? Clojurescript comes with a pretty big base bundle size due to
the runtime, right? Like hello world is still over 100kb or something before
gzip, right? (On my phone, so it’s hard to google the exact number.)

~~~
john-shaffer
That was a bug. It was fixed with this release, and swannodette added a test
to ensure the size stays under 10k bytes:
[https://github.com/clojure/clojurescript/commit/5d64c2a142e5...](https://github.com/clojure/clojurescript/commit/5d64c2a142e5b41a4e4390f563d4412502704e23)

~~~
christophilus
Swank! That’s a massive improvement. I’m going to spin up a Preact project and
see how it fares.

------
rhlsthrm
I've been really thinking about using a functional language that complies to
JS to start to learn more FP concepts and paradigms. I'm trying to decide if
ClojureScript or ReasonML is better for me. Anyone have experience with both?

~~~
enricozb
Both are beautiful in their own ways. I think ReasonML, or even SML or OCaml
might be a gentler introduction since they let you write imperative code (more
closely to what you probably write already) whenever you need to.

For example, I think there is a gradient from OCaml > Clojure > Haskell about
using mutable data structures in your code, from Encourage > Discourage >
Disallow. I think learning Haskell as your first FP might turn you off given
how strict it is in this regard. So using that as a line of reasoning, using
OCaml or ReasonML might be best since it lends an imperative hand whenever you
need it, and lets you explore all of the amazing things FP has to offer.

~~~
christophilus
I don’t know. Having used both, JS to CLJS was a much easier transition for me
than JS to Reason. CLJS makes mutation pretty trivial if the thing you’re
operating on is a JS object.

~~~
fulafel
There are built in mutable data structures now too:
[https://clojuredocs.org/clojure.core/transient](https://clojuredocs.org/clojure.core/transient)

Though their usage in public interfaces is not idiomatic Clojure and they come
closely coupled with functions to transform them back to immutable values.

You can look up eg TransientArrayMap in ClojureScript internals to see how
it's implemented on that side:
[https://github.com/clojure/clojurescript/blob/799d62fe3bba99...](https://github.com/clojure/clojurescript/blob/799d62fe3bba999287558538ca6b61501de02d49/src/main/cljs/cljs/core.cljs#L7052)

------
namelosw
Does this enable the possibility of having ClojureScript loaders for Webpack?

Shadow-cljs is great, but from time to time, it seems to be easier to
integrate with the ecosystem if it can be loaded as Webpack modules. For
example, loading arbitrary image, file, and possibly Rust modules, etc.

~~~
swannodette
Honestly not sure, I'm not a Webpack expert and have no wish to be :) But
again, as I've said elsewhere, there is no specific integration with Webpack.
The bundle feature makes no choices so it's easier for users to fully control
the integration with any JS build tool.

~~~
namelosw
Thank you for your response! ClojureScript is by far the best target-to-
browser solution I have used. The REPL experience is stunning, macros work as
expected, and Cljc compilation is seamless. Working with it is pure joy.

Thanks again for everything you did for ClojureScript, and your talks are also
really inspiring!

------
ethagnawl
This is an exciting release. Congrats to the team for their continued efforts
and for being such great stewards of the language and ecosystem.

I did have one (orthogonal) issue when following along with the tutorial
linked in the release notes and, since there's a decent chance someone here
has worked through this same issue in the last few days, I'd like to float the
question: Does anyone know of step-by-step instructions for getting
fireplace.vim to evaluate ClojureScript code?

------
christophilus
How’s the bundle size coming along? Also, I’m curious what back end most of
you are using? Node with CLJS, Clojure with???, Elixir, etc?

I’m spinning up a small side project, and started it out with vanilla JS and
Node. Bundle sizes are tiny, startup times are fast, lots of concurrent
connections, etc... But I really don’t enjoy the ecosystem or language, so am
probably going to port it over to Clojure. Clojure has spoiled me. :/

~~~
orestis
ClojureScript has a baseline which you cannot go under. Can’t remember the
exact number but it’s something like 250k (advanced compilation but not
gzipped).

For this you get the immutable data structures, and a decent chunk of the
standard library, which you would use anyway.

On top of that, everything else that you get from the ClojureScript ecosystem,
which is run through the Google Closure Compiler, is added incrementally. Use
only one function, pay only for one (and its dependencies).

~~~
solbloch
I believe this is fixed [0].

[0]:
[https://github.com/clojure/clojurescript/commit/5d64c2a142e5...](https://github.com/clojure/clojurescript/commit/5d64c2a142e5b41a4e4390f563d4412502704e23)

~~~
orestis
Well, sure, for hello world! But these days anything you do with CLJS will
involve the data structures, which is what brings in the dependencies :)

