
Ask HN: Production Lisp in 2020? - dhab
I have gone through initial chapters of &quot;Practical Common Lisp&quot;[1] and &quot;Loving Common Lisp&quot; [2], and have a bit of intuition on lisp, and the power of macros. Haven&#x27;t done any projects yet, but was also researching on real issues faced by adopting lisp, and ran into articles about abandoning lisp [3], adopting lisp [4],[5]. Could not find anything more recent; but what they mention in these articles - even the ones that are adopting lisp talk about issues like:<p>* poor ecosystem of libraries - few gems, most other half-baked<p>* poor community coordination<p>* Dependency management limitations with quicklisp<p>And some specific red flags like:<p>* poor support for json[6]
* poor support for async<p>* have to restart the server every 20 days because of some memory leak [3]<p>* hack to tune GC [5]<p>If you are using lisp in production for non-trivial cases, 
do these issues still exist? is there a way you can quantify effort is resolving them, and if yes, what is it?
and, finally, if you had to re-do your project, would you chose lisp or something else?<p>[1]: <a href="http:&#x2F;&#x2F;www.gigamonkeys.com&#x2F;book&#x2F;" rel="nofollow">http:&#x2F;&#x2F;www.gigamonkeys.com&#x2F;book&#x2F;</a><p>[2]: <a href="https:&#x2F;&#x2F;leanpub.com&#x2F;lovinglisp&#x2F;read#quicklisp" rel="nofollow">https:&#x2F;&#x2F;leanpub.com&#x2F;lovinglisp&#x2F;read#quicklisp</a><p>[3]: <a href="https:&#x2F;&#x2F;lisp-journey.gitlab.io&#x2F;blog&#x2F;why-turtl-switched-from-lisp-to-js&#x2F;" rel="nofollow">https:&#x2F;&#x2F;lisp-journey.gitlab.io&#x2F;blog&#x2F;why-turtl-switched-from-...</a><p>[4]: <a href="https:&#x2F;&#x2F;lisp-journey.gitlab.io&#x2F;blog&#x2F;why-deftask-chose-common-lisp&#x2F;" rel="nofollow">https:&#x2F;&#x2F;lisp-journey.gitlab.io&#x2F;blog&#x2F;why-deftask-chose-common...</a><p>[5]: <a href="https:&#x2F;&#x2F;www.grammarly.com&#x2F;blog&#x2F;engineering&#x2F;running-lisp-in-production&#x2F;" rel="nofollow">https:&#x2F;&#x2F;www.grammarly.com&#x2F;blog&#x2F;engineering&#x2F;running-lisp-in-p...</a><p>[6]: <a href="https:&#x2F;&#x2F;stevelosh.com&#x2F;blog&#x2F;2018&#x2F;08&#x2F;a-road-to-common-lisp&#x2F;#s48-st-json" rel="nofollow">https:&#x2F;&#x2F;stevelosh.com&#x2F;blog&#x2F;2018&#x2F;08&#x2F;a-road-to-common-lisp&#x2F;#s4...</a>
======
mikelevins
Yep, I've used Common Lisp in production. Several times. I'm in the middle of
writing a new app with Lispworks right now.

Common Lisp is generally the first thing I think of for any new work I
undertake. There are exceptions, but usually my first choice is Common Lisp.
It has been for a little over thirty years.

I've often worked in other languages--usually because someone wants to pay me
to do so. I usually pick Common Lisp, though, when the choice of tools is up
to me, unless some specific requirement dictates otherwise.

The objections you list might be an issue to some extent, but not much of one.
Certainly not enough to discourage me from using Common Lisp in a pretty wide
variety of projects. I've used it for native desktop apps, for web apps, for
system programming, for text editors, for interpreters and compilers. When I
worked on an experimental OS for Apple, the compiler and runtime system I used
were built in Common Lisp.

I'll use something else when someone pays me enough to do it. I'll use
something else because it's clearly the best fit for some specific set of
requirements. I'll use it when there isn't a suitable Common Lisp
implementation for what I want to do. I'll even use something else just
because I want to get to know it better.

I've taken various detours along the way into learning and using various other
languages. I like several of them quite a bit. I just don't like them as much
as Common Lisp.

The pleasure I take in my work is a significant factor in my productivity.
Choosing tools that offer me less joy is a cost I prefer not to bear without
good reason. That cost often exceeds the advantage I might realize from using
some other language. Not always; but often.

There was once a language I liked even better than Common Lisp. Apple
initially called it 'Ralph'. It evolved into Dylan, which, in its present
form, I don't like as much as Common Lisp. If I or someone else invested the
considerable time and effort needed to write a modern version of Ralph, then I
might choose it over Common Lisp.

For now, though, I'll stick with the old favorite. It continues to deliver the
goods.

~~~
Ingon
Care to elaborate on how Ralph was different from cl/dylan? Or at least point
me to some resources to read more about it? I don’t seem to find anything
specific on the internet. Thanks

~~~
mikelevins
When Ralph was new, it was essentially a hybrid of Common Lisp and Scheme. It
was very much a Lisp--not just technically, or in matters of surface syntax,
but down in its bones.

The surface language was basically Scheme, with some special forms removed and
others added or renamed. The type system was basically a simplified Common
Lisp Object System; all values were instances of CLOS classes.

The compiler, runtime, and development environment were built on Macintosh
Common Lisp. Ralph inherited MCL's design and aesthetics.

Like Common Lisp, it was designed for writing software by interacting with it
and modifying it as it ran. That's the essential point.

The project I worked on, bauhaus, was running basically all the time we worked
on it. We worked on it by interrogating and hot-modifying the running system,
in the time-honored tradition of old-fashioned Lisp and Smalltalk systems.

Later Dylan was not like that. It evolved into just another batch-compiled
application language. You edit some files. You batch-compile them. You run the
resulting artifact for testing. Rinse and repeat.

That's how OpenDylan is today. That's why it lost me.

It's also what's wrong with some newer Lisps, from my point of view. They
aren't designed for building programs by modifying them from inside while they
run. They don't know how to handle existing data in the presence of redefined
types. They don't provide interactive debuggers and inspectors that can be
used to rummage through the memory of the running program, edit it while it
runs, and conitnue execution.

Common Lisp provides these features, and has done for decades. Ralph provided
them. Smalltalk does, too. If all the Common Lisp implementations in the world
suddenly evaporated, I could get along fine with Smalltalk, after a brief
period of adjustment. It's probably purely an accident of history that I'm a
Lisper rather than a Smalltalker, anyway.

