Also worth noting that some of the workflows that were available in languages like CL or Smalltalk back in the 80s are superior to what most languages offer today.
In what ways? I don’t have any experience with those so I’m curious.
Common Lisp and Smalltalk provided live development environment where you could run any code as you write it in the context of your application. Even the whole Lisp OS was modifiable at runtime, you could just open code for any running application or even the OS itself, make changes on the fly, and see them reflected. A fun run through Symbolics Lisp Machine here https://www.youtube.com/watch?v=o4-YnLpLgtk
Here are some highlights.
The system was fully introspective and self-documenting. The entire OS and development environment was written in Lisp, allowing deep runtime inspection and modification. Every function, variable, or object could be inspected, traced, or redefined at runtime without restarting. Modern IDEs provide some introspection (e.g., via debuggers or REPLs), but not at the same pervasive level.
You had dynamic code editing & debugging. Functions could be redefined while running, even in the middle of execution (e.g., fixing a bug in a running server). You had the ability to attach “before,” “after,” or “around” hooks to any function dynamically.
The condition system in CL provided advanced error handling with restarts allowed interactive recovery from errors (far beyond modern exception handling).
Dynamic Window System UI elements were live Lisp objects that could be inspected and modified interactively. Objects could be inspected and edited in structured ways (e.g., modifying a list or hash table directly in the inspector). Modern IDEs lack this level of direct interactivity with live objects.
You had persistent image-based development where the entire system state (including running programs, open files, and debug sessions) could be saved to an image and resumed later. This is similar to Smalltalk images, but unlike modern IDEs where state is usually lost on restart.
You had knowledge-level documentation with Document Examiner (DOCX) which was hypertext-like documentation system where every function, variable, or concept was richly cross-linked. The system could also generate documentation from source code and comments dynamically. Modern tools such as Doxygen are less integrated and interactive.
CL had ephemeral GC that provided real-time garbage collection with minimal pauses. Weak references and finalizers are more sophisticated than most modern GC implementations. Modern languages (e.g., Java, Go, C#) have good GC but lack the fine-grained control of Lisp Machines.
Transparent Remote Procedure Calls (RPC) allowed Objects to seamlessly interact across machines as if they were local. Meanwhile NFS-like but Lisp-native file system allowed files to be accessed and edited remotely with versioning.
Finally, compilers like Zeta-C) could compile Lisp to efficient machine code with deep optimizations.
Unfortunately, the lisp machine didn’t gain traction because the start-up times were so long and I believe this is due to it doing lots of internal checks which was awesome but unfortunately things like the Sun SPARCstation won because it was crazy fast although buggy
I had access to a Symbolics machine back in the day, but I was too young & dumb to understand or appreciate what I had my hands on. Wasted opportunity 😔
I love Lisp, that’s why I like doing industry work in JS, because it’s very lisp like.
However if you gave an average industry programmer Lisp today they’d fuck up so much worse than the garbage enterprise grade language code that exists today. I switch jobs probably every 4 years and on average I teach 3 people a year what a closure is.
Lisp has a lot of great solutions for a lot of real problems, but these people quite literally fix one bug and create 3. I had a 10+ YOE Tech Lead tell me the other day that they kinda just ignore the error output of the TS compiler and it made me want to tear my eyes out.
I guess I’ve been lucky, I’ve been working with Clojure professionally for over a decade now, and every team I’ve worked on was very competent. Could be that there’s a selection bias at play with teams that use a language like Clojure though since it tends to appeal to experienced developers.
I’ve found it hard to find jobs with Clojure/Haskell/Rust. I typically look for interesting projects and industries that don’t make me feel icky even though they end up doing so because everything is fucking enterprise sales. My career has kinda been Bar Rescue for idiot companies who have blundered into an extremely hard problem and need someone to actually figure it out before the software stack implodes on itself.
Clojure jobs are definitely around, I got involved in the community early and wrote a few libraries that ended up getting some use. I also joined local Clojure meetup, and ended up making some connections with companies using it. I’ve also worked in a team lead position in a few places where I got to pick the tech stack and introduced Clojure. I didn’t find it was that hard to hire for it at all. While most people didn’t know Clojure up front, most people who applied were curious about programming in general and wanted to try new things.
Yeah I just haven’t really held out for one. At one point I have this fear that on average regardless of language I’m gonna see the same shit everywhere, so I typically pick by project interest and scale. If I wasn’t such a little cockroach about having a stable income I could have had some fun opportunities holding out for some Haskel, Erlang or Clojure jobs, but I didn’t.
I was once interviewed by a startup that was a crypto payments processor targeting the central American market and the interviewer let it slip that I shouldn’t worry about runway because it comes from a fairly large crypto fund that the founder owns that’s payed into by USAID/NED style soft intelligence services.
I immediately got the ick and I was like this is not something I want to involve myself in for stability’s sake but god damn I could have had a peek behind the curtain.
I found Clojure jobs were generally pretty interesting. One of my jobs was working at a hospital, and we were building software for patient care. So we got to go to the clinics within the hospital observe the workflow, builds tools for the users, and then see how it improved patient care day to day. It was an incredibly rewarding experience.
For me, the language matters a lot, and Clojure is the only language that I’ve used for many years that I’m still excited to write code in. Once you’ve worked with a workflow that’s fully interactive, it’s really hard to go back. I really enjoy having instant feedback on what the code is doing and being able to interrogate the app any time I’m not sure what’s happening. This leads to an iterative development process where you always have confidence that the code is doing exactly what you expect because you’re always exercising it, and experimentation become much easier. You can just try something see the result, and then adjust as you go.
I found Clojure jobs were generally pretty interesting. One of my jobs was working at a hospital, and we were building software for patient care. So we got to go to the clinics within the hospital observe the workflow, builds tools for the users, and then see how it improved patient care day to day. It was an incredibly rewarding experience.
Sounds like you got double lucky. Hasn’t really been my experience in the medical space. I find larger institutions like that very unreceptive to how software is made and often the environments are constricting and lead to bad outcomes that “nobody can really figure out why”. It often starts at timesheets and gets worse from there.
For me, the language matters a lot, and Clojure is the only language that I’ve used for many years that I’m still excited to write code in. Once you’ve worked with a workflow that’s fully interactive, it’s really hard to go back. I really enjoy having instant feedback on what the code is doing and being able to interrogate the app any time I’m not sure what’s happening. This leads to an iterative development process where you always have confidence that the code is doing exactly what you expect because you’re always exercising it, and experimentation become much easier. You can just try something see the result, and then adjust as you go.
Yeah you can definitely have this kind of stuff in other languages. It’s gonna be similar workflows that are generally BDD & REPL based but you have to have someone who knows what they’re doing do architecture, tooling selection, setting conventions, and helping to put it all together into a maintainable system. Very often that’s skipped at most companies, and I’ve found it to be a lucrative skill in my career.
In what ways? I don’t have any experience with those so I’m curious.
Common Lisp and Smalltalk provided live development environment where you could run any code as you write it in the context of your application. Even the whole Lisp OS was modifiable at runtime, you could just open code for any running application or even the OS itself, make changes on the fly, and see them reflected. A fun run through Symbolics Lisp Machine here https://www.youtube.com/watch?v=o4-YnLpLgtk
Here are some highlights.
The system was fully introspective and self-documenting. The entire OS and development environment was written in Lisp, allowing deep runtime inspection and modification. Every function, variable, or object could be inspected, traced, or redefined at runtime without restarting. Modern IDEs provide some introspection (e.g., via debuggers or REPLs), but not at the same pervasive level.
You had dynamic code editing & debugging. Functions could be redefined while running, even in the middle of execution (e.g., fixing a bug in a running server). You had the ability to attach “before,” “after,” or “around” hooks to any function dynamically.
The condition system in CL provided advanced error handling with restarts allowed interactive recovery from errors (far beyond modern exception handling).
Dynamic Window System UI elements were live Lisp objects that could be inspected and modified interactively. Objects could be inspected and edited in structured ways (e.g., modifying a list or hash table directly in the inspector). Modern IDEs lack this level of direct interactivity with live objects.
You had persistent image-based development where the entire system state (including running programs, open files, and debug sessions) could be saved to an image and resumed later. This is similar to Smalltalk images, but unlike modern IDEs where state is usually lost on restart.
You had knowledge-level documentation with Document Examiner (DOCX) which was hypertext-like documentation system where every function, variable, or concept was richly cross-linked. The system could also generate documentation from source code and comments dynamically. Modern tools such as Doxygen are less integrated and interactive.
CL had ephemeral GC that provided real-time garbage collection with minimal pauses. Weak references and finalizers are more sophisticated than most modern GC implementations. Modern languages (e.g., Java, Go, C#) have good GC but lack the fine-grained control of Lisp Machines.
Transparent Remote Procedure Calls (RPC) allowed Objects to seamlessly interact across machines as if they were local. Meanwhile NFS-like but Lisp-native file system allowed files to be accessed and edited remotely with versioning.
Finally, compilers like Zeta-C) could compile Lisp to efficient machine code with deep optimizations.
Unfortunately, the lisp machine didn’t gain traction because the start-up times were so long and I believe this is due to it doing lots of internal checks which was awesome but unfortunately things like the Sun SPARCstation won because it was crazy fast although buggy
I had access to a Symbolics machine back in the day, but I was too young & dumb to understand or appreciate what I had my hands on. Wasted opportunity 😔
It’s like an artifact from an ancient and more advanced civilization. :)
I love Lisp, that’s why I like doing industry work in JS, because it’s very lisp like.
However if you gave an average industry programmer Lisp today they’d fuck up so much worse than the garbage enterprise grade language code that exists today. I switch jobs probably every 4 years and on average I teach 3 people a year what a closure is.
Lisp has a lot of great solutions for a lot of real problems, but these people quite literally fix one bug and create 3. I had a 10+ YOE Tech Lead tell me the other day that they kinda just ignore the error output of the TS compiler and it made me want to tear my eyes out.
I guess I’ve been lucky, I’ve been working with Clojure professionally for over a decade now, and every team I’ve worked on was very competent. Could be that there’s a selection bias at play with teams that use a language like Clojure though since it tends to appeal to experienced developers.
I’ve found it hard to find jobs with Clojure/Haskell/Rust. I typically look for interesting projects and industries that don’t make me feel icky even though they end up doing so because everything is fucking enterprise sales. My career has kinda been Bar Rescue for idiot companies who have blundered into an extremely hard problem and need someone to actually figure it out before the software stack implodes on itself.
Clojure jobs are definitely around, I got involved in the community early and wrote a few libraries that ended up getting some use. I also joined local Clojure meetup, and ended up making some connections with companies using it. I’ve also worked in a team lead position in a few places where I got to pick the tech stack and introduced Clojure. I didn’t find it was that hard to hire for it at all. While most people didn’t know Clojure up front, most people who applied were curious about programming in general and wanted to try new things.
Yeah I just haven’t really held out for one. At one point I have this fear that on average regardless of language I’m gonna see the same shit everywhere, so I typically pick by project interest and scale. If I wasn’t such a little cockroach about having a stable income I could have had some fun opportunities holding out for some Haskel, Erlang or Clojure jobs, but I didn’t.
I was once interviewed by a startup that was a crypto payments processor targeting the central American market and the interviewer let it slip that I shouldn’t worry about runway because it comes from a fairly large crypto fund that the founder owns that’s payed into by USAID/NED style soft intelligence services.
I immediately got the ick and I was like this is not something I want to involve myself in for stability’s sake but god damn I could have had a peek behind the curtain.
I found Clojure jobs were generally pretty interesting. One of my jobs was working at a hospital, and we were building software for patient care. So we got to go to the clinics within the hospital observe the workflow, builds tools for the users, and then see how it improved patient care day to day. It was an incredibly rewarding experience.
For me, the language matters a lot, and Clojure is the only language that I’ve used for many years that I’m still excited to write code in. Once you’ve worked with a workflow that’s fully interactive, it’s really hard to go back. I really enjoy having instant feedback on what the code is doing and being able to interrogate the app any time I’m not sure what’s happening. This leads to an iterative development process where you always have confidence that the code is doing exactly what you expect because you’re always exercising it, and experimentation become much easier. You can just try something see the result, and then adjust as you go.
Sounds like you got double lucky. Hasn’t really been my experience in the medical space. I find larger institutions like that very unreceptive to how software is made and often the environments are constricting and lead to bad outcomes that “nobody can really figure out why”. It often starts at timesheets and gets worse from there.
Yeah you can definitely have this kind of stuff in other languages. It’s gonna be similar workflows that are generally BDD & REPL based but you have to have someone who knows what they’re doing do architecture, tooling selection, setting conventions, and helping to put it all together into a maintainable system. Very often that’s skipped at most companies, and I’ve found it to be a lucrative skill in my career.
No wonder there are some older developers who defend Lisp so passionately. Sounds like a dream to work with once you got the hang of it.
Interesting! Thank you!