Still remember all the meetings that generally always included someone complaining "what the $#&^%! were they thinking and why didn't their Management stop it before it got this far."
The programmers were based in Canada and only wrote in Haskell. The CTO of White Ops had apparently hired them previously as contractors at a prior company without issue.
In hindsight, it turned out the purpose of Haskell was specifically because it was very difficult to hire anyone to replace them, and they wrote in a strange manner that left even experienced Haskell developers confused, especially without their customized IDE extensions.
After a couple rounds of funding, the Marxists went on strike and demanded huge amounts of equity from White Ops to continue working. Ultimately the company wound up rewriting everything in a more popular language than acquiesce to their demands. I heard the Marxist group also had tons of drama because the leader made everyone live onsite in shared housing.
There was a furry who worked as a web developer for a small firm. He had built their back-end runtime in MUCK scripting language. (A MUCK is like a MUD, but without the statistics and stuff, so it's much less a role-playing game than it is simply role-playing.) Eventually he was fired, probably because he spent more time pretending to be a highly sexualized female fox on MUCKs than doing his job, but the back end to all their web apps was written in MUCK code -- and few non-furries even knew what a MUCK was let alone how to program one. So the befuddled engineers who remained had to figure out how to modify the code without their vulpine-in-his-own-mind former colleague.
They uh, also didn't notice the backdoor he put into the web server that allowed him to spy on their activities, even though he was gone from the company...
I think i know these guys! Their names are Karl, Vlad, and Fred, right? Last I heard they founded the International Common-Lisp Party
In parts of the community we do not so much think of the tools as part of the identity of the engineers. We’re looking for general intelligence/capability and train specific technologies on the job.
- A desktop application for a bank in which not only the gui’s content but the look and structure was generated or changed on the fly mimicking the status of a database.
- An interpreter in which most of its classes and methods were automatically generated. The Java rewrite took pretty nasty code generation hacks, visitor pattern madness and way more LOC.
- Some program with a huge cache (glorified hash table) that was not catching simple strings or objects as keys but actual code as s-expressions. I always thought that was pretty cool.
Most if not all of my Lisp (and Perl) projects have been eventually rewritten in Java, and not exactly due to technical issues. I mostly put up with Go these days which is great most of the time but of course makes me yearn for a more powerful language or wished I never dabbled with those.
As for "just using AST", it is tedious to me, that's why I don't bother with it in other languages, and judging by the code that I've seen, it is for the average programmer as well.
And a college of mine took the application and easily made a version for another customer in less than a day. Changing most of the 52 pages to match the other customer. The look, the page layout, some of the logic etc. He never looked at the source code.
And mind you I have written my own Lisp dialects just for fun, and have written code in Common Lisp and Scheme. I like the simplicity of Lisp the same way that I like the simplicity of Forth. But I just prefer other languages. Not having types is tedious to me.
Some time ago I wrote a sort of DevOps tool in Python (because I know better than to start new projects in Lisp in most settings). This tool had preconfigured tasks defined as point-free style functions that were easily composable. Non programmers were able to define their own pipelines either submitting a YAML file or dragging & dropping these components in a web UI. This was very powerful, but anything remotely complex (if you didn't want to end up reinventing Forth) required dropping down to Python to define these.
JSON and YAML are very good at conveying structure, but fall sort for anything else. It would be like doing any sort of complex programming with Ansible via just using roles and playbooks. It's possible, but no one sane does.
Now the question is if this really matters. Judging at the shape of the industry, the clear answer is no.
And how close we came... and yet so far =(
We were working on a DoD project to feed relatively large amounts of logistics data in and out of a bunch of simulation models written for different contracts for different branches of the military. The inputs/outputs were all relatively large/complex files, with different formats and different units, and some values had to be repopulated in the output-files before being fed into the next simulation, and the input/output formats of many of these things were often being changed. The whole environment we lived in was more dynamic than you'd ever really want, yet I remember it feeling really easy to describe what I wanted to do in code; more than any language I've worked in since, stuff tended to Just Work the first time.
Some of the cooler things one could do in LISP that were difficult/impossible to do in other languages:
- Running in an interpreter from your editor (emacs, of course) allowed you to write editor code that could read/rearrange/fix your application code in the running image making the tweak/reload/test cycle trivially fast, even in really complicated systems (Python comes close, but not quite there).
- If it made sense, you could write lisp code in your editor that helped you write/manage the LISP code for your project, create patches automatically, etc.
- Writing a refactoring script in your editor was often better than trying to do it by hand. Decades later, I have yet to see an IDE or a refactoring tool that works as cleanly.
- The LISP macro system made it "easy"[1] to avoid writing boilerplate code. It was often more practical to write a boilerplate-generator, rather than thousands (on 10k) lines of boilerplate.
- Since classes/objects could be redefined on the fly almost arbitrarily, it was possible to redefine object data members as static class-members, and subclasses with overridden member-data, depending on the contents of your dataset AFTER loading it (at the time, I think this had a RAM savings of ~30%?)
- CLOS is the cleanest, most flexible object-oriented language I've ever seen, with a sensible multiple-inheritance system and all sorts of tools (like "before", "after", and "around" methods) you could use if you had a good reason to.
- The metaobject stuff in LISP is deep, dark magic; but sometimes you actually need deep, dark magic. Not often, but sometimes.
In the end, I think LISP is still a great choice for really complicated, dynamic problems (the kind that take years and millions of lines of code to solve). If you find yourself working on the sort of problem that makes you feel a need to build a domain-specific language to solve it, that's the sort of problem that LISP is REALLY good for. While I'm not a manufacturing engineer, LISP feels a bit like the programming language equivalent of a CNC mill/lathe that you can use to build out a factory that might require building bigger/better CNC mill/lathes.
[1] "easy" in that the non-boilerplate code was easy to read and understand its intent, but often it was much harder to debug, as macros often called macros which called macros. Debugging code that writes code is a whole different level of brain-hurt, but sometimes it's still better than the alternative.