On the backend side, you start your server once, and whenever you change it locally, you apply what you changed directly to the running process, so you don't lose any state and without having to restart the server at all, so iterating on the program becomes very easy. Bugs are easy to track down too, as you can evaluate parts ("forms") of the program inside the process itself, debugging becomes a breeze.
On the frontend side, you have ClojureScript that basically enables the same but in a browser environment. Usually I have the browser on the right, my editor on the left, and whenever I "evaluate a function", it runs in the browser context, so again same thing; the frontend keeps the same state even after your changes, so no more "make change -> wait for compilation -> get frontend into the state that reproduces the issue -> output debug info -> make change again", you just change one part, see the page update and then continue changing.
If you've used React+Redux (or similar) before, it's basically that experience, but much tighter and together with code evaluation inside of the browser context. If I recall correctly, Redux was pretty much directly inspired by ClojureScript and Reagent in the first place, I think Abramov even referenced ClojureScritp/Reagent in the first Redux talk.
clojure itself is a joy to use, on the web or outside of it
BUT
it doesn't have the equivalent of rails, mostly because lispers are an opinionated bunch and can't come together to agree on how web development should be done
the frameworks that do exist are more of a collections of libraries with some plumbing to connect the dots
Which in reality isn't a problem, once you absorb the ideas of Clojure and try to apply them when using Clojure. Composition of well picked libraries beat batteries-included frameworks for most use cases, both short term and long term, at least in 99% of the cases I'm writing Clojure/Script code.
I think it actually is a pretty big problem. "Once you absorb the ideas of Clojure" takes months or years to fully get. Composing libraries yourself, like your comment says, requires that they are "well-picked". Stitching together separate libraries is really time consuming and a distraction from the project you're trying to build. It also results in pointless thrashing within a team as everyone has become personally invested in their own mosaic of hand-selected libraries for every little thing. By the time a beginner learning Clojure has researched and put together their web stack and got it all hooked up and is ready to start, the Django developer already shipped their project last quarter, iterated on it a few times, and is on to the next thing.
One big library/framework has huge benefits and network effects, from enabling a big 3rd party plugin ecosystem, to a deeper documentation literature (including paid courses, books, and AI). It means that there's less or virtually zero getting up to speed when changing from one project to an other. It means that the upstream framework team takes care of upgrades whereas you have to consider, when a new technology comes up, how to integrate this into your stack. There's a reason that Laravel, Django, Rails, and Spring each have thousands or hundreds-of-thousands of times more websites in production than all of Clojure combined.
At a meta/discourse level, I also find the Clojure community's tendency to constantly deny and downplay any criticism or even just issue that people face to be really frustrating and counter productive.
> By the time a beginner learning Clojure has researched and put together their web stack and got it all hooked up and is ready to start, the Django developer already shipped their project last quarter, iterated on it a few times, and is on to the next thing.
Yes, but this is intentional. Django developers are optimizing for "easy" which makes it fast to spin up project after project, Clojure developers are optimizing for "simple" which means way longer time to get the project of the ground, to nail all the design before things start to actually be put together, which makes it easier and faster to iterate on the same codebase after years of working on.
Ask the Django developer how easy it is for them to add features after a project they've done that approach with for N years, then compare it to a Clojure codebase, and you'll notice the difference.
Sure, I guess this is "downplaying" and "denying", personally I see people who disagree with me as people who disagree with me, that's fine, I thought that was why we were sharing our opinions in this forum in the first place. But anyways, if you're very deep into "frameworks are clearly superior in every case", that we disagree probably matters less. Best wishes regardless!
Rich's Simple Made Easy talk is really interesting and insightful and I still love it but I think now the distinction is brought out too often almost reflexively, and used as a crutch. Yes "simple" and "easy" are not the same thing, but nor are they opposites. Just because something is "not easy" doesn't mean it's "simple".
I think there are lots of well maintained Django projects. In fact, if I do a search on AI and on google for what one web stack probably has the lowest overall total cost of ownership including maintenance years down the line, Django usually is what comes up, without even specifically searching for/mentioning it.
> if you're very deep into "frameworks are clearly superior in every case"
This is a mischaracterization of what I have said, and is more like the extreme position that Clojure devs seem to take. The original commenter said that Clojure is wonderful, but it's too bad that [for the people who want it,] there isn't the option of a well maintained, all-in-one, batteries included framework. You deny that this is a problem, saying that actually a well-chosen set of libraries are superior (I guess in every case, because if not then it actually would be a problem sometimes).
In my experience, Clojure was a huge pain in the ass to get into, and there's a non-zero amount of community members that talk about it in nothing about aphorisms. I really wanted practical advice, but getting people to talk normally about it was an uphill battle. This made me almost quit several times. But it is a very pragmatic language underneath (which you've already mentioned).
But I'm not sure a framework is really going to change that onboarding process, or help with network effects that much. Elixir has a de facto framework, but it's barely more popular than Clojure. I mean, we had Leiningen starter kits and we have Kit. But what's confusing to me wasn't setting up a project, it was learning how it was wired together. Wiring small libraries together and just passing data can feel surprisingly leaky, and I don't really have to peak into the internals of Laravel the way I do Clojure projects.
I think Biff is a promising step in the right direction. I think the way it has wired things up is easier to follow. But for whatever reason, they made the choice to use XTDB as a default, which is a huge cognitive burden for newcomers. They have an article on how to use something else instead, but this is already getting out of the "it just works" territory if you haven't even learned Clojure yet. But the author is a really nice and talented person, and I am looking forward to seeing where it goes.
> I think there are lots of well maintained Django projects. In fact, if I do a search on AI and on google for what one web stack probably has the lowest overall total cost of ownership including maintenance years down the line, Django usually is what comes up, without even specifically searching for/mentioning it.
Having used Clojure, Laravel, Spring, and Django, I wouldn't touch Django again with a 10 foot pole. I don't know what you're referring to by "doing a search of lowest cost of ownership" but it sounds pretty unscientific. Anecdotally, I do legacy apps, and I have picked up people's Django apps, and I've never loved what I saw. It's a classic fast to start, slow to maintain framework. Huge businesses have been built on it, but huge businesses have been built on everything.
> I'm not sure a framework is really going to change that onboarding process, or help with network effects that much
having one commonly accepted and recommended way does improve onboarding, because it collapses the decision space beginners face. right now they are supposed to make decisions (not even directly, but just through selecting one of the many frameworks) about things like:
1. which project templating tool to use? (lein, clj-new, neil)
2. which dependencies management tooling to use? (lein, deps)
3. which build tooling to use? (lein, tools build, boot)
4. which web server? (jetty, httpkit, undertow)
5. which routing library? (pedestal, reitit)
6. which templating engine? (hiccup, rum, selmer)
7. how to deal with javascript and it's build tooling? (clojurescript with a host of it's own decisions, bolt ts/js and wire it yourself, dodge that completely with htmx)
whats worse - most of the alternatives overlap in various ways, so making the "best choice" in order to reduce future headache induces quite a bit of anxiety.
yes, multiple frameworks exist that make those choices for you, but then you inevitably hit the problem that some of the components haven't been updated in a while, so documentation is out of date and when you try updating it just for your project you need to fix the framework plumbing and due to number of frameworks, the corpus of useful information on the internet is quite fragmented and the community help is limited, and on and on.
none of this is good beginner experience.
and don't get me wrong, choice by itself isn't bad, focus on composability of smaller libraries is important, dominant framework is not going to improve anything when it locks people into bad decisions.
what we lack is convergence behind a single "reference stack" of libraries that ought to be good enough for the general case and a minimal framework of plumbing that doesn't require dozens of files just to get started.
there doesn't need to be a single way of doing it, but there needs to be a single recommended way of doing it.
I don't disagree with what you're saying. But by "onboarding process" I mean the effort of getting more people into Clojure, not the experience for a single person.
What I'm suggesting is Elixir has everything you're talking about in Phoenix, yet it's still an extremely niche language most people haven't even heard of. Because come on, it's a totally different paradigm than what people are trained to program in. I understand the mental math of "easier means more people," but I don't think that's really going to cut it for Clojure. I had full projects spun up the minute I started learning, but that wasn't where the difficulty was.
So yes, I think having a solid framework is good for Clojure, but the original person suggested it's not popular because it doesn't have one, and I just don't think that's true.
> the original person suggested it's not popular because it doesn't have one, and I just don't think that's true
i agree that it's not a sufficient condition, but it's an important factor and it would significantly improve the onboarding process by collapsing the decision space beginners have to navigate
even going by your definition of onboarding (the effort of getting more people) - dispersing that effort across multitude of dimensions and directions is certainly less effective than coordinating and converging
not intending to have an argument about popularity, but since you keep bringing up elixir - there's a lot that can be said about elixir/phoenix as to why they aren't more popular than they are, but they are more popular than clojure in every recent ranking i've checked ¯\_(ツ)_/¯
if anything, elixir/phoenix is a good example for how strong default improves onboarding and ecosystem cohesion, even if it doesn't make the language broadly popular
i don't look at it from perspective of "what should clojure do to be more popular than php" - there are fundamental reasons why that just can't happen in this timeline
i look at it from perspective of "what does this ecosystem lack that makes it hard for beginners to get going and stick"
and lack of "single recommended way of doing it" is at the top of my list
Yeah, Elixir's Pheonix if anything demonstrates how important a flagship framework/stack plays a huge role in driving language adoption. Despite Elixir coming out after Clojure, and running on a VM that is more esoteric/niche than the JVM, and having a host language which is 1000 times smaller in popularity and library ecosystem size, it still is probably more popular than Clojure at this point and almost all of that is from people picking up Elixir to use Pheonix. And Clojure's use is not just staying where it is, it seems to be in free fall. There used to be dozens of Clojure job postings in Canada, now without exaggeration I don't think there's a single one.
The fundamental mistake of Simple Made Easy was how many people interpreted them as orthogonal (or even opposing) qualities, when that's not inherently true.
This led to a lot of Clojure code being simple, but avoiding the hard additional work of also making it easy, and sometimes in even making it complete.
The prime example was tools.deps/deps.edn. It largely supplanted Leiningen for new code, but by being simple and minimal, it led to an explosion of ad hoc, custom tooling for 2-3 years afterwards, as everyone rewrote functionality that Lein already had, but tools.deps was missing. (And I say this as someone who once lost a whole week debugging a subtle maven/lein set ordering bug.)
Because it would have been an act of aggression to close off the strait. Iran did not want to invite war, the US and Israel have entirely been the aggressors in this recent conflict.
Incredibly fascinating. One thing is that it seems still very conceptual. What id be curious about how good of a micro llm we can train say with 12 hours of training on macbook.
Yeah. We are coping. Just today, I had a simple bug where the data received was throwing undefined because it was in 2 alternate formats.
I showed ChatGPT(free-tier) the API response and the part of the code reading it, and it fixed it in 5 seconds. Would've been pretty short either way less than 30-40 mins but it's very good for simple tasks like these. The solution is just correct.
reply