But Dylan doesn't have those essential features anymore, and nothing that
lacks them is likely to win me over--not OpenDylan, not Julia, not Clojure or
Haskell, or F#. I like all of those languages, but not nearly as much as I
like my livecoding.

~~~
metroholografix
Strongly agree with that viewpoint and the central paradigm it describes, it's
what's made my 15 year investment into Lisp more than worth it. It's also what
makes every newly emergent language not measure up to Lisp: None of them focus
on interactive development. In fact, the only one I'm aware of that (partly)
did that was Slava Pestov's Factor but ultimately, it was more a proof-of-
concept than anything that could be considered practical and is now
languishing.

Later, Slava went to Apple to work on Swift, which turned out to be another
mediocrity, lacking any sort of originality / vision and having a firm
expiration date. There used to be a time when programming languages focused
primarily on end-user empowerment and paradigm-centered computing was the norm
(e.g. Seymour Papert's groundbreaking research in constructionism and
incremental learning / development). There is precious little left of that
now.

~~~
7thaccount
Hmmmm...PharoSmalltalk, 8th (same rough family as Factor), Mathematica, Dyalog
APL, J, K...lots of tools that are fully interactive in their bones.

~~~
metroholografix
I wouldn't characterize Pharo/Mathematica/Dyalog APL as newly emergent,
they've been around for a long time. I can't say anything about J and K since
I've never used them but my superficial impression is that they are focused on
a specific niche, not as general purpose as most Lisps. They've also been
around for a long time.

8th I have actually looked at and it's both _not_ particularly interactive
(certainly nowhere near as interactive as Factor) and has a very strange
license [1] to boot which makes it a total nop for me. It has been criticized
before [2].

[1] [https://8th-dev.com/com-license.html](https://8th-dev.com/com-
license.html)

