I implemented a proprietary, commercial application in Common Lisp called Tankan that runs on Microsoft Windows as a native executable.
It's a program for training yourself to memorize Japanese kanji characters.
The program runs as a background HTTP server. The execution of this server and navigating to its pages, is coordinated by a tiny system notification area (a.k.a "Tray") icon application which I developed using Visual C++.
The tiny tray icon application starts, monitors and stops the Lisp-based server, and communicates with it using Win32 pipes tied to its standard input and output. Through a pipe, the Lisp server informs the tray icon application of the precise URL with the right port number, and that tray icon application can launch the browser via the Shell API to browse that URL. The user just double-clicks on the icon to bring up the UI.
The Lisp program maintains in its memory a fairly complex session state which contains the user's input history and various relationships among various objects. Lisp's circular object notation (enabled by the *print-circle*
variable) and how it works across custom CLOS print-object
methods is of a tremendous help in implementing the persistence: users can save the state to disk and resume where they left off. Everything is saved, including the state of the UI. There is a lot of shared substructure in the object graph, as well as cycles. Plus, lots of static cruft that doesn't have to be persisted, like contents of dictionary entry objects. With ANSI Common Lisp custom print object methods, you can create condensed printed representations for objects which are nevertheless machine readable, and have their circular references preserved.
Almost no JavaScript is used in the web UI. Even the controls for hiding and showing parts of the UI are done by form submission and re-rendering the HTML. Every detail of the UI state is hence in the server and persisted when the user saves. The re-generation of the HTML is very fast. It's done by a giant Lisp backquote expression which feeds a HTML generating macro. The code compiled by Clozure Common Lisp (CCL) makes this happen so fast that you're hardly aware that when you click on a [+] button on the UI to open something, you're submitting a request to a server which regenerates the entire darn page, and not simply running some local JavaScript to change the visibility of a local document element.
The program was originally developed with CLISP. Thanks to ANSI CL being a standard language, with implementations that conform well and not too many sneaky pitfalls in the language ("undefined" or "implementation-defined" behavior) it quite easily ported to CCL.
CLISP hasn't been abandoned; it is still used for powering the licensing back end, using much of the same common code base.
I developed an original licensing system for the program, using elliptic curve crypto provided by the IronClad library, which is used by the licensing server to sign licenses to certify them. (I seem to remember I might have used OpenSSL's command line program to generate the EC parameters for the server key.)
Licenses are represented as Lisp objects. It's a tribute to Lisp portability that a Windows program compiled by Clozure Common Lisp can generate an S-expression-based license, a CLISP program running on a Debian server can fill in the missing digital signature field in that object, and send it back to the Windows program which can validate the signature.
On the server, in addition to the CGI-based licensing service, I simple command line API for managing licenses. You can list licenses, find specific ones, and edit their attributes: such as for instance editing the expiry date of a temporary license to grant a user an exception. The licensing back-end also generates e-mails. I didn't use any library for the CGI handling on the server side: just hand-rolled Lisp code for dealing with the Apache environment variables and command line arguments. (Though library code is used for dealing with URL encoding and HTML generation.)
No database is used for storage; the licenses are catenated into a file called licenses.lisp
and that's that.