SBCL is a great choice! It's a surprisingly dynamic system (so are other CL implementations).
A while ago, I did some private work for someone, using SBCL, and sent her the native binary I built, then forgot about the whole thing.
The client came back with some new requirements much later, when the project was concluded, and the source code was already lost by that time.
I vaguely remembered how I did things, so I spawned a REPL from the old binary, went into the relevant CL package, wrote a new function that overrides the old behavior, and the client's problem was solved.
I did all those without the original source code. It was a small thing to fix, but I can't imagine making the same fix so swiftly with any other tech stack, when the source code is lost. I was deeply impressed.
That's pretty cool, but also, get version control
Version control won't help if the repo itself has been lost to the sands of time
Very true.
Get backups
Which the client might be responsible for because the contractor might not be allowed to retain the IP
The author says they went about learning CL the wrong way. I wonder if there is a standard "community approved" way of learning the language?
Looks like vim-slime is essential to how you work with CL + vim. I've only used vim for not even 2 years, and came across vim-slime 6 months ago when working in ruby and wanting to quickly 'send' code from editor (neovim) to rails console. 2 months ago I launched a startup and for hours every day had to swat/fix repercussions of bugs that weren't apparent pre-launch (as well as doing via the console things users needed but weren't able to do because the feature to do it hadn't been built yet). It was daunting. I don't know how I'd have managed without vim + vim-slime. Probably a lot of copy/pasting from vscode. Vim + vim-slime was at least a 2x productivity improvement, and >2x increase in developer happiness.
Another huge benefit of vim and vim-slime is it is immediately valuable when you use/learn any new language. So long as the language has a REPL/console/interpreter that can be opened from the terminal or terminal emulator in any form (e.g. CL, ruby, python, bash etc etc etc) then vim + vim-slime will be a brilliant ~IDE. (Possibly the only thing I haven't been able to do but wanted to is 'send' code from neovim to the javascript console in chrome, which would be pretty awesome!)
A side note: I found doom-emacs very similar to vim, only needed ~10 or so new keyboard shortcuts to be productive in emacs. (I still much prefer vim, but I'm not so down on emacs).
>Looks like vim-slime is essential to how you work with CL
slime has some issues for me (obviously not OP) and I am not convinced lisp and vim are a good pair. lem is getting pretty good and improving by the day, find it much better to work with than vim when it comes to lisp and vim is my primary editor.
I have been using Clojure and before that Racket using only vim and vim-surround for almost a decade now.
I am sure I have left some productivity on the table not investing in workflows like cider etc but I have gotten a decent workflow using just vanilla tmux, a repl pane and vim-surround
The % matcher in vim does so much heavy lifting, I've never felt limited by a lack of slurp and barf
I actually wrote my own tiny plugin to send snippets to the repl using nc and I'm still happy enough tearing the clojure repl up and down and copying stuff in by hand because dealing with repl state can be pain. Even though I have at times had repls open for months, there is a freedom in just tearing it all down and up again.
Clojure itself has plenty of functions to load in files or snippets to help as well
Yep, I'm using the `slimv` plugin for vim and the `swank` server in a running `sbcl` instance in a second terminal tab. Since I'm on macOS, I could build a keyboard shortcut in vim that automates opening the 2nd terminal tab with the “Lisp machine + swank” when I say “connect” in vim. slimv/swank practically make vim an IDE for Lisp.
That is a very interesting journey — mine was exactly opposite, after many years with Common Lisp, I moved to Clojure and wouldn't even think of going back. I find it intriguing that the author would want to move in the other direction, especially as concurrency was mentioned (one of the main reasons why I initially looked at Clojure).
I wonder what it was about babashka that didn't work for the author. When I need a quick script with batteries included, I use babashka and it works great.
I had already written large, nontrivial apps (linked in article) which required more libraries than babashka was written with, including ones I had written but also others. I therefore needed to run native-image on my own codebase, as it was not runnable from within babashka (at the time? I don't know if it is now).
Running native-image on an already established, not-written-for-it codebase is a nightmare. I just tried again some months ago on the linked code bases. native-image wouldn't budge. Kept getting hung up on I don't even know what, the errors were way too opaque or the app just misbehaved in weird ways.
Ok, that explains why babashka wasn't suitable. I still wonder, though, about the requirement to have an executable.
I still remember many years of reading comp.lang.lisp, where the #1 complaint of newcomers was that "common lisp cannot produce a native executable". I remember being somewhat amused by this, because apparently nobody expected the same thing from other languages, like, say, Python. But apparently things have changed over the years and now CL implementations can produce bundled executables while Clojure can't — how the tables have turned :-)
> spent long, hard hours banging my head against native-image and it just wasn't working out.
it would be nice to know what exactly isn't working out and what the problems with native-image was.
Coz i think clojure is as close to perfect, imho, as a language can go without selling out.
Graalvm native image for Clojure is a solved problem. Just add this library to the project and add a flag to native image command line.
https://github.com/clj-easy/graal-build-time
This initializes Clojure classes at build time and it mostly works for pure Clojure code.
Doing complicated things (e.g. depending on native library, etc.) requires some tweaking. For example, a few packages may need to be declared as initialized at build time or run time, depending what they are doing. And any unresolved classes need to be added to reflection-config.json.
All these are easily discoverable if one talks to people in the Clojurian slack channels. Clojure is a small community, so it helps to be part of it, because there are not a lot of open materials on the Web.
> solved problem
except...
> mostly works
> requires some tweaking
> discoverable if...
I know nothing about Clojure but from your caveats I think I can see why he spent hours banging his head against a wall.
when engineers say it's a solved problem, they mean it in the same way as a mathematician saying a theorem is trivially proved.
Look at the hoops OP had to jump through to get SBCL working on Windows. I think Graal would compared favourably with that.
I actually just dusted off my old Clojure stuff to see if it was a "solved problem", and it isn't.
I grant that it might be described thus if I started out with that stack, but trying to retrofit an older code base with it is, I have found, next to impossible. You have to code around the myriad gotchas as you go or you're never going to identify all those landmines going back over it after the fact. The errors and bad behaviors are too difficult to identify, even for the `native-image` tooling.
With the great tooling Common Lisp commercial systems inherit from Lisp Machine and Interlisp-D days, it is kind of sad seeing vim being the option.
Also unless we're about Allegro or LispWorks with their own additions, the Java ecosystem tends to have more choice of mature libraries, I think ASDF isn't kind of spoiled by choice as Maven Central.
But to each their own.
I have been working with Clojure for 5+ years now. For CLI applications babashka has worked quite well for us.
Would love to know more about the problems you faced.
In my experience whenever I faced such issues - it has been because I am not using it well.
For CLOS kind of things I have found https://github.com/camsaul/methodical library quite well and the performance is better than default multimethods in core clojure implementation.
I don't understand the "Requirements Met" section, that reasoning applies to almost any programming language. You chose Common Lisp because there's a JSON library?
There's a section "hunt for new Lisp". It isn't explicitly stated in the requirements maybe because it can be inferred from there that being a Lisp is also one.
A lot of these intermediary languages are not trivial to parse safely and are a vector for exploits. It's not something you can really do on your own unless you're just supporting a specific subset for your application. Even then, you really need to know what you're doing.
Yeah I thought he would go with Rust or Go after seeing those requirements.
Clearly there was another implicit requirement - maybe it had to be a niche language?
Probably had to be a Lisp, considering the OP was coming from Clojure. Rust and Go fail that (unwritten) requirement.
Ah, it's this time of the year when we get to fantasize about cool platforms and languages before succumbing back to python, typescript or feeding the relentless AI monster in a major cloud provider.
Wondering whether a dialect like Jank [1] may be worth a shot?
> I wrote this blog post because I noticed that there have been more newcomers on the Common Lisp Discord
Even CL people are using Discord now? People really do seem to love to converge to a single place.
Unfortunately as all the interesting stuff disappears when the server closes. I know it can be remedied, but unfortunately it's not standard. Especially for CL this is crappy as a lot of things are still valid and working 10 years from now but the discord server is long gone.
I went on a similar journey a couple of years ago and ended up on Gerbil Scheme instead.
Related, Janet: https://janet-lang.org/
I especially like its github readme and the FAQ there, provides a good amount of context about the project: https://github.com/janet-lang/janet
To the extent that Julia is a Lisp (which requires some squinting and handwaving), I wonder how it stacks up against these requirements. With my limited knowledge:
1. Standalone Executables: The biggest current obstacle right away! But I believe this (as in compilation to standalone, small executables) is coming with the next version (Julia 1.12) in an early form, so maybe stabilized and reliable within this year? There does seem to be a lot of momentum in this direction.
2. Vim Workflow: vim-slime works well to my knowledge, and the overall support (eg. treesitter, LSP, etc.) is pretty good, even if VS Code is the "main" supported editor.
3. Windows/Mac/Linux Support: mostly Tier 1 support [https://julialang.org/downloads/#supported_platforms]
4. Larger Imperative Ecosystem: FFI with both C and Python are pretty standard and commonly used.
5. Runtime Speed: Crazy fast as well
6. Multithreading: Base language support is already pretty good, and there's OhMyThreads.jl [1] and data chunking libraries and many other supporting libraries around multithreading.
7. Strong Community: I'd expect Julia and CL communities to be on the same order of magnitude? Complete assumption though, in both directions. Web presence is mostly on the Discourse [2] and Slack, and the JuliaCons are pretty well attended.
8. Ecosystem: Since package management is mentioned, I'll shout out the built-in Pkg package manager, the seamless virtual environment support, and the generally quite good versioning in the ecosystem, all of which add up to a really good experience. As for particular libraries, JSON is the only one I know the answer to: JSON3.jl is a solid, standard choice. I don't know if SQLite.jl [3] would be the recommended option for SQLite or something else, HTTP.jl does the job for HTTP requests but I believe isn't particularly fast or sophisticated, and I could believe there's a subcommunity within Julia that uses "functional data structures" but I wouldn't even know where to look. But, for the ex-Clojurian, may I present Transducers.jl [4] as worth a look?
[1] https://juliafolds2.github.io/OhMyThreads.jl/stable/ [2] https://discourse.julialang.org/ [3] https://github.com/JuliaDatabases/SQLite.jl [4] https://github.com/JuliaFolds2/Transducers.jl
Last I checked, Julia actually compiled rather slowly, making development a lot less fluent than a Lisp.
Beyond that, wrapping C code from Julia is neither nicer nor worse than from CL. Wrapping C code is basically done everywhere except for a few outlier languages (Go comes to mind. It IS possible, but it means usibg cgo, which is its own world).
I liked Julia well enough, but the compile times were slow enough to be painful for me. All the best though to Julia :)
Mfiano wrote about this. https://mfiano.net/posts/2022-09-04-from-common-lisp-to-juli... . (By the last report, mfiano came back to CL.)
Refutation: https://gist.github.com/digikar99/24decb414ddfa15a220b27f674...
food for thought and feel free to chime-in: https://gist.github.com/vindarel/15f4021baad4d22d334cb5ce2be... Common Lisp VS Julia
If your looking to write CLI utilities in Clojure babashka really is awesome. It doesn't meet the author's standalone binary requirement, but it's got great startup time and comes batteries included with all sorts of helpful tools.
the lispers will never win
Win what?
tl;dr: OP was using a Lisp and they were looking for a different Lisp.
Probably the only reason why anyone would ever pick Common Lisp for a new project in 2025.
Why? Not everyone is resume grifting. It is fast, solid and has excellent developer workflows. Lot of stable (oh no, no updates for 10 years because it just works!) libraries. With CLOG it is a nice secret weapon with people wondering how you managed to move that fast. At least in our experience but we make products so we don't have to explain what it is made of or why.
lispers will never win
You'll lose first.
He cannot use Emacs and then goes to ... Vim ?!?! Nothing against Vim or Emacs, I love both but they had their time which is long gone. I am using Linux ans OSS technolgies since 95 and would have never imagined to advocate a MS product, but just use VS Code. It's awesome. VS Code managed to by-pass the qualitiy and amount of extensions/plugins in a fraction of time Emacs took decades.
VS Code support for Common Lisp is lacking. Alive extension is relatively recent and is a solo effort and thus has significant bugs and is not as feature packed as Vim/Emacs alternatives. For example, it doesn't provide structural editing. It's interaction with sbcl cache seemingly broke my project a few times.
Lots of people work with Vim and Emacs day to day, what makes them "long gone" in your opinion?
Not GP, but I've always found it weird how many people are obsessed with vi/vim and/or Emacs. I get some of the extensibility appeal of Emacs if you're a Lisp fan, but fundamentally I don't understand the appeal of "programming your brain" just to edit code. 90% of my code editing time is spent reading and thinking, not writing or modifying. Memorizing and minimizing (e.g. VimGolf) editor syntax seems like a massive waste of time and cognitive function to me. Modern IDEs have you up and running instantly, and their refactoring tools are really amazing.
I feel like there's been a boom in "editor hipsterism" in the last 10 - 15 years, while everyone has forgotten the variety of novel editors that were made in the 80s and 90s (I've forgotten them, too, I just remember seeing ads and reviews in magazines as a young programmer).
For context, I do have a basic understanding of vim because I run it on servers, but my knowledge doesn't go far beyond search and replace.
I like vim because the keybindings are familiar everywhere. For small server stuff I use vim, for most coding I use Doom Emacs (vim keybindings), and for Java I use Intellij with vim keybindings.
I mostly use Emacs because of org mode. It's way better than anything else trying to fill this hole. Otherwise I'd probably just use VSCode. But I don't want to add yet another editor to my regular use.