[2]
[https://news.ycombinator.com/item?id=15672361](https://news.ycombinator.com/item?id=15672361)

~~~
7thaccount
New is pretty relative, but yeah they've definitely been around for a while.
I'd say the array languages (APL/J/K) can be used in far more areas than most
people think, but I understand your point and am on the fence myself.

What is wrong with 8th's license? It is basically a Forth, so extremely
interactive...mostly just messing with a stack...not sure about
metaprogramming. I think a production license costs you $200 as a one time fee
and you have to pay no royalties or anything for apps (better than many tools
out there). Upgrading to a later version comes at a discount too. Most of the
runtime is proprietary/closed-source if that is what you were saying (def
understandable if you had a problem with that). Also, being a 1-developer
project, progress is rapid, but I'd be worried about what happens if the
maintainer wins the lottery.

~~~
metroholografix
The second link I included goes over some of the issues but regarding
interactivity, just look at the videos its author produced to show it off.
He's writing code in either VIM or the shell. That's a long way from Factor's
image-based interactivity and a long long way from Smalltalk and Lisp Machine-
paradigm Lisps.

Any language with a REPL can be described as "interactive" but that's not what
having a strong focus on interactive development means. As Mikel Evins wrote,
it's really about the entirety of a language being geared around interactive
development.

~~~
mikelevins
It's "mikel evins".

I can't blame you for parsing it the other way; it's a more likely spelling.
You can blame my eccentric father for the odd spelling of my first name, but
he inherited the surname fair and square.

It's pronounced exactly the same way as "Michael Evans."

~~~
metroholografix
I'm always grateful when the map-territory distinction comes along and slaps
me in the face. It's a signal that I should re-calibrate.

It's been a while, thanks for making it happen!

------
jasode
I think Reddit's decision to move from Common Lisp to Python is interesting
and their reasoning (ecosystem) is still valid 15 years later.

The historical timeline is especially interesting because Reddit's cofounders
Steve Huffman & Aaron Swartz were alumni of Paul Graham's first YC batch and
PG is the author of the well-known Lisp essay "Beating the Averages":

\- 2001-04 Paul Graham : Lisp essay _" Beating the Averages"_ [1]

\- 2005-07-26 Paul Graham :
[https://groups.google.com/forum/#!topic/comp.lang.lisp/vJmLV...](https://groups.google.com/forum/#!topic/comp.lang.lisp/vJmLVd9lJyk)

\- 2005-12-05 Steve Huffman : [https://redditblog.com/2005/12/05/on-
lisp/](https://redditblog.com/2005/12/05/on-lisp/)

\- 2005-12-06 Aaron Schwartz :
[http://www.aaronsw.com/weblog/rewritingreddit](http://www.aaronsw.com/weblog/rewritingreddit)

The takeaway from the Reddit case study is this: Yes Lisp macros and language
malleability gives it superpowers that other languages don't have (the "Blub
Paradox") -- but other languages also have _other superpowers_
(ecosystem/libraries) that can cancel out the power of Lisp macros.

You have to analyze your personal project to predict if the ecosystem matters
more than Lisp's elegant syntax powers.

[1] [http://www.paulgraham.com/avg.html](http://www.paulgraham.com/avg.html)

~~~
justinmeiners
I would like to consider Python a common lisp alternative. But it's one or two
orders of magnitude slower and is not really standardized. I think there is a
lot more that's attractive than just macros.

~~~
elcomet
> and is not really standardized

What do you mean by this ?

~~~
justinmeiners
My understanding is the Python standard is essentially whatever C Python
chooses to do. They do write the changes to a specification separately, but
essentially its one moving implementation, with alternatives that have
compatibility limitations.

~~~
schmudde
Indeed. I'm curious what Python 4 will do to Python 3.

------
reikonomusha
Rigetti Computing is a company that builds quantum computers.

We have used Common Lisp in production at Rigetti Computing for 4 years both
in cloud deployment as well as for a downloadable SDK. Common Lisp is used to
build what is currently the best free optimizing compiler for quantum
computing [1, 2] as well as one of the most flexible quantum computer
simulators [3]. They’re both open source, so you can actually see for yourself
how we version, deploy as binaries, and deploy in Docker containers.

> If you are using lisp in production for non-trivial cases, do these issues
> still exist?

Before getting into the specifics, any large, non-trivial product that
customers use will need tweaking. Especially languages that have runtimes,
including languages like C. This is usually a result of leaky abstractions
that just have to be dealt with in The Real World (TM).

> * poor ecosystem of libraries - few gems, most other half-baked

You have libraries for most things you need. Some are lacking, like in
scientific computing. But all your usual stuff to glue things together is
there and works.

Some people confuse “half-baked” with “no commits for 5 years”. Lisp libraries
are older than many in vogue languages, and Lisp doesn’t change, so “5 years
no commits” shouldn’t be worrisome.

At Rigetti, the biggest weight we had to pull that we wouldn’t have needed to
do in, say, Python, is bind to a bunch of FORTRAN code, specifically LAPACK.
That was a pain because you need to do FFI with complex double floats.

* poor community coordination

The community all agrees on one thing: Lisp is standardized.

Lisp lacks a sort of “centralized community” like Go or Clojure. I like to
think that Common Lisp is more “democratic”. We have a “constitution” (the
Common Lisp standard) that we all agree on and we all make our own
contributions atop that.

With that said, #lisp on Freenode is attentive. SBCL, for example, responds to
bug reports almost immediately. Several library ecosystems are kept up to
date, etc.

> * Dependency management limitations with quicklisp

With Quicklisp, I personally realized a lot of other dependency management
solutions are overblown and don’t actually solve problems. Maybe QL gets away
with it because the ecosystem is smaller than others.

Xach, the creator of QL, does a lot of community diligence for free to ensure
things work.

For production code, I’ve had 0 issues.

> * poor support for json

We use YASON [4] and it works fine.

> * poor support for async

This is true now but wasn’t true years ago. Lisp implementers have not been
interested in implementing a runtime supporting async programming. Little in
the Common Lisp language itself prohibits it. Before the world of threads and
SMP, Lisp implementers _did_ implement async runtimes.

Why aren’t Lisp implementers interested in async? I’m not sure. Maybe they see
it as a passing fad?

> * have to restart the server every 20 days because of some memory leak

Memory leaks can happen but they’re usually the programmer’s fault for not
understanding symbol interning, weak pointers, or finalizers. Writing long-
running applications does require know-how.

> * hack to tune GC

I don’t consider it hacking. In SBCL we tune the GC to our application. This
seems reasonable; different programs have different allocation patterns. But
you wouldn’t need to do this out of the box.

> is there a way you can quantify effort is resolving them, and if yes, what
> is it?

Big applications that are customer products require care and feeding. The
benefits of writing in Lisp in the first place largely outweigh some of the
extra work needed to productionize it.

I will say that writing production Common Lisp code is greatly benefited by
having at least one experienced Lisper on the team. If a team would, for some
reason, write an application in Lisp but not really have a good understanding
of the language, then productionizing and hardening will be difficult.

> and, finally, if you had to re-do your project, would you chose lisp or
> something else?

Common Lisp allows something that never existed before (a completely
automatic, optimizing quantum compiler) to exist. If Lisp weren’t there, that
wouldn’t exist.

My parting advice is this: The biggest difficulty in writing an application is
to actually write it. It takes a lot of hard work to get requirements, listen
to feedback, articulate a direction, etc. In Common Lisp, SBCL or LispWorks or
whatever else, dumping an executable is so easy and you can have a deployable
“production app” in 5 minutes. So the good news is that you won’t be held up
trying to figure out how to dockerize your Python app.

I definitely agree that before embarking, doing an objective and relevant
comparative analysis would be good (we did this at Rigetti), but ultimately
you just need to sit down and write.

Almost every programming problem is solvable these days with enough glue and
elbow grease. I wouldn’t be too worried.

[1] [https://arxiv.org/abs/2003.13961](https://arxiv.org/abs/2003.13961)

[2] [https://github.com/rigetti/quilc](https://github.com/rigetti/quilc)

[3] [https://github.com/rigetti/qvm](https://github.com/rigetti/qvm)

[4] [https://github.com/phmarek/yason](https://github.com/phmarek/yason)

~~~
7thaccount
How complete are your LAPACK bindings?

~~~
reikonomusha
They’re complete in the sense that all standard functions are exposed.
However, there’s only a modest “high-level” interface.

The library:
[https://github.com/rigetti/magicl](https://github.com/rigetti/magicl)

Comparison with NumPy:
[https://github.com/rigetti/magicl/blob/master/doc/high-
level...](https://github.com/rigetti/magicl/blob/master/doc/high-level.md)

------
jmercouris
I'm using Lisp in production, our browser and all of our infrastructure is in
Lisp [https://github.com/atlas-engineer/next](https://github.com/atlas-
engineer/next).

TO address some of your points;

poor ecosystem of libraries: many great libraries, some incomplete. you must
not be afraid to look at the source code to understand and edit

poor community coordination: true, there are few large scale community lisp
projects. be the change you want to see

dependency limitations with quicklisp: like what? quicklisp works great. if
you are talking about loading several versions of the same library at the same
time in a single image, this is being researched and developed

poor support for json: no, there is good support

have to restart the server every 20 days: not familiar, I have had lisp
servers running for years now

hack to tune GC: no

if I had to redo my project would I choose Lisp? I would choose lisp, yes.
there is no more powerful language than this, and believe me, I have tried
many

~~~
dhab
The post [1] (though old) - hints at no good libs for json (mentions a
workaround for one he picks)

    
    
      > For me, the most important quality 
      I need in a JSON library is an unambiguous, 
      one-to-one mapping of types. For example: some libraries 
      will deserialize JSON arrays as Lisp lists, 
      and JSON true/false as t/nil. But this means [] and false
      both deserialize to nil, so you can't reliably round trip anything! 
    

Although this post is from 2018, wondering if it has improved since then.

[1] [https://stevelosh.com/blog/2018/08/a-road-to-common-
lisp/#s4...](https://stevelosh.com/blog/2018/08/a-road-to-common-lisp/#s48-st-
json)

~~~
junke
This just works:

    
    
        USER> (yason:parse "{\"null\" : null, \"false\" : false, \"empty\": []}"
                           :object-as :plist
                           :json-arrays-as-vectors t
                           :json-booleans-as-symbols t
                           :json-nulls-as-keyword t)
        ("null" :NULL "false" YASON:FALSE "empty" #())
    

Null is mapped to the :null keyword, false to a symbol named false in the
yason package, and the empty vector to an empty lisp vector (in Lisp #(1 2 3)
denotes a vector, whereas (1 2 3) is a linked-list). All threes can be
distguinshed from the others.

All those options defaults to special (dynamically scoped) variables, so you
don't have to pass them everytime.

Encoding prints to the standard output (you can redirect it to an http stream,
if you want), so you don't see double-quotes being escaped, but the string is
equivalent (modulo spaces):

    
    
        USER> (yason:encode-plist *)
        {"null":null,"false":false,"empty":[]}
    

The defaults in Yason just returns list for vectors, and map both null and
false to nil, but this is not a problem: if you expect your field "items" to
be a vector, then nil will denote the empty list, if you expect another field
"enable-debug" to be a boolean, nil be good enough too. But in cases where you
need to handle them differently, the library can help you distinguish among
all kinds of value.

See [https://phmarek.github.io/yason/](https://phmarek.github.io/yason/)

------
synthc
Clojure has a good ecosystem and you can fall back to Java's ecosystem if
needed. It has excellent support for json, and acceptable async support (I use
manifold + aleph, but there are other options). It runs on the JVM which has
world class GC.

~~~
ssivark
I want to understand the complementary picture. Assuming Clojure as a good
default, what would be some specific kinds of tasks/problems for which one
might wish to avoid Clojure? And what alternatives would you recommend, for
those cases? (be it another lisp, or otherwise)

~~~
piranha
I wouldn't use Clojure if fast startup time is important for you. So it's okay
for servers, but not okay for (in general case) for command line tools. With
GraalVM this is changed a bit, but then compilation of non-trivial projects
with GraalVM is also non-trivial.

If you need a low memory consumption then Clojure is also not a great choice.

We've built an ecommerce site on Clojure though and it's been great. :)

~~~
shivekkhurana
SCI or Small Clojure Interpreter is a subset of Clojure meant for quick
startup.

Babashka is a library on top of SCI and is particularly suited to building
command line tools. It doesn't need the JVM, starts up in milliseconds, has
access to a large part of clojure.core (including core.async) and can be
downloaded as a 13mb binary.

[https://github.com/borkdude/babashka](https://github.com/borkdude/babashka)

------
souenzzo
I delived a service in 2019 that was written 100% written in clojure.
ReactNative app + SPA Web app + Server all sharing the same code.

The developer experience was great. I get subsecond hot-reload on all
plataforms (app emulator/app on-device/web/server).

The same UI components was shared between ReactNative and ReactDOM. All App
issues are reproducible in Web, then I fix in web and I'm sure that App is
working.

Even SSR was possible, with some tweaks.

~~~
virtualwhys
Got a public repo to share that would show how you pulled this off?

Barring that, as a sibling comment asks, what specific framework and/or
libraries did you use to achieve the holy grail of sharing-all-the-things?
(thought ReactNative required implementing separate UI for iOS and Android).

Sub second hot reload sounds amazing, btw.

~~~
Jonovono
Not sure this will help: ClojureScript RN app: (I think has desktop and all
that as well) [https://github.com/status-im/status-
react](https://github.com/status-im/status-react)

------
sulami
CircleCI is mostly Clojure, and some Go.

The only problems we are seeing is the significant startup time cost (hence
the Go bits, where it matters).

Memory usage also isn't always great, but that's more a JVM problem, as it's
not releasing reclaimed memory as quickly as you'd like it to. Fine on
servers, annoying on a 16GB laptop.

The Common Lisp problems you outlined don't really apply to Clojure, it's a
modern lanaguage and has been stable and versatile for us.

~~~
capableweb
Is the new frontend also written in ClojureScript? Seems you've closed sourced
the frontend (old source is here
[https://github.com/circleci/frontend](https://github.com/circleci/frontend))
but you used to use CLJS, but maybe new one is written in something else?

~~~
sulami
I'm on the backend, but all I've seen of the new frontend is TypeScript. There
has been a decision to switch languages for reasons that someone else can
probably explain better than I could, a lot of us lurk here.

------
thom
Perhaps you didn't mention it for a reason, but I am sure I won't be the only
one to bring up Clojure in this thread, and others will argue for and against
more eloquently. Obviously it lacks much of what makes people love Common
Lisp, but it's more Lisp than not Lisp, and specifically addresses all of your
points via the JVM and its ecosystem.

------
mark_l_watson
First, thanks for linking my Living Common Lisp book. Common Lisp is my
preferred language, but only for projects where I need/want an environment
that support rapid experimentation of new ideas. If I know how to implement
something and I want to deploy at scale, then I might not choose Common Lisp.

I am a happy LispWorks customer but I also use SBCL (efficient code, easy to
package standalone apps) and Clozure Common Lisp (fast compiler for
development).

------
dan-robertson
I’ve not used lisp in production. But I sometimes wish I did. In particular,
whenever there’s an issue with a production process (think a batch job rather
than some kind of online processing), I wish I could attach a debugger,
inspect some variables, and invoke a restart. I don’t know how of any language
that makes it more convenient to do that sort of issue-resolution.

I don’t really care about libraries. I think generally it’s not very hard to
write an ffi binding to a C library and most of the time you don’t need a
library anyway. Most of the time you can just write your own library from
scratch as you probably only need a few functions.

But maybe this is more a statement of the sort of programs I work on and if
you worked on different systems you would want to use lots of external
libraries that you don’t control.

I think the biggest issue with CL is how tightly attached it is to an outdated
standard. It makes it harder to have things like good Unix support if your
interface is through pathnames and streams.

Other thing which may be annoying about CL are the lack of a good way to
consistently go from source code to a binary and that compiler optimisations
can be unpredictable

~~~
justinmeiners
> consistently go from source code to a binary

Can you talk more about this?

~~~
dan-robertson
Let’s say I have a big repo full of lisp. I want a program that uses some
subset of this lisp. Similarly to if I had a big repo full of C programs and
libraries and I wanted to build one of those programs (statically linking all
the libraries it used). In CL, it is annoying and tricky to go from those
files to an executable I can deploy. Typically you’d write some script to (use
ASDF to) compile/load your various files and then dump the image specifying a
binary. It’s a bit messy and not very portable.

~~~
aidenn0
I will never understand how people have such a rosy view of C development. Is
it just that today people think there is only GNU make, and only GCC or clang?

Autotools used m4 because it was the most portable Unix tool, not because it's
a good language to write your build scripts in...

~~~
justinmeiners
I have had problems with C, but building my code was never one of them. You
are right that I have only used GCC, Clang, and Visual Studio.

I thought they use M4 because they were doing sophisticated preprocessing?

~~~
aidenn0
I misremembered; M4sh (which uses m4 to generate portable bourne-ish shell
scripts) is what was the lowest-common-denominator for autoconf.

------
TurboHaskal
Can't speak for SBCL (I use it exclusively for development and haven't
deployed anything non trivial and user facing with it) but I have used Clozure
CL (CCL) successfully to develop back end services without horror stories
regarding the GC. If you end up needing huge heap sizes, in theory with ABCL
you get access to state of the art GC algorithm implementations and (IMHO) a
much nicer, less dogmatic language than Clojure.

I recently switched to LispWorks after struggling a bit with CCL's Cocoa
bridge and I wish I had done that sooner. A much younger, idealistic me would
scream at the thought of it but sometimes you just need to throw some money at
a problem. CAPI is really a killer feature.

------
varjag
We use CL for production (embedded/distributed system). CCL and Lispworks on
low end ARM32.

We do use JSON but mainly for the product's Websocket API towards higher level
SCADA system. As we have control over both ends there isn't much trouble
really.

The project has soft realtime component also implemented with Lisp, and at
least Lispworks exposes a substantial degree of control over GC. We however
didn't need to tune anything thus far.

The system has perhaps a dozen direct dependencies to the libraries, luckily
few of them posed any challenges in use.

~~~
spauldo
If you don't mind my asking, what company is this? I'm a Lisp hobbyist working
for a SCADA integrator, and while I'm not in the job market right now I might
be in a few years.

~~~
varjag
It's norphonic.com, based in Norway. The product is not on the webpage yet
though.

~~~
spauldo
Ah, pity. I'd love to visit Norway sometime (I've heard great things), but my
family won't move across the ocean.

Anyway, thanks for the reply.

------
foobar-xk
Apple has been using Clojure in production for years, and is hiring:
[https://jobs.apple.com/en-us/details/200000986/apple-
media-p...](https://jobs.apple.com/en-us/details/200000986/apple-media-
products-software-engineer-core-services)

Excerpt from the description: "These are the people who power the App Store,
Apple TV, Apple Music, Apple Podcasts, and Apple Books. And they do it on a
massive scale, meeting Apple’s high expectations with high performance to
deliver a huge variety of entertainment in over 35 languages to more than 150
countries."

------
dutchblacksmith
I use lispworks, the CAPI works well on allmost all platforms. They know what
they are doing. Books: common lisp recipes, PAIP, ANSI COMMON LISP. The few
libraries you need are very good.And you need Quicklisp. I stopped using C,
C++, pascal, fortran, javascript. Altough they all are just fine. You still
have to learn the craft of programming. Just go for it.

~~~
nicklaf
I'm going to second the recommendation of Common Lisp Recipes. The others too,
of course (especially PAIP).

------
Grue3
Not really production because the traffic is low, but I run
[http://ichi.moe](http://ichi.moe) on SBCL (Hunchentoot web server) and I
never had to restart it because of memory leak or a crash. I usually hot-swap
the updates and the same server process stays up for months. It also heavily
uses JSON and XML and the libraries for them (jsown and cxml) are perfectly
adequate.

------
lukego
I'm starting a new project in Lisp in 2020. That's rolling my own CAD tools
for learning hardware development.

Lisp makes sense because it's a comfortable environment for interacting with
my data. I'll be running the Lisp code "offline" so I'm not worried about
runtime aspects like GC pauses and most of my I/O will be generating data for
external tools (e.g. KiCad) in their own esoteric formats.

Coming back to Lisp it's nice to see that all my favourite software is still
available and working fine, and there seem to be more active open source Lisp
developers than ever. (Far fewer than Javascript, for example, but that's not
my yardstick.)

------
vindarel
I am running a web app in production, with live reloads, no issues so far.

> * poor ecosystem of libraries - few gems, most other half-baked

I actually had the _choice_ for my libraries: DB interface, email sender, HTML
template, data structure helpers… these ones with good documentation.

I have observed and explored the ecosystem for the last 3 years and I still
find hidden gems. There are way more libraries than we can see at a quick
glance.

We do a selection on [https://github.com/CodyReichert/awesome-
cl](https://github.com/CodyReichert/awesome-cl)

> * poor community coordination

It looks like the oldest ones don't coordinate much and the youngers do (and
push the established players, such as the CL foundation).

> * poor support for async

Maybe not for a full async runtime (cf Turtl feedback), but there is a good
choice for all sort of async stuff (bordeaux-threads, lparallel, lfarm,
channel, SBCL built-ins etc)

------
deckeraa
I use Clojure and ClojureScript in production. The developer experience is a
real pleasure: there is good library support, libraries are typically easy to
use, and you can always interop with the underlying JVM/js if the need arises.

Clojure also has the core.async library. This can be used along with Reagent
to build React-based apps; core.async allows you to do what Redux does but in
fewer lines of code.

[https://github.com/deckeraa/OpenStainer](https://github.com/deckeraa/OpenStainer)
is an example of building apps this way.

------
juskrey
Clojure is a production Lisp in 2020

~~~
_ix
Our health benefits startup has been using Clojure in production for some
time. Efforts are ongoing to migrate the last bits from other JVM languages to
Clojure, but ClojureScript is already ubiquitous.

------
ashtonkem
I used to work in Common Lisp (SBCL).

The ecosystem problem meant something different to me than most. Sure, when
new tech came out (Kafka to pick a random example) there wouldn’t be an open
source library ready for me. But I had stable infrastructure so I didn’t
really care much about that.

The ecosystem problem for me meant that if something went wrong I was on my
own. It’s a pretty unfortunate feeling to search for a bug and find _nothing_
on Stack Overflow.

~~~
kazinator
> _It’s a pretty unfortunate feeling to search for a bug and find nothing on
> Stack Overflow._

Par for the course in embedded. So isn't going to tell you why the kernel
driver for the ABC123 chip is locking up on the XYZ15 eval board from Such-
and-Such vendor.

You debug it yourself, whipping out JTAG debuggers and oscilloscopes, if
necessary.

Because I work in embedded, I don't understand the whole ecosystem fuss.

I mean, joy of joys, you have the darned source to almost everything nowadays.
That makes everything so easy, that all else is a footnote.

~~~
snazz
I'm coming at this from the opposite side. Currently, it feels like most of my
programming skills are really just Googling skills and remembering what a
particular error message means. The market emphasizes this kind of programming
by combining existing libraries and hoping things work, so it's really hard
for me to break away from doing that and start to learn the way that stuff
works internally. I think that this was the reason that they stopped teaching
SICP in Scheme [0].

I can read source code (I do some security research for fun) and use a
debugger, but I still feel like I'm programming by poking. What would you
recommend to younger programmers to get out of this rut?

0: _In this talk at the NYC Lisp meetup, Gerry Sussman was asked why MIT
stopped teaching the legendary 6.001 course, which was based on Sussman and
Abelson’s classic text The Structure and Interpretation of Computer Programs
(SICP). Sussman’s answer was that: (1) he and Hal Abelson got tired of
teaching it (having done it since the 1980s). So in 1997, they walked into the
department head’s office and said: “We quit. Figure out what to do.” And more
importantly, (2) that they felt that the SICP curriculum no longer prepared
engineers for what engineering is like today. Sussman said that in the 80s and
90s, engineers built complex systems by combining simple and well-understood
parts. The goal of SICP was to provide the abstraction language for reasoning
about such systems.

Today, this is no longer the case. Sussman pointed out that engineers now
routinely write code for complicated hardware that they don’t fully understand
(and often can’t understand because of trade secrecy.) The same is true at the
software level, since programming environments consist of gigantic libraries
with enormous functionality. According to Sussman, his students spend most of
their time reading manuals for these libraries to figure out how to stitch
them together to get a job done. He said that programming today is “More like
science. You grab this piece of library and you poke at it. You write programs
that poke it and see what it does. And you say, ‘Can I tweak it to do the
thing I want?'”. The “analysis-by-synthesis” view of SICP — where you build a
larger system out of smaller, simple parts — became irrelevant. Nowadays, we
do programming by poking._

~~~
neutronicus
Edit-[optionally compile]-Run-[optionally step in Debugger] is addictive
because the feedback loop is so tight, and it always feels like work. The way
to break the addiction is to start working in a domain where there's
significant friction to that process.

Work on a heavy-ass C++ GUI application that takes forever to load, with a
big-ass code base that takes forever to compile, and you'll be thinking deeply
about code in no time, because you can't program that sucker by poking when
poking takes 40 minutes.

------
tsss
I really hope that Lisp will get a comeback in the space that is now occupied
by XML and YAML. It's always the same story: Narrow minded engineers chose
YAML (formerly XML) as the trendy simple configuration language and it works
fine for a while. 3 years later they inevitably hit the ceiling with YAML and
either start badly implementing new language features on top of YAML (see
Gitlab CI's `when`, `only`, `except`, etc. syntax) that are never flexible
enough or write hugely complicated templating tools (see Kustomize and Helm
for K8S) for things that would amount to a simple if-expression in Lisp. This
is the use case where Lisp can really shine. Configuration is almost always
untyped and doesn't start out with a library ecosystem. Most of the time you
just need a way to write a simple nestable DSL that is human readable. There's
probably no language that makes this simpler than Lisp: Any college freshman
could write their own interpreter. But it is also extremely flexible if it
turns out that you need more power than YAML offers.

~~~
fsloth
I don't think XML has been 'trendy' for ages :)

XML is totally fine for storing structured dumb data. Don't program in XML.

I would not be so bullish about implementing your own interpreter - as the
best obvious choice every time.

Numbers especially are hard to get correct unless you know what you are doing.

~~~
justinmeiners
I don't think this user is advocating using home grown interpreters. Rather
it's easy to understand how they work completely.

The point is complex configurations tend to grow into a poor programming
language. They would be far better as a lisp DSL.

------
lisper
> poor ecosystem of libraries - few gems, most other half-baked

Definitely no longer an issue for Common Lisp. Quicklisp is da bomb.

> Dependency management limitations with quicklisp

Never had any issues. It Just Works for me.

> have to restart the server every 20 days because of some memory leak [3]

You can get memory leaks in any language. You're much less likely to have a
leak in a GCd language than a non-GCd language. But seriously, if you can't
easily restart your server whenever it's needed, you have bigger problems.

> hack to tune GC [5]

I've run CL in production for many different applications. I've never had to
tune a GC.

------
akssri
ITA software's account of using CL may also be of interest,

[http://www.paulgraham.com/carl.html](http://www.paulgraham.com/carl.html)

------
cbuskilla
try hy -
[https://docs.hylang.org/en/stable/](https://docs.hylang.org/en/stable/)

Most of my production code is python, but I also wanted to create a dsl so I
used hy. You get to enjoy both worlds

~~~
sgt
I tried to get hy but I just got confused.

------
dhab
Thank you for your responses. I was interested in learning about these
concerns for Common Lisp only, and not the other dialects including scheme,
clojure, racket ...

------
gjvc
This may not squarely answer your question, but when I was investigating this
for a production project, the following tools seemed to be both essential and
well-supported.

SBCL, SLIME, SLY, ASDF, quicklisp, and ultralisp

Other tools and solutions are available, but familiarity with this seemed to
be what was required for comfortable use.

------
jonwalch
My very early stage startup, whiplash.gg (tune in today at 2pm PT to see us in
action) uses Clojure on the backend.

Ladder Insurance is a full stack Clojure shop and Watchful has a bunch of
Clojure in prod too.

------
mapcars
I made a few hobby projects in different Lisps, but in the end for my field
(REST backends) I would chose Erlang and today I also started looking towards
Kotlin. Lisp's macros while being powerful are still creating a lot of trouble
in terms of understanding the system, working with other people and finding
support online. Also I personally didn't meet many developers who have solid
understanding of FP, not even talking about macros - they are simply too
complicated and don't allow human scaling.

~~~
fastball
Why Kotlin and not Elixir + Pheonix for web backend?

~~~
mapcars
I have some experience with Elixir, you can think of it as nicer Erlang.
Kotlin is interesting because it gives you access to Java (Android & Desktop)
world and is closer to functional languages while still being widely usable.

------
jjuliano
The problem with malleability of programming languages, is there is no upper
limitation of how malleable it can be.

I experienced this in both Clojure and Ruby as well. The fact that developers
can spend countless of precious time, cycling through a loop of malleability,
reforming an already functional product in production. It costs precious time
and money, it is expensive. And more importantly, it is non-stop.

Other programming languages like Go are very conservative with feature
changes, and imposes hard limitations by choice, the team/company behind it
thinks the same way, that a cycle of O(n) is destructive.

And nowadays, you can't expect a developer to stay on a company for so long,
so a sureball tooling to hit it hard, and precise, with less time and
tinkering around is much needed than ever.

On the future of programming languages, we will see languages being used not
because it is malleable, but because it is sure, precise and right for the
job.

~~~
unityByFreedom
I tried Go and didn't like its opinionated nature. As a beginner, I disliked,

\- I have to use every variable I declare, otherwise it won't compile (b/c
golang authors decided this produces better code)

\- Official docs confusingly suggest I structure imported files with the root
as github.com/ (b/c golang assumes all code will be open sourced)

\- I can only import one file per folder

\- There is no built in map or reduce function. You're expected to use for
loops everywhere because it is more explicit

Once I discovered the last point I noped out.

~~~
jjuliano
> \- I have to use every variable I declare, otherwise it won't compile (b/c
> golang authors decided this produces better code)

> \- There is no built in map or reduce function. You're expected to use for
> loops everywhere because it is more explicit

Go is an imperative language, where no implicit magic happens on the
background, like auto creation of resources on runtime, every sequence needs
to be manually defined by the programmer. "With imperative code, you’re
telling your program how to do something. And with declarative code, you’re
telling your program what you want to do. - Tyler Mcginnis, React
Fundamentals", depends on the programmer, but I like to be in control.

~~~
unityByFreedom
Yeah I get that. I prefer declarative code. I _really_ enjoy constraint
programming, for example, which is anything but imperative. I had no idea
there were folks who preferred imperative languages until I discovered the Go
community. I always figured people choose imperative languages for lack of
familiarity with more declarative ones.

------
CyberFonic
Your questions are well answered by Paul Graham in
[http://www.paulgraham.com/avg.html](http://www.paulgraham.com/avg.html).

There are many Common Lisp and Scheme environments. Many have excellent JIT
compilers. They all have their relative strengths and weaknesses. So it really
depends on your specific use case as to which environment has the best
support. For me the biggest factor is that Lisp is very productive for use by
a small and competent team. In those situations they tend to create a DSL and
evolve the system. PG's essay describes the reason Lisp fails many projects in
the section "The Blub Paradox".

~~~
d0m
I'm a big PG fan but to be honest, him building viaweb in Lisp is 99% because:
"Robert and I both knew Lisp well, and we couldn't see any reason not to trust
our instincts and go with Lisp.", and not because of a competitive advantage
in the language.

There are so many things that can go wrong in a startup, it's not the time to
pick a stack or database you know nothing about.

------
err4nt
I use CCL and a set of helper functions (that take continuations) so I can
quickly and easily generate bits and pieces of HTML from my shell. I have
previously written the same helpers in JS, Python, and Ruby, but there was a
certain elegance about the LISP version and that's the only version I use and
maintain anymore.

I doubt anybody knows how often I'm using LISP with this little tool because
they only see the resulting HTML, but it's been a big help to me.

------
atgreen
Low traffic, but [https://rl.gl](https://rl.gl) is running production on SBCL
(on kubernetes). Common Lisp is a joy.

------
_bxg1
Clojure direct tackles most of these problems and it seems to me
(subjectively) that it's one of the most widely-used Lisps for actual
production systems.

------
kmclean
Have you considered lisp dialects? I've been working with
Clojure/Clojurescript for a while and it addresses most of those concerns.
It's been a real pleasure to work with.

\- There are lots of high quality libraries, but you also have access to the
entire Java and/or Javascript ecosystem with very easy interop

\- Not too sure what you mean by "community coordination", but I've found the
clojure community to be exceptionally friendly, welcoming, and responsive. The
core team is active and I've even had some questions answered directly by them
in slack!

\- There is some tooling built and maintained by the core team that makes
managing dependencies painless

\- There's a library (transit) that's widely used and well suited for
marshalling data in and out of a clojure app. There's a library that's part of
the core which implements the CSP (communicating sequential processes)
concurrency model, similar to Go. It works in both Clojure and Clojurescript
and is a very sensible way to manage async operations in a system.

\- GC is managed by the JVM (for clojure), which is state of the art

------
thanatropism
I'm using Hy[0] for some API-accessible "glue code" (basically doing high
level stuff with scipy.sparse and friends as building blocks).

[0] hylang.org

------
jetti
We use Clojure + ClojureScript for just about everything where I work. There
are a few older applications that are in Javascript with NodeJS and we have
one that is C# and .NET but the rest of the company pretty much runs on
Clojure. As mentioned elsewhere, Clojure doesn't really have any of the issues
that you mention.

------
pjmlp
Usually using Lisp in production means making use of either LispWorks or
Allegro Common Lisp, and not the FOSS offerings.

~~~
rjsw
You can run applications on the Web now.

~~~
mark_l_watson
Another good solution is to make a command line app with SBCL or CCL and use
Radiance
[https://github.com/Shirakumo/radiance](https://github.com/Shirakumo/radiance)
or something similar that opens a new browser window for your app.

------
jmorrison
I am using CL in pre-production to avail myself of its ability to compile &
load at runtime. I haven't used Lisp in production in a while (dating back to
Zetalisp!), and the decades of perspective lead me to some surprising
conclusions. I have encountered neither ecosystem issues (due to quicklisp)
nor community issues (due to "addition by subtraction" in the Lisp online
community). However, I have encountered plenty of issues due to dependency-
hell issues in the non-CL software I'm using: Python 2 vs 3 vs Python package
incompatibilities; Python 2 vs 3 Ansible/Vagrant container/VM/distro
incompatibilities; node.js vs npm vs inter-node-package version
incompatibilities; etc. CL has been gloriously stable, and given me
substantially less heartburn and fewer headaches.

------
mgdev
Oracle used Lisp [1] in the UIs for their gen-2 cloud product. They eventually
hit a wall hiring the kinds of people Oracle wanted to hire (few of whom
wanted to learn an esoteric language), and made the tragic decision to move
new development over to TypeScript (and port many of the key existing surfaces
for ongoing maintainability). Mixed results on that. Many who were around for
both the old and new code bases report that, while the old one took more
effort to pick up, it was easier to trace data flow and is less prone to
creating weird state bugs.

[1]: [https://www.linkedin.com/pulse/building-cloud-choosing-
lisp-...](https://www.linkedin.com/pulse/building-cloud-choosing-lisp-because-
nobody-told-me-i-mason-browne/)

------
Chris2048
I'm not a lisp programmer, but I have used emacs in the past.

For people w/ lisp dev XP, can I ask this: Is the ".emacs/config bankruptcy"
issue a general problem? Specifically, when you use so many powerful devices,
macros etc; but with little predictable code structure, then further
development that sits well with existing code becomes pretty difficult.

~~~
ssivark
I’m not an experienced lisp programmer, but Emacs bankruptcy is imho
avoidable. You must understand that people often configure their editors by
the worst of Stackoverflow-driven coding... copy-pasting random snippets till
things work, and accumulating cruft over time. Also, Emacs lisp is not
particularly great (compared to other lisps) and Emacs configuration is
typically done through a bunch of exposed global variables. YMMV.

A production codebase hopefully merits very different attitudes :-)

~~~
mijoharas
Also, frameworks seek to claw back some structure from the morasses.

It's kinda fine if every library you use is _slightly_ different if you can
have a unified interface for how to use them (spacemacs layers system for me).

It is annoying figuring out which invocation of variables sets the tab-width
for _this_ new language though...

Also, most libraries in the emacs ecosystem have become more standardised in
their interfaces, so things aren't too different nowadays.

------
zubairq
Yazz Pilot
([https://github.com/zubairq/pilot](https://github.com/zubairq/pilot)) was
originally written in Lisp (Clojure) but we switched to Javascript, simply
because it was easier to get third party developers on board with Javascript
compared to Lisp

------
tomck
> have to restart the server every 20 days because of some memory leak

Hmm this seems like something super specific to their async setup, rather than
'common lisp leaks memory'

------
Random_ernest
I just would like to add to all the great comments, that clojure also has
access to the python ecosystem via libpython clj.

------
frompdx
> * poor ecosystem of libraries - few gems, most other half-baked

Specific to common lisp: I don't find the ecosystem to be poor but I notice
that many are turned off by the look and feel of library landing pages which
do feel dated. In same cases I have felt the libraries lacked documentation,
like Caveman2, but in the end I found there was little to document after
reading some of the source code.

Specific to Clojure: I don't think this criticism applies to Clojure at all
and the popular Clojure libraries usually come with great documentation as
well.

IMO, JavaScript is also littered with mounds of crappy half baked libraries as
well but people still use it for server side stuff even though they have a
choice to use something else.

> * poor community coordination

Which lisp community?

> * Dependency management limitations with quicklisp

What limitations? Also, if you don't like quicklisp or common lisp in general,
I think Clojure really nails dependency management and find it very easy to
use.

> * poor support for json[6]

Specific to CL: I can understand this because there are a number of libraries
and no obvious winner. JSON isn't the only data serialization format though.
Guess it depends on what you need.
[https://www.cliki.net/serialization](https://www.cliki.net/serialization)

> * poor support for async

Specific to Common Lisp: There is cl-libuv: [https://quickref.common-
lisp.net/cl-libuv.html](https://quickref.common-lisp.net/cl-libuv.html) and
wookie.

Specific to Clojure: core.async is great and if you don't like it you are also
free to use node.js as your runtime with clojurescript.

> * have to restart the server every 20 days because of some memory leak [3]

If I had a dollar for every node.js production app that suffered this very
same problem I could probably retire today. I thought it was interesting that
the author of that article says the service was re-written in node.js given
node.js is hardly immune to these sorts of problems. IMO, async is just a pain
to work with and these types of issues are a manifestation of that.

> * hack to tune GC [5]

Users in JVM land also report having to resort to tuning the GC or selecting
the optimal GC for their use case. I don't think this is a reason to shy away
from lisp.

> If you are using lisp in production for non-trivial cases, do these issues
> still exist?

I have not personally encountered these issues in Clojure or CL. That is not
to say they do not exist. But they also exist in plenty of other popular
platforms to varying degrees. See my responses above for examples.

> and, finally, if you had to re-do your project, would you chose lisp or
> something else?

I would still choose lisp, either Clojure or Common Lisp. I generally favor
Clojure to CL.

------
flavio81
I've used Lisp for a production system I delivered one year ago. I used CCL as
an implementation and had a lot of success.

Here i'll cover your points:

> poor ecosystem of libraries - few gems, most other half-baked

I'd say the ecosystem is high-quality. There are relatively few libraries
(around 2000+) compared to other ecosystem, but on the other hand most of them
are either interesting, or unique (wouldn't exist in languages that lack
certain features), or really well-written. Or many of those qualities at the
same time.

In the absolute sense, there are enough libraries, IMO.

If you need something that isn't available, you have at least three options:

1\. Bind to a C library; for this, Common Lisp has many facilities/libs for
this, some of them make this task rather easy.

2\. Same as (1) but Use ECL (Embeddable Common Lisp) for integrating a C
program with a Lisp program as a whole, easily calling C from Lisp and Lisp
from C, etc.

3\. Use the java ecosystem and use the Armed Bear Common Lisp (ABCL)
implementation. This implementation makes calling java libs a piece of cake,
basically you call a java method with just one line of code. Or instance a
class with just one line of code, etc. Really easy.

> poor community coordination

That's a bit meaningless. There are really good quality books and resources, i
think that's what counts.

> Dependency management limitations with quicklisp

Quite the opposite. Quicklisp is awesome, better than PIP or NPM. It "just
works".

> And some specific red flags like:

> poor support for json[6]

The opposite, many libs for JSON. The one I use, I like a lot.

> poor support for async

What does this mean? You can use cl-async, but i wonder what would be the
benefit when in CL you have actual threads and great libraries for concurrency
like lparallel (which introduces parallel processing constructs) or chanL
(which gives you an easy to use channel implementation).

Cl-async allows you to leverage the whole power of libuv (just like Node
does), but why? I'd rather use threads.

> have to restart the server every 20 days because of some memory leak [3]

Never heard about such things.

Perhaps you are confusing the "condition - restarts system" (which is the Lisp
exception handling system) with having to restart something?

> hack to tune GC [5]

The URL you cite says "We had to tune the generation sizes".

Any respecting developer who wants to release a high performance production
quality service NEEDS to tune the GC. Tune the GC is not a "hack", is just
configuration parameters. Ask any Java developer who has had to "tune" the JVM
for best performance.

By the way, everybody raves about Golang but it has a GC system that is
comparatively outdated to the ones in most Lisp implementations (or the JVM).
For example CCL has a very good generational garbage collection.

------
MageSlayer
KDB+ is Lisp under the hood. Please count as highly successful Lisp used in
production.

