This is really a massive release with many cool new features

My personal favorite is add-libs

You can now write single file demos or minimal examples for issues. Really lowers the friction to share small runnable snippets with people

You can also actually use it to demo Java libraries as well without all the Java boilerplate. Just poke around in the REPL and paste code into a comment on HN or wherever and anyone can replicate your "setup" and get it running exactly the same. No need to clone a repo or anything

Cool! You should post an example :)
Just tested it:

You run `clj` to get a Clojure REPL

Then you can for instance paste the following into the REPL

    (add-libs {'thi.ng/geom {:mvn/version "1.0.0-RC4"}})
    (use 'thi.ng.geom.viz.core)
    (use 'thi.ng.geom.svg.core)

    (->> {:x-axis (linear-axis
                {:domain [-10 310]
                    :range  [50 550]
                    :major  100
                    :minor  50
                    :pos    150})
        :y-axis (linear-axis
                {:domain  [0 4]
                    :range   [50 150]
                    :visible false})
        :data   [{:values  [[0 100] [10 90] [80 200] [250 300] [150 170] [110 120]
                            [210 280] [180 280] [160 240] [160 170]]
                    :attribs {:stroke-width "10px" :stroke-linecap "round" :stroke "#0af"}
                    :layout  svg-stacked-interval-plot}]}
        (svg-plot2d-cartesian)
        (svg {:width 600 :height 200})
        (serialize)
        symbol)
- the first line downloads a library and adds it to the running session

- the second and third line add the library to the REPL's default namespace

- the rest of the code makes an axis and plots some random values

- the output is then serialized and send out the REPL output

You should get a little SVG plot on the output

PS: Make sure you have version `1.12` by running with `clj --version`. If not, then (re)run the instructions here to get the latest version: https://clojure.org/guides/install_clojure

Using (add-lib 'thi.ng/geom) is sufficient here - it uses the newest version by default.
Parent specified a RC version, does it automatically use the latest RC versions as well? AFAIK, it only uses the latest stable version, but I could be wrong, it happened before.
Here is an example playing with BooFCV's Java API

It'll pop up a little window displaying an image

    (add-libs {'org.boofcv/boofcv-all {:mvn/version "0.35"}})
    (import 'boofcv.alg.color.ColorRgb
            'boofcv.core.image.ConvertImage
            'boofcv.gui.ListDisplayPanel
            'boofcv.gui.image.ShowImages
            'boofcv.io.UtilIO
            'boofcv.io.image.ConvertBufferedImage
            'boofcv.io.image.UtilImageIO
            'boofcv.struct.image.GrayU8
            'boofcv.struct.image.ImageType
            'boofcv.struct.image.Planar
            'java.awt.image.BufferedImage)
    (let [image-url  "https://kxygk.github.io/web/chengdu.jpg"
          color (ConvertBufferedImage/convertFrom (UtilImageIO/loadImage image-url)
                                                  true,
                                                  (ImageType/pl 3 GrayU8))
          weighted (GrayU8. (.width color)
                            (.height color))
          gui (ListDisplayPanel.)]
      (ColorRgb/rgbToGray_Weighted color weighted)
      (.addImage gui
                 weighted
                 (str (.width color)
                      " "
                      (.height color)))
      (ShowImages/showWindow gui
                             "RGB222"
                             true))
Does anyone remember Groovy? It has @Grab annotation which does essentially the same as add-libs you described. Very conventient for writing scripts.
> Does anyone remember Groovy?

I recall that Atlassian had some kind of scripting console where you could run Groovy and interact with its API / objects. It was useful for exploring when writing plugins for bamboo or Jira ...

  • kaba0
  • ·
  • 4 months ago
  • ·
  • [ - ]
Yes! Groovy does have quite a few under appreciated cool gems, and it’s a shame that is barely getting any attention nowadays..
  • pjmlp
  • ·
  • 4 months ago
  • ·
  • [ - ]
Note that Java has a REPL now and scripting support, although something like add-libs is still missing from available meta commands.
Java's REPL is like a kick in the nuts compared to using one in Common Lisp. How does Clojure's REPL feel like in comparison?
Haven't used neither Java's repl nor Common Lisp (just read about both of them) but at a glance Clojure's repl is much closer to CLs repl than Java's.

In fact, I think it's confusing to call the repls of language like Ruby, Java, JavaScript et al "REPL" at all, compared to what lisps offer, as the experience is so different. They're more like "Code evaluators" than anything else.

Typically when using repls outside of lisps, you'd type your code into the actual repl window, while in lisp-land you typically connect your editor to the repl and program like usual, selecting stuff to evaluate and so on.

  • lispm
  • ·
  • 4 months ago
  • ·
  • [ - ]
> Typically when using repls outside of lisps, you'd type your code into the actual repl window, while in lisp-land you typically connect your editor to the repl and program like usual, selecting stuff to evaluate and so on.

I think that's neither typical in the history of Lisp nor in other languages. For example in Mathematica and Jupyter one interacts via a Notebook interface. Smalltalk interacts via an integrated IDE. Many editors connect via LSP to language servers.

In Lisp the idea of an editor connecting to a Lisp is a bit of a historic accident. After the AI winter the Lisp development environments were no longer used.

A typical way to start Lisp from an external editor was via the editor starting a subprocess (the "inferior Lisp") and talking to it. GNU Emacs did that with IDEs for Lisp, like ILISP.

The next generation used GNU Emacs as its external development environment (instead of developing a new one in Lisp) via a network interface. SLIME was the most important one, with SWANK being the component loaded into the external Lisp, which provided a server interface.

Unfortunately the SLIME REPL itself (its read eval print loop) is not great (in general SLIME is okay to use) and other languages sadly copied the SLIME model, failing to copy various other important REPL features of Lisp. For example Clojure lacked the error handling of Lisp REPLs, which typically provide features like break loops, where one can inspect and repair errors. SLIME goes directly into a backtrace window. Thus people copied it, without knowing that there is a tradition of completely different REPL interaction. GNU Emacs is bad at multitasking, thus one REPL buffer could block the editor for a while -> multiple REPL windows were not that useful. Another way of working got lost...

> Unfortunately the SLIME REPL itself (its read eval print loop) is not great

> Another way of working got lost...

You singled out SLIME, but you've mentioned before that you use LispWorks - do you think it's also "not great"? Just curious ...

  • lispm
  • ·
  • 4 months ago
  • ·
  • [ - ]
> You singled out SLIME

Especially the REPL of SLIME / GNU Emacs.

LispWorks provides a better REPL experience.

Do you use LW's built-in editor, or emacs?
  • lispm
  • ·
  • 4 months ago
  • ·
  • [ - ]
The built-in editor. With LispWorks I don't use GNU Emacs. I have GNU Emacs configured, so that I could use it, but I don't... I use SLIME with SBCL, but mostly because of SBCL, which is a great implementation.

I'm faster and more in the flow with the LispWorks IDE.

> In fact, I think it's confusing to call the repls of language like Ruby, Java, JavaScript et al "REPL" at all

Agreed. I always call them “consoles,” since I work largely in JS and that’s what the browser calls it. There’s no way in a console to jump into a module and modify a single function without resetting any state that the module was tracking.

repl as a name kind of describes the requirements for something to be a repl - it has a read-evaluate-print loop. It would be more confusing to say that something with a read-evaluate-print loop isn't a repl.
Yeah, the problem with "REPL" is that it underdescribes what Clojure, Common Lisp, etc. can do, not that it overdescribes Ruby, Python, etc.
> Java's REPL is like a kick in the nuts compared to using one in Common Lisp.

An IDE connected to a running Java process via JDPA/JDI (Java debug interface) is probably a better comparison.

Sure, Common Lisp will allow you to load more substantial code changes into the running process, but using JDI you can "break on specific/ all exceptions" which will allow you to inspect code before the stack is unwound, you can drop frames and re-run stuff possibly after changing values.

What's funny is that I started noticing and using these possibilities at my Java job while learning Common Lisp. Before learning about Common Lisp I was almost exclusively an edit/compile/run guy, now I often take the shorter route of edit/CTRL-SHIFT-F9.

  • pjmlp
  • ·
  • 4 months ago
  • ·
  • [ - ]
Many tools are like that, unfortunately Common Lisp didn't took off, and we are still catching up, see Python and Machine Learning, instead of using a powerful dynamic language with native compilers.

However that doesn't mean Java REPL is useless.

JBang can grab dependencies for you.
I thought they were going to hold this until Clojure/conj 2024. No particular reason to believe so (besides Clojure 1.10 being released around the same time as Clojure/conj 2021 and the Datomic-becoming-free announcement being done at the very start of Clojure/conj 2023).

Still waiting on spec2, though... for now I am working around rigidity of specs by using Malli but it really isn't a first-class citizen in Clojure (mostly due to inability to check macros, and this is by design of the Clojure compiler). But you can emulate the ideas of schema/select by manipulating malli schemas as data.

The changes for functional interfaces also means we no longer have to maintain utility macros like

  (defmacro ->Consumer [f]
    `(reify java.util.function.Consumer
       (accept [this arg#]
         (~f arg#))))
and instead just pass functions directly.
I really wanted schema/select after watching “maybe not”, so wrote a library for malli: https://github.com/eval/malli-select
Malli really is what spec should have been.
What do you mean by “inability to check macros”? You can s/fdef macros with spec and it checks the calls at compile time. In fact Clojure core uses spec to check macro calls as you can see in the stack trace sometimes when you call one wrong. Do you mean something else?
Here's what I mean by Malli's inability to check macros.

https://github.com/clojure/clojure/blob/ad54fec/src/jvm/cloj...

The Clojure compiler directly calls into clojure.spec and does not expose any sort of hook for validating macros. No library can validate macros except clojure.spec. In this sense, Malli feels like a second-class citizen in Clojure compared to the built-in clojure.spec.

Ah thanks for explaining! I did not know they special cased spec. I hope that changes.
Such a pleasure to get a boatload of new features and all my code just runs on it because of the hard work dedicated to avoid breaking changes.
If you're interested in learning more about Clojure, check out the Clojure/conj conference Oct 23-25 in Alexandria, VA. https://2024.clojure-conj.org :)
Lovely to see add-libs and sync-deps, aren't many (any?) reasons to close down a session at all now.

This release feels like it had a very different scope from previous releases, contains a lot of stuff, which is exciting to see! But I hope it doesn't end up like a hairball a few releases down from increase of pace or something.

> But I hope it doesn't end up like a hairball a few releases down from increase of pace or something.

Rich Hickey and the rest of the Clojure Team are very careful designers. I wouldn't worry too much

> Rich Hickey and the rest of the Clojure Team are very careful designers. I wouldn't worry too much

I am aware of this, which is why I suppose previous releases haven't included as many features at once as this one. It's this possible change of pace that raised the question in me :)

Add to which, a lot of "new, big features" come in libraries, not the core language itself.
But my point is specifically about the features mentioned in this very release, which are all in the built-in clojure namespaces. Or did I miss something from the release notes?

In fact, the separate libraries have their own release process and isn't part of this release at all, as things should be. So not sure what you're referring to here exactly?

> So not sure what you're referring to here exactly?

That the size or pace of this release alone should cause worry about future hairballs.

Pure speculation but I believe this is the first release since Rich Hickey left nubank so could be more attention from him.
They've also hired Michael Fogus to work on Clojure, so more resources are definitely being put into developing the language.
The functional interface changes are huge. Clojure is always at its best when staying close to Java via judicious use of interop and this solves one of the major missing links.
What had become of spec? Abandoned? Any news on hopes for it?
It continues to exist and is in use. Lots of work has been done on a successor, but that is stalled while we consider what we want to do on various things.
It would be wonderful if perhaps the clojure team could do blog posts on those various things, perhaps might bring ideas to come from elsewhere.
Looks like a pretty solid release, very happy that Clojure is still going strong!
Is it going strong? I'm evaluating it for a new project. I'm considering it together with Clara[0]. However, it does give a vibe that it's not as mainstream as it was before and that the ecosystem is more sparse than what is once was.

I'm not trying to troll. I want to choose it. It seems like a good engineering decision to me, but if it's nosediving in popularity and contributors, this might bite me back in the near future.

[0] https://www.clara-rules.org/

Clojure's slow, deliberate development pace confuses people. The core team takes backwards compatibility very seriously. What you see with each new Clojure release is generally improved performance, better Java interop, and a smattering of new features. This is doubly true for 1.12 which is doing quite a bit of invisible work to make interop considerably better.

So what you don't see is a constant flux of "innovation" followed by a community having to adapt to those innovations. People pull Clojure examples out of books that are 12 or more years old and they still run.

I think there's some very exciting things in the Clojure space, such as Clerk (https://github.com/nextjournal/clerk) for live notebooks, and Babashka (https://github.com/borkdude/babashka) for amazing (and amazingly fast) scripting.

I guess that the GP didn't talk about the language itself, but the users. For me it looks like Scala and Clojure had lost many of its users because of Kotlin and newer Java versions. Generally I see a decline in the usage of functional languages since their heyday in the 2010s. I guess that's because imperative languages either get "functional features" or are "functional enough" - new ones like Rust or Swift.
  • ndr
  • ·
  • 4 months ago
  • ·
  • [ - ]
Clojure is more lindy than Scala.

If someone tells you their project is written in Scala, Golang, Groovy, Coffeescript it almost dates the project doesn't it? Not so much in Clojure.

It's niche but I can bet it's still going to be there 10 years from now, going at least as strongly as now.

I'm not so sure. I wish it were as you say but there are currently 5600 job postings mentioning Scala on LinkedIn in the USA, vs 82 that mention Clojure. 82! In the entire USA. So even in its state of relative decline, Scala might be about 70 times as used in industry as Clojure is.

Even as I flip through the 7 postings mentioning Clojure in all of Canada, only 4 of them seem to indicate the job itself makes use of the language (rather than mentioning it just as an example language as in "* Fluency in one or more languages like Ruby, Clojure, Scala, ReactJS, JavaScript, TypeScript, Java, Python - Deep understanding of internet protocols and standards.")

What Clojure dev uses LinkedIn to find jobs?

I certainly wouldn't.

  • thom
  • ·
  • 4 months ago
  • ·
  • [ - ]
What you’re seeing sounds familiar but definitely not new. I’ve used Clojure professionally for 15 years and at no point in that time have you been guaranteed critical mass around any library or framework. Clojure has always been a small ecosystem of high variance people and projects. You get things like Rama and Electric which are bold reimaginings of what systems could look like, but you also get a lot of short lived, burnt out efforts that fizzled.

The good news is nothing really _breaks_ ever, and you have access to the entire JVM ecosystem if you want it (many Clojure people find Java interop icky which I personally find moronic).

  • pjmlp
  • ·
  • 4 months ago
  • ·
  • [ - ]
Ironically, Clojure seems to be the only guest language on the JVM where the community is welcoming of the platform that makes their existence possible in first place.

Similarly to how Groovy used to be, but I am not counting it as it seems only to be around to power Gradle and little else.

Scala and Kotlin folks speak too much about replacing Java, yet I am yet to see their native variants match JVM in any form or fashion.

Even if we take Android into consideration, Google was forced to update their Java support, as means to keep Java libraries ecosystem available for Android developers and their beloved Kotlin.

I don’t do much Clojure anymore (I wish I did!) but agreed on all points. The JVM interop is such a huge, huge advantage that it’s hard to express to people who aren’t used it.
Electric looks outstanding. It seems like the sort of thing that would take some time to spread but once it does and people take the time to learn it it could be huge.
I'd categorize Clojure as stable but niche. It's not nosediving in popularity, but I don't think it's growing by leaps and bounds either. Many libraries are also stable, in the sense that they are finished - sometimes people will see no activity on a GitHub project and assume it is dead when in reality it's just done. Clojure libraries tend to be very small and focused, and often no Clojure wrapper is needed at all due to the ease of Java interop.

I love Clojure, and it's been great for me and all the professional teams I've worked on that use it.

Reagent is the clojurescript wrapper to react Reagent has the same API and the same best practices since 2014 Meanwhile, react changed from creactClass to extend Class. From classes to function components.

Many clojure libraries are simply done. There is no reason to commit everyday to a project.

I'd also look at

https://github.com/oakes/odoyle-rules/

I think the userbase is slowly shrinking, but I'd personally use Clojure even if all Clojure developers disappeared tomorrow. It's not built on shifting sand as the JVM is stable. If you need really niche/cutting edge stuff you're probably going to need to dip into Java or JS interop anyway

Thanks for the link! I’m not the parent poster, but I was thinking of using Clara Rules for prototyping a game idea and to get some experience with rule engines. I don’t think that truth maintenance (which is handled by Clara and not O’Doyle) is important for my use case, and O’Doyle looks simpler to pick up.
From the last view developer surveys I've paid attention to it didn't seem like Clojure was growing much but it's definitely still large enough of an ecosystem to be a valid choice. So, depends on your definition of 'going strong'. On its merits it's definitely still a great choice, I never really thought of it as particularly mainstream.
I found myself frustrated a lot when I used it two years ago. A lot of abandoned libraries. There's not a huge ecosystem around it compared to golang and other popular languages, but there's probably enough that it's a viable option if you really want to work with the language.
> I found myself frustrated a lot when I used it two years ago.

Sad to hear about your experience.

> A lot of abandoned libraries. There's not a huge ecosystem around it compared to golang

I found it to be the opposite. In Clojure you have Clojurists Together: https://www.clojuriststogether.org which funds people to work on Open Source libraries. And more importantly there is Clojure Commons: https://github.com/clj-commons which takes popular Clojure libraries, that are no longer being supported and carries on looking after them.

When I found popular Go libraries that have been abandoned, I asked in the Go community, if there are such initiatives, especially seeing how Google is behind Go. When people didn't understand what I meant, I pointed them at the examples above, from Clojure. To which their response was "TIL, Clojure, never heard of it before! No, we don't have such initiatives in Go."

Maybe the initiatives from Clojure Commons & Clojurists Together need more visibility for the newcomers to Clojure?

I think there is this misconception that lack of activity on libraries indicates they aren't worth using. But I strongly believe a lot of libraries are just feature complete and bug-free enough to leave them be. The syntax of the language changes so minimally that libraries don't have to change at all after updates. This isn't Javascript where everyone keeps tweaking things over and over again.
The problem this creates is that as a potential consumer I can't tell the difference between "effectively done" and "abandoned, half-done, and about to waste a lot of my time".

I don't see an easy answer to this because having "done" be an available state is extremely attractive, and forcing extra work on the author would be the wrong thing to do.

Well, picking libraries shouldn't be done willy nilly by looking at the stars in a github repo or that they contributed 5 minutes ago. There are many curated resources that help pick libraries. Here is a great one: https://www.clojure-toolbox.com/
Also the whole/part of the point of being hosted on the JVM is if there isn't a clojure lib for something you can just use a Java lib.
I agree, solid working libraries often don’t need frequent updates. Sort of Common Lisp: a lot of old very stable code that just works fine.
  • Zak
  • ·
  • 4 months ago
  • ·
  • [ - ]
Something I've found to be more true of Clojure libraries than those in most languages is that they can be finished. Once the code does the thing it set out to do, there's often no need to do anything else. The language is unlikely to break compatibility, and idiomatic code tends to be mostly functional with very clean interfaces.

The one example I can think of where that's emphatically not true is clojure-android, which was tightly coupled to the Android SDK and did not remain usable after the main developer moved on. The Android SDK does not share the aforementioned traits.

I find this to be the case in Lispy languages in general (CL, Scheme, Clojure..); I go looking for a library that does X, only to find that someone wrote one more than a decade ago. It looks weird coming from more fast paced languages, but Lisp maintainers tend to their libraries carefully and might tweak them over the years but they're mostly complete already.
Exactly.

Find a random node package that was last changed 4 years ago and it might as well be toxic waste.

Find a clj lib with the same stats and it's probably going to work smoothly.

  • thom
  • ·
  • 4 months ago
  • ·
  • [ - ]
I know a lot of people are making the case libraries are just finished not abandoned, but your feelings are valid. It’s like investing in a really low yield but dependable bond, when everyone around you is making huge gains on tech stocks. I like libraries that get more featureful over time, but sometimes you watch your friends go broke.

There are opportunity costs too, maybe you can say Spec is perfectly fine but you’d be forgiven for having mixed feelings with a massive codebase built on that in a world where many have moved to Malli or elsewhere.

But let’s also be honest, loads of promising Clojure libraries do get abandoned, not finished. ClojureQL was a brilliant, composable approach to writing SQL queries but never reached its potential and was left in a fairly buggy state. I’m probably four or five Clojure data access libraries on from that in my career now. Om was highly influential but good luck if you made an investment in that. Incanter could have been enormous but failed to reach critical mass and you’d be crazy to pick it up now. There’s ‘core’ stuff like core.logic that feels like a decade old unoptimised proof of concept that didn’t follow up any of the interesting paths it laid down. Heck, I’ve even got code that relies on libraries from Chris Zheng, who quit the scene after getting a deserved dressing down from Rich Hickey after complaining about the Clojure development process.

None of this is a moral failing on the Clojure community, and there’s no reason to be defensive about it. It’s a small ecosystem and it’s very hard to build critical mass. Clojure people often have magpie brains that pull them to work on new things. You’ve got to judge it for yourself.

This is my favourite example of a not-abandoned library: https://github.com/candera/causatum?tab=readme-ov-file#liven...

"As of this writing (25-Sep-2014) I consider this library alive and well"

... "Update 2017-Oct-16: Still true. :)"

This library has been done-done for a decade now. I used it last week.

The really nice thing about Clojure is it runs on the JVM.

The entire ecosystem could die tomorrow, and you can still compile new Clojure code for any system that supports Java in the future.

  • ·
  • 4 months ago
  • ·
  • [ - ]
  • mvc
  • ·
  • 4 months ago
  • ·
  • [ - ]
There's another Clojure rules library worth considering. It has a section in the README about why you might prefer it to Clara.

https://github.com/oakes/odoyle-rules

NuBank[0] mainly use clojure for most of their software, and NuBank is a big yet quickly growing company.

[0]: https://en.wikipedia.org/wiki/Nubank

  • rr808
  • ·
  • 4 months ago
  • ·
  • [ - ]
Its dead in the water. Sure, some people like it for their private projects and I'm sure there are some commercial products but I wouldn't touch it. I dont particularly like Scala either but at least it has Spark which means it'll be around for decades.
Scala for spark is in decline too - people prefer the Python bindings for some reason.
It's never been easier to turning existing developers into Clojure developers.

A major problem people have at first[0] is just reading the code. AIs like ChatGPT and Claude are incredibly good at explaining existing Clojure code.

As a result, developers can onboard much, much faster.

[0] After a few weeks, reading Clojure becomes second nature and you'll forget you ever COULDN'T read it.

  • pjmlp
  • ·
  • 4 months ago
  • ·
  • [ - ]
Lots of cool improvements. The main Lisp like language I usually reach for.
Clojure is great. Brining together Lisp with the Java ecosystem makeand its concurrency model makes it great for building backend system, while still enabling quick changes. One thing that I found noteworthy is that Clujure did not pickup some innovations happening at Java since like version 8, such as Invoke Dynamic in the JVM or streams.
Generally for streams, the equivalent in Clojure with sequences or transducers is much cleaner and simpler so there was not a lot of reason to want them from Clojure. However, it is important to provide interop paths to work with Java libs that make use of them.

The functional interface coercion is implemented with invokedynamic.

Dumb question: what is clojure usually used for ? (in my view, Java is for "enterprise" stuff, python for AI/data sciences, C for performance, etc.)
"Enterprise" stuff in a much less "enterprise" way is one usage, hence being based off the JVM. Rich Hickey has also mentioned the concept of "situational programs"[1] which Clojure is used in a lot. Clojure is also used in a wide variety of other areas like data science[2] or desktop applications[3] much like other general purpose programming languages.

[1] https://youtu.be/2V1FtfBDsLU?feature=shared&t=639 [2] https://scicloj.github.io/ [3] https://github.com/HumbleUI/HumbleUI

It is a general programming language (with great interop with Java). You can pretty much build anything with it - web apps (backend + frontend), APIs, Scripts, etc. Anything you can do in Python / Java you can do it in Cloujure. It even has libraries for data crunching (or can use Java libs).
It's a general purpose programming language that runs on the JVM.

It can easily interop with Java and do the same stuff that Java does ('enterprise stuff' and more).

It excels at handling data transformations, so it's popular for tasks involving complex data pipelines, analysis, or real-time processing.

Clojure’s immutable data structures and concurrency story make it great for building highly concurrent systems, so things like financial services, real-time monitoring, event processing.

Clojurescript compiles to Javascript and interops with it well, so web based front end applications. It's used for mobile app development too.

There are libraries for AI/data sciences and there's python interop via library too, so you can build Clojure apps on top of Python libs.

Native-fast shell scripts using Babashka.

I would not use it for low level system programming (eg. where C is used), but for everything else - it would be one of my first choices.

It's a very pragmatic and practical programming language, with a strong philosophy behind every design decision and the fact that it can interop with pretty much everything makes it a powerful tool in skilled hands. Learning curve is quite steep though, but well worth climbing it.

The same advantages of java in a lisp-like shell.

NuBank, OneStudyTeam, CircleCI, and Guaranteed Rate are some of the larger companies I know about personally that have significant investments in Clojure.

  • zcam
  • ·
  • 4 months ago
  • ·
  • [ - ]
Exoscale, a cloud provider is also using clojure heavily.

Pretty much anywhere where the jvm is a good fit, but given it’s a hosted language you can also use it to emit dart code or js and find it running on shoulders of others (like jank, llvm based dialect, or babashka)

A lot of banking/finance use cases.
I run an Internet-based business on top of it.

$5M ARR. Two full-time developers.

sync-deps and add-lib seems very cool
This is a wonderful language I've only just started paying attention to, watching the talks from Rich on YouTube have ruined things I loved (like Either types.) I'm struggling with how to introduce it into my company without recommending my colleagues follow my path of working through 3 books and then watching most of the conj talks from the last 12 years on 1.75x speed, while building a personal project and re-implementing a couple of services I work with every day in it... but the lessons around simplicity I think are so critical, I'm going to find a way.
I've been at an organization that went from Java to Clojure about 12 years ago. I think there were two main things that allowed us to make the move:

* No one was in love with Java. It was fine but we were doing the whole spring style super verbose Java and it felt like a lot of ceremony to get anything done. There had been an experiment with Scala previously but that hadn't taken off.

* We had a service-oriented architecture which meant we could try Clojure out on a few new services and see how it felt.

We ended up going from 2 services to moving the whole org over really quickly. A lot of excitement built up and people didn't want to be left out. At the end of things only 2 people decided they didn't want to learn Clojure.

A few other things we did:

* Bought loads of books and left them lying around

* Started a Clojure club where we booked an hour a week and did some exercises in Clojure

* Had a big meeting where we convinced everyone that Clojure was worth an experiment

* Brought in 3 consultants to do some Clojure training for everyone

* Probably strong armed everyone into watching simple made easy - it helped that lots of people had already seen it live that year

There are a few talks about it floating around although they are very very old now and I'm not sure they're worth the time!

https://whostolebenfrog.github.io/clojure,/deployments,/clou...

  • xpe
  • ·
  • 4 months ago
  • ·
  • [ - ]
> Bought loads of books and left them lying around

At strategic locations? Such as the bathroom?

  • chii
  • ·
  • 4 months ago
  • ·
  • [ - ]
Find the least important project that one person can take on, and have that be the prototype for the clojure stack.

Ideally, use someone well versed in the tech stack - otherwise, you're taking on double risk of a new tech stack plus unfamiliarity. This prototype needs to demonstrate the value of the clojure stack - which has to have a business value (aka, speed/ease of maintenance etc).

Convince the decision makers to use clojure after the above prototype showed value, and use it to extrapolate value for other projects. This will then require a transition from doing the project, to teaching others (who might not know clojure at all). You cannot rely on just telling people to watch videos or read books - they won't do it, and it will cause failure in subsequent projects.

You will have to hand hold, until the newbie "clicks". Unfortuantely, this is an uphill battle, because management will always want to hire for the "regular/normal" tech stack, and will have trouble finding clojure-ready people. So the company will continue to have to invest in teaching it to new hires, which is a drain that could tank the clojure move.

It's funny because I went the opposite direction - from clojure to Rust, and I feel my programs are more maintainable, easier to re-read code written by myself and others, and runs without needing to bring along a virtual machine.

I do like Rich's talks and agree that static typing can be taken a bit too far though.

ClojureScript in particular is much nicer to work with compared to JavaScript

  • lelag
  • ·
  • 4 months ago
  • ·
  • [ - ]
Honestly, maybe don’t. You love Clojure, that’s awesome. But introducing it at your company if it does not have a lisp culture already might not go so well. You say so yourself: lisp dialects like Clojure come with a steep learning curve, and not everyone will appreciate the shift, especially if they're comfortable with the current stack.

Forcing it on your team could create frustration, confusion, and a lot of resentment, not just toward the language, but possibly toward you. Sure, you might convert a person or two, but most will likely see it as unnecessary complexity.

If you really want to write Clojure every day, you might be better off finding a company that already embraces it instead of trying to turn your current team into Clojurists. Sometimes it’s better to enjoy something for yourself than to make it everyone else’s problem.

I'll second this. Many people are happily complacent with mainstream languages. A minority ventures out in $lang of the day for the fun of it, with functional languages being an even smaller minority.

At a minimum, build some strong clojure skills first, such that when you introduce it to anyone else, you can do so with confidence

I spent a lot of time in my early career jumping from company to company looking for the next better thing, be it tech stack, job title, pay package. It worked quite well for me early on, until I interviewed for a principal engineer role at Branch and the VP said something that struck right to my core… that I had a good interview and good experience but my work history showed someone who wouldn’t be there in two years, and they were hiring for a long term role.

I’ve vowed since then to stick it out, to work hard building something better at the companies I work at, and to make it obvious from my resume and day to day that I care about being somewhere long term. I take the idea of leaving my campsite better than I found it seriously, and if Clojure was just a fun hobby for me I wouldn’t try to introduce it at work. I think my colleagues can learn a lot from the language and paradigms that are at the core of the language, my hope isn’t that we re-write our stack in Clojure, or even that the services I write in it persist past when I leave. My hope is that I can use it as an example to show the other engineers I work with a better way, even if we do it with go in most of the stack.

it is better to have +1 company with Clojure (potentially hiring), than +1 Clojure dev looking for work
It’s not too hard to point to NuBank’s success and say we can be like that, my C-suite is already on board. Hopefully we’ll be +1 hiring for Clojure in the next year if I’m successful
Every company likes to hear about increased productivity and less bugs, and that's what Clojure/Script gives you. The trade-off is you get less resumes when hiring. The plot twist is the resumes are much higher quality.
Ha.

I personally have sat in a meeting where a clojure enthusiast was explaining how he had quickly built a system.

He could not explain the code he had written only three weeks before.

Clojure suffers heavily from a “less code is good code, write clever code not verbose code” culture.

For newcomers this creates dumpster fires that are quick to create and impossible to maintain.

Anywaaay, long story short: no. It doesn’t.

Specifically, I’ve seen it be a dumpster fire three times.

Perhaps your experience has been different; but you are flat out wrong in your generalisation; and that arrogant attitude has been the root cause of all three failures I have personally had to clean up after.

  • elric
  • ·
  • 4 months ago
  • ·
  • [ - ]
People who complain about verbosity and boilerplate in Java generally fall in 1 of 2 categories: people who haven't used Java for anything non-trivial in a very long time, or people who are bad at designing abstractions.

Less code can be good code, but they largely are orthogonal axes. Without good abstractions, it doesn't matter whether code is dense or verbose, it will be bad and difficult to grok.

Having done substantial work in both Java and Clojure, my experience with abstraction in both is that in Java, making things more abstract almost always involves making the code larger (adding more interfaces, extending existing types to those interfaces, etc) whereas in Clojure making things more abstract typically means they get smaller.

Over time and at scale, this matters quite a lot. Java code grows and grows at a super linear rate as it handles new and changing requirements. This is ultimately not sustainable. Clojure code typically grows at a more linear rate (accretion of attributes in data or operations on data), but has more tools to create abstraction that can actually (if wielded well), be sub linear instead. This kind of change is not free or easy in any language, but in Clojure it is at least possible.

  • ·
  • 4 months ago
  • ·
  • [ - ]
The way is to drop Clojure and adopt it's principles. Teach your colleagues the functional engineering principles.

You can write code that looks a lot like Clojure in any modern language now, a lot of the functional primitives have been adopted in mainstream. e.g. Async/await => channels.

I started my career as a Clojure/Clojurescript developer 12 years ago. And now I do python for ML research and Typescript for prototyping all day.

Clojure honestly help me back a lot of the time because the tooling is so far behind the large programming communities. Functional programming has a lot of good ideas, but none good enough to leave behind all the packages on pip/npm.

I would only ever advise niche programming languages for small sub-teams that are highly technical were it makes a lot of sense. Something like compiler teams, webgl/triton for GPU programming, etc...

> leave behind all the packages on pip/npm

At least for npm you don't have to do this. With shadow-cljs, nbb, and squint, you now have good mature options for consuming npm packages.

left-right-thingy makes me chuckle every time I watch "Maybe Not"
  • ·
  • 4 months ago
  • ·
  • [ - ]
Dont. It wont be appreciated because nobody but you can work on it, and one day you wont work there anymore and the company is stuck with a few projects in Clojure while the rest is on their regular tech stack. You are creating a major company risk just for your own personal benefit.
My goal isn’t personal happiness, it’s improving the code quality in our code base, without telling my colleagues “you’re doing it wrong” or other obnoxious things. I’ll let Rich do it.

I see nil panics a couple times a week, in prod. We could learn the methods and apply them in other languages, like other people said they did in this thread.

[dead]
Fantastic. Sure would love to get a clojure job one day.
  • ·
  • 4 months ago
  • ·
  • [ - ]
[dead]
We had to dump a Clojure code base for Golang because it was too slow for lambda usage. Does any of this release help with startup time?
> Does any of this release help with startup time?

Clojure (and indirectly Java) was never created with "fast startup speed" in mind. This is why things like `add-lib` (that was added in this release) is so useful, because you start your developing session once, and it stays open until you either have to restart your computer or done developing the project.

Then the typical deployment target is either "Push this .jar to a server somehow, start the process and let it run" or "User double-clicks executable, waits for application to be ready".

If you really need fast startup, you can go through something like https://github.com/ionutbalosin/faster-jvm-start-up-techniqu...

Or if you're fine with slightly worse runtime performance, give https://github.com/babashka/babashka a try

Finally, if you're OK with JavaScript you could give ClojureScript a try, has fast startup (as fast as NodeJS I suppose) but yeah, it's JavaScript.

But overall, Clojure/Java isn't optimized for the use-case of "Start process for each request, stop process once processed" so I'm guessing you'll face an uphill battle there.

No changes from clojure.

But from java world: With GraalVM/NativeImage, it is possible to compile (clojure or java) .jar files into native binaries.

Those binaries have a way faster to startup (less than 10ms for non-trivial apps)

Also, lambda engines (like AWS lambda) continuously improve their "java" target, with preloading and other things,which also benefits clojure.

TLDR; clojure startup isn't a thing that needs to be fixed. JVM startup used to be slow. And this is being resolved in the JVM itself.

Note: clojure DEV startup time is still slow-ish. Clojure DEV is usually not AOT compiled and etc. the new "sync deps" feature helps to solve this DEV problem