Steel Bank Common Lisp version 2.6.7
Posted by tmtvl 6 days ago
Comments
Comment by taolson 5 days ago
Comment by p_l 5 days ago
Namely, that "SB" stands for "Sanely Bootstrappable" - something that the CMU Common Lisp was unable to do
Comment by jojohohanon 5 days ago
Comment by guenthert 5 days ago
Comment by p_l 5 days ago
The difference with SBCL is that it can compile so long as you have any CL implementation that handles certain broad, but not complete, subset of ANSI CL.
It does it by being able to compile itself in sort-of sandboxed state hosted within another CL image, and then using that compiler to build itself, without requiring to modify the host compiler like CMU
As for the bytecode, as far as I recall CMU CL did not have bytecode compiler at all - it had evaluator option, which was indeed dropped for a long time from SBCL but was recently reintroduced, partially to support efforts such as porting Kandria [1] to Nintendo Switch
Comment by jhgb 5 days ago
The byte code compilation option is described in CMUCL documentation, section 5.9 Byte Coded Compilation: https://cmucl.org/docs/cmu-user/html/Byte-Coded-Compilation....
Comment by p_l 4 days ago
That said, as mentioned, it gave no real impact on bootstrappability nor portability
Comment by pfdietz 5 days ago
Comment by wk_end 6 days ago
* the SB-SIMD contrib now supports ARM64. (Thanks to Sylvia Harrington)
* AVX512 instructions are now supported on X86-64. (Thanks to Robert Smith and Arthur Miller)
* additional support for SIMD instructions on ARM64 and X86-64. (Thanks to Arthur Miller)
These seem like pretty awesome additions. Does anyone know how SIMD works in SBCL? Is this at the codegen layer? i.e. can it auto-vectorize or anything like that? Or are these intrinsics you have to explicitly ask for?Comment by peri-cl 5 days ago
This is the first news I've seen on HN in weeks that I am genuinely excited about! I have several AVX-2 hobby projects in Common Lisp, and an AVX-512 machine. It's an unexpected surprise to read this morning that this very useful ISA is suddenly unlocked. I'll be trying it out right away.
(edit: Looks like they mean *compiler* support for AVX-512, but not SB-SIMD definitions (yet). So I believe the only way for end-users to call AVX-512 instructions right now is to write custom VOP's).
> "Or are these intrinsics you have to explicitly ask for?"
There are language SIMD types and you explicitly use SIMD functions that operate on them. I believe it's essentially the same idea as C intrinsics. You can for example write (interactively)
(u32.8+ (make-u32.8 0 1 2 3 4 5 6 7)
(u32.8 10))
;; => #<SB-EXT:SIMD-PACK-256 10 11 12 13 14 15 16 17>
And that's VPADDD under the hood. Or reading an array (loop with sum = (f32.8 0.0f0)
for index below (* 8 (floor length 8)) by 8
do (setq sum (f32.8+ (f32.8-aref array index)
sum))
finally (return sum))
which compiles down to a small loop around the vector insts VMOVUPS YMM1, [RDX+RCX*2+1]
VADDPS YMM0, YMM1, YMM0
I much prefer it to writing intrinsics in C (and the results are just as good). It's an interactive, exploratory, coding: I write small modular functions, SBCL compiles them on the fly, I glue them together with high-level language constructs.Comment by amno 3 days ago
Nice to hear! :)
It is the basic compiler support, and lots of instructions added. However, you can't use knor, knoq and similar since they require scheduling of k-masks. Not done yet. But you can certainly use some of avx512 instructions and add yourself if you need some that is not available already. Check https://github.com/sbcl/sbcl/blob/master/src/compiler/x86-64....
Comment by Archit3ch 4 days ago
Same here, but in Julia instead. Sometimes I drop down to LLVM intrinsics (e.g. to force lop3.lut on GPUs).
Comment by wild_egg 6 days ago
Comment by BoingBoomTschak 5 days ago
Comment by e12e 6 days ago
Comment by amno 3 days ago
On implementation level, it is a codegen layer. It uses a system of macros to generate instructions from a database of instructions. The database is specified manually:
https://github.com/sbcl/sbcl/tree/master/contrib/sb-simd/cod...
At compile-time, they are converted into "VOPs", i.e. intrinsic functions, which are used by the compiler to emit the actual machine instructions.
> can it auto-vectorize or anything like that?
Unfortunately, it can't.
> are these intrinsics you have to explicitly ask for?
Yes, more like higher-level intrinsics. You get quite some automation, but you are requesting manually what you need. More like a DSL, than pure intrinsics. This is how you can use it (as an example):
(defun count-lines-and-words-ascii (sap size ws-init-state) (declare (type fixnum size) (type (unsigned-byte 8) ws-init-state) (type sb-sys:system-area-pointer sap) (optimize (speed 3) (safety 0))) (loop with loop-end of-type fixnum = (logandc2 size 127) for i of-type fixnum from 0 below loop-end by 128
with 0x0 of-type u8.32 = (u8.32 #x00)
with 0x20 of-type u8.32 = (u8.32 #x20)
with 0x0A of-type u8.32 = (u8.32 #x0A)
with wa of-type u64.4 = (u64.4 0)
with la of-type u64.4 = (u64.4 0)
with ws-prev of-type u8.32 = (u8.32 ws-init-state)
for c1 = (u8.32-sap-ref sap (+ i 0))
for c2 = (u8.32-sap-ref sap (+ i 32))
for c3 = (u8.32-sap-ref sap (+ i 64))
for c4 = (u8.32-sap-ref sap (+ i 96))
do
(flet ((process-chunk (curr prev)
(let* ((ctrl (u8.32-sat- (u8.32- curr 9) 4))
(ws (u8.32-or (u8.32= ctrl 0x0) (u8.32= curr 0x20)))
(ws-shift (u8.32-alignr ws (u8.32-permute128 prev ws #x21) 15))
(wmask (u8.32-andc1 ws ws-shift))
(lmask (u8.32= curr 0x0A)))
(values wmask lmask ws))))
(multiple-value-bind (wm lm prev) (process-chunk c1 ws-prev)
(psetf wa (u64.4+ wa (u8.32-sad wm 0x0))
la (u64.4+ la (u8.32-sad lm 0x0))
ws-prev prev))
(multiple-value-bind (wm lm prev) (process-chunk c2 ws-prev)
(psetf wa (u64.4+ wa (u8.32-sad wm 0x0))
la (u64.4+ la (u8.32-sad lm 0x0))
ws-prev prev))
(multiple-value-bind (wm lm prev) (process-chunk c3 ws-prev)
(psetf wa (u64.4+ wa (u8.32-sad wm 0x0))
la (u64.4+ la (u8.32-sad lm 0x0))
ws-prev prev))
(multiple-value-bind (wm lm prev) (process-chunk c4 ws-prev)
(psetf wa (u64.4+ wa (u8.32-sad wm 0x0))
la (u64.4+ la (u8.32-sad lm 0x0))
ws-prev prev)))
finally
(return
(loop for j from loop-end below size
with words of-type fixnum = (sum-lanes wa)
with lines of-type fixnum = (sum-lanes la)
with prev-ws of-type boolean = (logbitp 31 (u8.32-movemask ws-prev))
with tlines of-type fixnum = 0
with twords of-type fixnum = 0
for byte of-type fixnum = (sb-sys:sap-ref-8 sap j)
for curr-ws of-type boolean = (or (= byte 32) (<= 9 byte 13))
do
(when (= byte 10) (incf tlines))
(when (and (not curr-ws) prev-ws) (incf twords))
(setf prev-ws curr-ws)
finally
(return (values (the fixnum (+ lines tlines))
(the fixnum (+ words twords))
nil))))))Comment by OuterVale 5 days ago
https://news.ycombinator.com/item?id=44099006
I discovered this while doing some research for a post the other day: https://vale.rocks/posts/hacker-news
Comment by SeanLuke 5 days ago
Comment by vindarel 5 days ago
Comment by maleldil 5 days ago
Comment by dmux 5 days ago
Comment by vindarel 5 days ago
I’m curious: was Arc running Racket BC or CS? I understand it got a big performance boost after switching to Chez Scheme.
dang: It was running BC. I had high hopes for switching to CS because I'd heard the same thing you had, but when I tried it, HN slowed to a crawl. This stuff is so unpredictable.
https://news.ycombinator.com/item?id=47140657Comment by soegaard 2 hours ago
I can't remember the details, but I recall that Arc was pinned to an older version of Racket and didn't benefit from improvements to BC and then later to CS.
But ... be aware that the Arc interpreter is much more dynamic than Racket, so in general normal Racket programs are more efficient than Arc programs.
Comment by HexDecOctBin 6 days ago
Comment by stackghost 6 days ago
- use SB-VM:NEW-ARENA to make a new arena
- use SB-VM:WITH-ARENA to redirect ordinary allocation into an existing arena like you would use WITH-OPEN-FILE or similar macros
The only real doc is this internals note, and it doesn't even cover NEW-ARENA which I guess is left as an exercise to the reader: https://github.com/sbcl/sbcl/blob/master/doc/internals-notes...
Comment by HexDecOctBin 5 days ago
Comment by Jach 5 days ago
Comment by baq 6 days ago
Comment by tyromaniac 6 days ago
Personally I think/hope they would have earlier discoveries / more broad usage of the deterministic systems like nix etc, which are built upon functional principles of immutability etc.
Maybe the world would be guix/Hurd!
Comment by dismalaf 6 days ago
Comment by agumonkey 5 days ago
i would argue that lispers use of mutability was much more surgical and principled but maybe i'm biased
Comment by dismalaf 5 days ago
Immutability requires lots of copying and early computers didn't have much memory to spare...
Comment by agumonkey 4 days ago
Comment by dismalaf 4 days ago
> In addition to the facilities for describing S-functions, there are facilities for using S-functions in programs written as sequences of statements along the lines of FORTRAN (4) or ALGOL (5). These features will not be described in this article
Comment by agumonkey 3 days ago
Comment by pfdietz 5 days ago
Comment by Scarblac 5 days ago
Comment by johnlorentzson 5 days ago
Comment by pfdietz 5 days ago
The use cases for images would be: delivery of applications to users, or (internally) delivery of some fixed set of underlying code that is used as a substrate for development but that wouldn't normally be changed by developers.
Normally, the developer has an image running all day, and does development and testing in it, but (unless needed for additional testing) doesn't save that image as a new binary that others can run.
Comment by tyromaniac 5 days ago
Comment by muvlon 5 days ago
Comment by attila-lendvai 5 days ago
Comment by blubber 6 days ago
Comment by zellyn 5 days ago
So while Lisp may not be purely functional, the culture hewed that way.
Comment by rprospero 5 days ago
I specifically remember the breaking point being third-party library where none of the functions had any parameters. Instead, everything was controlled by using dynamic binding to adjust the variables within the functions. Various forum members kept praising its beauty and elegance, but I found it needlessly confusing.
I have a soft spot for the Lisp family of languages. I've been using Emacs for almost thirty years and have used both Scheme and Clojure in production. However, my experiences back in 2006 have left me with a permanent bias against Common Lisp.
Comment by tyromaniac 5 days ago
Comment by neutronicus 6 days ago
Yeah, that, uh, doesn't sound like Lisp
Comment by tyromaniac 5 days ago
Comment by neutronicus 5 days ago
Comment by tyromaniac 4 days ago
To me the mythology of lisp (from my mostly outsider perspective) is more like "make everything a interoperable DSL" (although if this is what you were describing with your sentence then thats fair enough)
Comment by anthk 4 days ago
Comment by WillAdams 5 days ago
Somewhere, I have a copy of a commercial LISP for Windows which would compile to an executable --- apparently this sort of thing is still possible, but it's not widely known/used, and sadly Jean-Marie Hullot's "SOS Interface" for the Mac was co-opted to NeXTstep:
https://denninginstitute.com/itcore/userinterface/GUIHistory...
I'd dearly love to see a RAD (Rapid Application Development) tool using LISP w/ a nifty UI for working up a GUI which would compile to something easily deployed (maybe HTML5 Canvas and JavaScript) as a stand-alone/single-file web application?
Comment by brabel 5 days ago
Comment by mark_l_watson 5 days ago
re: heap based delivery: not a good idea. But, I sometimes do heap based development when I have a ton of data I want loaded every dev session, then I save a SBCL image, and restart my Lisp environment using my custom image.
Comment by actionfromafar 5 days ago
Comment by fiddlerwoaroof 5 days ago
Comment by mark_l_watson 5 days ago
Comment by attila-lendvai 5 days ago
Comment by fiddlerwoaroof 5 days ago
Comment by galaxyLogic 5 days ago
Comment by goatlover 5 days ago
Comment by igouy 5 days ago
https://books.google.com/books?id=CD8EAAAAMBAJ&lpg=PA25&dq=d...
September 1991 — "Smalltalk/V code is portable between the Windows and the OS/2 versions. And the resulting application carries no runtime charges. All for just $499.95."
(Advert on the last page of "The Smalltalk Report")
https://rmod-files.lille.inria.fr/Archives/TheSmalltalkRepor...
Comment by galaxyLogic 4 days ago
Comment by igouy 4 days ago
Comment by galaxyLogic 3 days ago
Comment by igouy 5 days ago
Comment by igouy 5 days ago
Depends what you mean. Details matter.
> You can not build new things by using "images" as components.
Depends what you mean. Details matter.
Comment by joshmarlow 5 days ago
Comment by g9550684 5 days ago
Comment by groundzeros2015 5 days ago
It’s not a hack.
Comment by pfdietz 5 days ago
Comment by groundzeros2015 5 days ago
inb4 DoS attack. That is a universal parsing problem and should be solved by configuring OS limits for your process.
Comment by pfdietz 4 days ago
Yes, it's nice we have control over it. This is a lisp thing, where features that are used to implement standard things (like the standard reader) are exposed so the user can play with them also.
But code written with custom read tables has some problems. Different code with different read tables may not be composable. If I have two packages that use incompatible read tables I can't import them into a third package and expect to be able to use their readtables there.
Also, it makes treating code as an object to be inspected, modified, and written out again difficult. This is similar to the problem of code rewriting systems on preprocessed languages like C or C++.
A different branch of Lisp put everything into S expressions. Interlisp, for example, had comments in the code as forms, so the code could be editted as S-expressions. But that was dropped from Common Lisp, which took the surface syntax more from Maclisp.
Comment by groundzeros2015 4 days ago
Comment by reddit_clone 5 days ago
Quite a while back I have read about a system based on Scheme , called termite (I don't remember which scheme that was) that can actually sling live running code/closures across network and execute them remotely..
Boggles my mind even today.
Comment by mechanicum 5 days ago
“Concurrency Oriented Programming in Termite Scheme”: http://scheme2006.cs.uchicago.edu/09-germain.pdf
Implemented in Gambit Scheme: https://github.com/FredericHamel/termite-scheme
Comment by asa400 5 days ago
Comment by dmux 5 days ago
[0] https://core.tcl-lang.org/tcllib/doc/trunk/embedded/md/tclli...
Comment by iLemming 5 days ago
We have a few services built in Clojure and we expose nrepl port on our pods in our SDEs, it's enormously helpful to test and debug things on the fly, without having to redeploy or restart anything. Without having to deal with state, caching, etc.
Comment by lenkite 5 days ago
Comment by reddit_clone 5 days ago
Also not sure what is SDE.
Comment by iLemming 5 days ago
Comment by sph 5 days ago
I imagine it would look a bit like Erlang's BEAM. No need to stop and start the application, but write a script to do hot updates of a live image.
Comment by attila-lendvai 5 days ago
Comment by whyenot 5 days ago
Comment by pfdietz 5 days ago
What stopped further development of the standard was the collapse of the market for Common Lisp.
I should note that many of the things that need changes to the language definition in other languages are just libraries in Common Lisp.
Comment by guenthert 5 days ago
Comment by BoingBoomTschak 5 days ago
Comment by dmux 5 days ago
Comment by Shorel 5 days ago
AWS already has lots of AMI and docker are essentially image based.
We would version whole images in something like git, and that's all.
Comment by groundzeros2015 5 days ago
Comment by amno 3 days ago
Comment by blubber 6 days ago
Comment by quotemstr 5 days ago
Comment by coldtea 5 days ago
Comment by epolanski 6 days ago
I'm strongly convinced, having used Scheme, CL, Racket, Clojure that Lisp is doomed to be (mostly) a hobby language.
The very power of Lisp, macros, dynamic programming, reflection lead to a mess of an ecosystem where every single developer reinvents the wheel and nobody can understand yet another DSL invented by the next developer next to them.
Racket's theme of being a "programming language for building programming languages" is just the poster child of this naivety: I don't want even more friction.
What scales and works is simple and boring.
That's by the way why also Haskell has struggled forever. Beyond its dreadful DX, poor tooling and unacceptable compilation times, the language is just plagued by compiler extensions and every single developer reinventing its own abstractions.
There was the simple haskell movement to just standardize around a set of extensions and conventions, but nope, these languages unavoidably attract people that want to stay in the ivory tower.
Really, I love both lisps and haskell, but I would take a dreadful php over them every single day at work. No contest.
Comment by offlineguy 5 days ago
On the contrary, we considered it a major reason we were able to build a quite successful stock broker and bank from scratch with a team of 4-6 people, who doubled as datacenter ops (we ran on-prem), internal tech support for the rest of the firm (~20 people) and 2.line customer support.
We quite naturally converged on a set of internal libraries for various tasks. Understanding and fixing each other’s code was not a big deal.
Coincidentally, our frontend was php. That was messier, and we conciously kept that layer as lean as possible.
Comment by ux266478 5 days ago
Not that these people are necessarily bad at their jobs, but they're definitely a personality type you should learn to identify so you can manage them properly.
Comment by epolanski 5 days ago
> I think most people who have led teams will know exactly what I'm talking about.
I've had those as leads themselves, with great benefit and pain. They further convinced me about the beauty of ugly and boring.
Comment by iLemming 5 days ago
Your line up of Lisp and Haskell next to one another is already telling - the two cultures can't be more different. Haskell culture historically have selected for people who enjoy theory for its own sake. Lisp culture genuinely prizes getting-shit-done attitude.
> What scales and works is simple and boring.
Java was exotic in 1996 and boring by 2006. If "boring" just means "widely adopted and familiar", then your notion just collapses to "what's popular is popular". True and absolutely pointless and empty.
I reckon, you're piggybacking on Dan McKinley's "Choose Boring Technology", but his point was that the innovation tokens are scarce. That is a good and true argument. But it's about organizational risk budgets, not language virtue. It says nothing about Haskell or Lisp being bad or impractical - it says being different is expensive, and you'd better be buying something with that expense. I personally disagree with that argument (in this case), because I have effectively proven that Lisp's bus factor is much smaller than even of Python or JS/TS, because modern Lisp dialects are far simpler and less convoluted and easier to train into. The experience difference and angle of opinions of two Python/JS experts can be dramatic. Having two Lispers talking "the same" language is far more plausible in practice. Not to mention that ROI from hiring a practicing Lisper (regardless of the business stack) more likely to exceed of a programmer without such knowledge.
Let me remind you that Python was considered a niche scripting toy at some point when it was the same age of [niche] Clojure today. It got boring by riding two waves that had nothing to do with the language design: web (Django/Flask) and then, decisively, being in the right place and time when scientific computing and ML needed a glue language.
Boring things survive by mass, inertia, and being unremarkable - COBOL endures because ripping it out of banks is too expensive, not because anyone loves it. Lisp survives by being remarkable - by smaller population who see the thing the majority can't, regenerating the flame across dialects out of conviction, not inertia.
What scales and works is boring, that is true. Lisp is not that, never will be, and doesn't care. What has enduring value survives regardless of adoption - that is Unix, SQL, lambda calculus itself. I'm sure you won't be arguing that any of these are impractical. Anyone can wholeheartedly accept every new rising and falling, boring COBOL and chase every new hype cycle, or just quietly keep feeding on truly everlasting ideas. Or, like in my case, nothing stands in your way of combining both - I use plenty of boring languages at work, and efficiently utilize Lisp for my personal computing. Because the darn thing just fucking works!
Comment by anthk 4 days ago
SICP tells me otherwise.
Comment by vincent-manis 4 days ago
Comment by iLemming 4 days ago
NuBank: from ~12M customers in 2019, grown to 25M in a year, then to 48M at IPO a year later, then to 114M in 2024, to 131M in 2025 - 991.67% growth within 6 years and still going. Not in theory, not conceptually, not because "SICP has told them". They did get-the-shit-done. Not acknowledging that Datomic and Clojure has something to do with this succes would be simply a dishonest gesture.
Walmart - the canonical "Clojure at scale" story. The eReceipts system processed every purchase across 5,000+ US stores plus online/mobile, built and maintained by just 8 developers. Architect Anthony Marcar's line after Black Friday: the system "handled its first Walmart Black Friday and came out without a scratch". They cited 5-10x less code than alternatives.
Apple - known for using Lisp for a long time.
Metabase - open-source BI. ~46k GitHub stars.
Amperity - customer data platform, "99% Clojure" - their own quote.
Netflix - been using Clojure since forever. Watch their talk from the last year's Conj. It's eye-opening on stability of complex systems.
Cisco - malware analysis platform. Multiple huge Clojure projects: IROH - Incident Response Orchestration Hub, CTIM/CTIA - Cisco Threat Intelligence Model and API, etc.
Braintree/PayPal - payments backend. CircleCI. Grammarly (this guys are on SBCL)
And that's just a short list of actual, real, profitable businesses built with and maintained using Lisp. I don't know what "SICP has told" you, but maybe you just need to look around, things have changed a bit since then.
Comment by anthk 4 days ago
Comment by iLemming 4 days ago
My initial point was about cultures - Haskelites are typically very smart, extremely mathy, and they'd often choose certain ways even if it takes them forever and requires reading and analyzing dozens of academic papers, just because "Galois was a genius and we can make this theory fit here, because then we can center infinite divs on infinitely large DOM entities...", then publishes a paper "Coequalizers for Vertical Alignment: A Comonadic Approach"
A Lisper would be like: "Ahem... I wrapped the whole thing in a macro. Yes, it evals a string. Yes, the string is generated by another macro. No, I will not be explaining it. It shipped Tuesday, it prints money, it works. Gotta go, kids need dinner.."
Comment by anthk 4 days ago
Comment by rootnod3 3 days ago
Also, where do you go from "preferring strong CS theoretical grounds" to "cutting corners"? They don't have to be mutually exclusive.
That garbage collection that Haskell has? Guess where that came from. The whole "functions as data to pass around", guess where that came from. It was those pesky lispers on a Tuesday.
Edit: typo
Comment by iLemming 2 days ago
Da hell you're talking about, friend? I said nothing about "people", or them being smart or dumb; just a difference in cultural stereotypes.
Now you're ironically "proving the point" I didn't make by saying some dumb shit and pulling me into this pit too. If I was actually smarter I'd probably just ignored it. Reminds me Billy Madison quote: "everyone in this room is now dumber for having listened to it. I award you no points, and may God have mercy on your soul."
Comment by anthk 13 hours ago
Again, check HAKMEM from ITS/Maclisp/PDP10's (The OS from Richard Stallman took all the ideas for GNU Emacs, the GPL license, the free software movemement and whatnot). Lisp itself accounts for tons of papers and innovation.
Comment by Jach 4 days ago
Comment by anthk 4 days ago
I'd woudn't consider SICP negative, the same with all the good CL books (Intro to Symbolic Computation, Paradigms of AI Programming...)
Both are the ur-examples on how to grasp the basic of CS well.
Comment by vincent-manis 5 days ago
The fact that Lisp is the “programmable programming language” doesn't mean that every engineer should be inventing weird versions of while loops. What it does mean is that a skilled Lisp programmer can build a domain-specific language that substantially helps in development.
One good example of this is the Crash Bandicoot games, along with the same studio's Jax and Daxter, which were built with dialects of Lisp (yes, they had to compile the code, and take care with storage allocation, just like any other game code). Cisco hired Kent Dybvig, principal author of the Chez Scheme system, and open-sourced that software; I have no clue what they use it for, to be honest, but I assume that they had some reason for doing this. Companies using various Lisp languages have been documented in areas from fintech to quantum computing.
Comment by oumua_don17 5 days ago
Says who, you? Wrong. I use Common Lisp at work.
edit: and not just use as in a side toy, design and writing software in CL is my primary responsibility. FWIW, at a FAANG!
Comment by stackghost 5 days ago
Do you work on ITA? Only FAANG I'm aware of using Lisp is Google.
Comment by oumua_don17 5 days ago
Comment by stackghost 5 days ago
Comment by rootnod3 3 days ago
Comment by michaelmrose 5 days ago
Have you like looked at anything in the Clojure ecosystem because this description makes no sense of any kind. Clojure has macros but less powerful than common lisp and Clojure code in the ecosystem tends to be small and understandable.
Comment by Zak 5 days ago
Comment by kscarlet 5 days ago
The "Lisp Curse" is a ridiculous and tired myth that can only be invented by people who have looked at the language for 5 seconds and went straight to finding an excuse to not learn it.
Comment by Zak 5 days ago
But seriously, I think Clojure has a particularly strong tradition of writing clean, readable code.
Comment by iLemming 5 days ago
Use-cases for code that writes code across a host boundary are rare, yet enormously useful and really difficult to achieve without homoiconic nature of the language.
Hyperfiddle/Electric is a nice project that effectively utilizes the idea.
Comment by p_l 5 days ago
Comment by epolanski 5 days ago
Comment by iLemming 5 days ago
Have you ever seen GitHub language stats? Elisp there in the list a few points behind Lua, Elixir, OCaml and Haskell. The amount of Emacs Lisp on GitHub alone should be at least surprising. There's so much Elisp in the wild - the amount of it probably exceeds Clojure, CL and Racket combined. And let me remind you that it isn't a "general-purpose PL" - it's meant for one and only purpose.
Look at the number of package for AI-coding in Emacs¹ - 35 and counting. Mind that emacs has no central curated marketplace with the same discoverability as VSCode's. Packages live across MELPA, GNU/NonGNU ELPA, and countless personal repos, so a hand-counted 35 from a Reddit roundup is almost certainly an undercount of what exists in the wild.
And that's just one of the observable axes of Lisp. Anyone can join Clojurians Slack and scroll through #news-and-articles, just out of curiosity. It is hard to find a problem space today or a runtime where Lisp has not proliferated. Why? Because Lisp is enormously practical. Just because you convinced yourself it isn't, doesn't change a thing about reality.
---
¹ https://www.reddit.com/r/emacs/comments/1uwm3c0/the_state_of...
Comment by epolanski 5 days ago
My point stands.
Comment by iLemming 5 days ago
Your point can stand, sit or jump around in a circle - makes no difference. Any ignorant fool can make a hollow point about things they don't fully understand and congratulate themselves in the process.
You can make similar "observation" about Linux on Desktop, mechanical keyboards, 3D printing and Raspberry Pi/Arduino tinkering and call them "hobby business".
You're essentially conflating "niche" with "unserious". By that logic Linux was a hobby OS and Git a hobby VCS - both literally started as one guy's side project, both now run the industry. Lisp is niche, not unserious: Clojure runs Nubank, Walmart, Cisco and Apple; Common Lisp ran ITA/Google Flights; and most of the features in whatever your favorite language is were Lisp ideas first.
Comment by rjsw 6 days ago
Comment by derrida 2 days ago
Message Sent from Common Lisp
Comment by mark_l_watson 5 days ago
I don’t agree with you but your comment is very well thought out and doesn’t deserve downvotes.
Comment by iLemming 5 days ago
Lisp dialects turned out to be extremely practical - I just can't even imagine doing the things I do today with Emacs in anything else. Achieving similar effects with any other tool would be enormously more time consuming and far more frustrating. Sure, it really took me years to get to that point, but even though I had already knew all sorts of other tools which I could've picked to achieve similar results - from bash/zsh, awk, sed and tcl to python, golang and a bunch of others, the way Lisp-driven Emacs lets me get there is beyond meaningful comparison. Nothing even comes close and I'm enormously proficient in vim, I spent almost a decade in IntelliJ and used tons of different IDEs before - from Delphi and Eclipse to Visual Studio and VSCode.
Clojure, at which I scoffed at some point, turned out to be an immensely pragmatic tool for dealing with data. Any kind of data - big or small. It effectively replaced jq in my toolbelt, all my API interrogations happen in a Clojure REPL today. Fetching data from psql, mysql, sqlite and sorting, slicing, dicing, transforming that data interactively, directly from my editor is an absolute delight.
Building simple web-scraping scripts with nbb driving Playwright is so much faster than using any other stack, even javascript is no longer "an obvious choice" for me, even though I spent decades learning its quirks.
Babashka has replaced any kind of bash-scripting - anything longer than three lines almost has no reason to be made in bash/zsh/fish anymore.
Anything Lua-driven is now done with Fennel. It's not even funny how a dozen-lines boilerplate of Lua can be compacted into a simple, reasonable three-liner Fennel macro. Or the way how I can connect to the Hammerspoon REPL and poke through visual elements of any app on Mac, interactively and with ease - is complete and total bananas.
Era of LLMs incidentally highlighted another enormous advantage of Lisp - when you give an LLM a true Lisp REPL, agents stop guessing and start empirically analyzing current state of things and produces working solution faster, costing far less tokens. And you get to watch it solve things interactively, e.g. I often let AI poke through our UI (via Playwright-driven Clojurescript REPL), while monitoring situation in k8s - through nrepl port, connected to Clojure REPL. It literally interactively walks the DOM, finds the selectors, clicks buttons, etc. All without restarts, complex state management and all.
"Well", you may say: "these examples exactly what I'd consider a 'hobby language' territory".
Alas, I have worked in teams where Clojure was used for shipping commercial software and I have seen truly complex projects - Cisco's infosec infrastructure and FindingCircle's complex Kafka topologies. I have met and talked to people working at Netflix, Apple, Amazon, Nubank, CircleCI, etc., and I can confidently say: your self-conviction is absolutely backwards.
Lisp-world has never been more cornucopian than today; we see the proliferation of different tools and new Lisp dialects popping almost every passing week - Jank, Jolt, ClojureDart, Squint, Coalton, Clojerl, LFE, uLisp, etc. It is frankly inconceivable to find today any platform where you can't really run a Lisp. My advice to any programmer who's aspired to become a hacker - do learn Lisp. It comes in handy. For real.
Comment by leonmeng 5 days ago
Comment by WalterGR 6 days ago
Comment by jorams 5 days ago
CCL isn't very actively maintained and currently doesn't have an ARM64 port, but otherwise continues to work fine. I believe one reason people use it is that it compiles a bit faster than SBCL, at least in part by doing less optimization.
Comment by pfdietz 5 days ago
Comment by GalaxyNova 5 days ago
Comment by p_l 5 days ago
Comment by NeutralForest 6 days ago
Comment by GalaxyNova 6 days ago
Comment by ivxvm 5 days ago
Comment by ux266478 5 days ago
I wish more desktop applications could hit even a 100ms startup time. These days it feels like 5 seconds or more is the norm.
Comment by klibertp 5 days ago
Web services need either cooperative concurrency or M:N concurrency due to the "10k problem". CL only supports threads (OS-level) and promises; everything else is incomplete (eg., delimited continuations, which could be used to build coroutines) due to missing parts in the spec and some language features (eg., conditions and restarts). Of course it can be done, but it won't be as pleasant as using Elixir and Phoenix.
A game engine would work, most likely, unless it was for an MMO (again, concurrency handling). I personally never worked on one, but I see examples of game engines in CL, and they tend to look nice.
In general, single-user desktop (CLI, TUI, GUI) apps are still a good fit for CL, even today (you need to put some work into packaging the app for different platforms, but it tends to be easier to set up than it is for C or C++; harder than Go or Rust, though). It's unfortunately not as good a fit for the backend, at least not until an implementation with good support for concurrency appears. It's nice as an extension language in a larger app (through ECL), and as far as dynamic languages go, it's quite performant, so some computation-heavy apps can benefit from using CL (with SBCL). On the other hand, the ecosystem is quite small, which means dependency-heavy apps are better written in something like Python or a mixture of CL and another language (there are two-way bindings to many dynamic languages and there's mature FFI support for compiled languages).
To be perfectly honest: as much as I love Lisp, I personally gave up on trying to use it, for now. For hobby stuff, I found an even more niche solution that is more enjoyable to work with in the GUI/TUI/CLI space. It also doesn't support OS-level threads, but instead provides coroutines for concurrency - I find this side of the trade-off to be useful/beneficial more often, at least in the code I tend to write. I don't believe the time spent learning CL and other Lisps was wasted, but it's become harder and harder to justify going for CL over the past 15 years, and I finally reached a point where I stopped trying. YMMV though, and I would still give CL a chance if it's your first language of this kind (i.e., providing image-based interactive development, a dynamic language with a native compiler with inline assembly support, a multimethod-based object system, and homoiconicity/macros, etc.).
Comment by fuzztester 5 days ago
What is that solution?
Comment by klibertp 5 days ago
I don't remember the exact numbers, but when I checked, the GT+Pharo ecosystem (available packages, number of people in Discord, tools with support for the language, etc.) was ~2x smaller than Common Lisp's. It also comes with its own problems, some of which CL doesn't suffer from (the GIL, performance, startup time). But it's very fun to use and play with, which is the most important quality for me in my hobby/side-projects. :)
Comment by fuzztester 3 days ago
Comment by wduquette 4 days ago
Comment by Jach 4 days ago
I'm confused by the GP's assertion that backends aren't a good fit because of the threading model, to me they're one of the best fits. The 10k problem isn't a concern for most software, and in any case there are ways around it. (I don't know what Google Flights does but even at their scale they haven't moved off SBCL. And Hacker News itself runs fine on SBCL, though there probably aren't 10k concurrent connections.) In the ecosystem, there's the https://github.com/fukamachi/woo webserver which binds to libev to handle similar scale as Go was advertising about 10 years ago. And besides some work going on recently on the SBCL dev mailing list to add native fibers/green-threads, there's been non-native versions of them before, and basically any concurrency model you can think of has been built on top of SBCL by someone. (STM, actors, async (one even built on libuv), channels, promises/futures...)
Comment by ivxvm 4 days ago
> The startup is of course nowhere near that of a small C or Zig binary, but for larger tools it will be tolerable.
It's worse than Java and Python and JavaScript I think? The languages that were always disliked for CLI/TUI/GUI apps because of unnecessary bloat they bring due to their runtimes. It's not impossible to use this ofc, it's just inferior to alternatives with minimal runtime, so such an app might be considered a temporary solution to use before someone rewrites it in Rust or Zig or C and people have no reason to use slower and more resource hoggy version. Many people even choose to avoid Emacs for slow startup times, now imagine if something like grep was starting a virtual Lisp Machine underneath. This is why I think it's more promising to consider it for apps and niches that people never tried to keep minimal, such as games and webservices, even if it doesn't have native coroutines or whatever. Using non-standard solution is almost a non-issue and invisible to end user while startup times and RAM usage are very visible.
Also, ofc there's definitely unique things that become available with something that's just as programmable in runtime as it is in development stage. So some kind of very polymorphic app that benefits from growing more native code in response to user actions, could benefit from it. I don't have many ideas of what app really needs this though.
In the past, like two decades ago, I've seen a person using SBCL with some kind of unofficial continuations or green threads for backend webdev in commercial setting. I also remember someone using it in context of virtualization systems, but don't remember their exact usecase.
Also quick search shows there are some modern takes on coroutines as well: https://atgreen.github.io/repl-yell/posts/sbcl-fibers/
Comment by NeutralForest 6 days ago
Comment by srparish 5 days ago
Comment by p_l 5 days ago
Not mine, but interesting.
Comment by GeorgeTirebiter 5 days ago
I wanted something more 'algorithmic' - and more accurate.
So me and Claude build an sbcl-based Film Recommendation system. Type in a new film name, it goes to open film database OMDB, grabs the scores, and then, using films I have already rated and with a built-in tiny Neural Net, gives me a personal recommendation. It uses the OMDB data and an algo that weights those with my personal values (in half a dozen areas: overall, acting, cinematography, etc), along with a 'comments' box to note for friends / others.
The code is very well-done CL, heavily commented. The film & ratings database is stored as S-exprs, naturally, all in one file. I don't use a database as I only have a few hundred films, but maybe later I will. And that's the point -- this is a living chunk of code that I from time to time bolt in new features, or try new things (e.g. the UI is localhost:8080)
I fretted about having a 'real' project to really dig into CL for a long time, and finally, found a meaty-enough project that ends up being really useful & quite a learning (continuing learning) experience. I start it up inside emacs/sly like this:
(ql:quickload '(:hunchentoot :dexador :yason))
(load "s:/filmrec.lisp")
(filmrec:start)
I have to set the omdb key: (setf filmrec:*omdb-api-key* "fxxxx70")
Then, every so often, I retrain the NN: (filmrec:retrain)
Good Luck, you'll find a project. And with an LLM buddy, you'll succeed.Comment by nesarkvechnep 5 days ago
Comment by mfru 5 days ago
Comment by nesarkvechnep 5 days ago
Comment by sroerick 6 days ago
Comment by hermitShell 5 days ago
Comment by wild_egg 6 days ago
Comment by DonHopkins 5 days ago
Comment by WalterGR 5 days ago
I’d recommend using close parens for your code sample. Those are portable between the two.
Comment by vindarel 5 days ago
Comment by tmtvl 5 days ago
(funcall (funcall (funcall (funcall ; ...
...though I don't think that functions which return functions which return functions which return functions ad infinitum are a great idea. Simply taking a value and returning a value means you can use a pipelining operator: (~> some-data
function-1
function-2
(function-3 _ some-other-data)
; ...
function-n)Comment by dapperdrake 5 days ago
Comment by unfirehose 5 days ago
Comment by arikrahman 6 days ago