Running Lisp in Production – Grammarly Engineering Blog

This page summarizes the projects mentioned and recommended in the original post on news.ycombinator.com

Our great sponsors
  • InfluxDB - Power Real-Time Data Analytics at Scale
  • WorkOS - The modern identity platform for B2B SaaS
  • SaaSHub - Software Alternatives and Reviews
  • coalton

    Coalton is an efficient, statically typed functional programming language that supercharges Common Lisp.

  • I can't speak from a professional level about this, but I'll tell you why I started using Common Lisp for my personal development.

    One day I was thinking it would be awesome if someone created a really powerful language with great facilities for abstraction: first class functions, objects, meta objects, etc. It should use dynamic typing during development with an excellent REPL and a built in debugger available everywhere, but it should have the ability to add type declarations when the code got more settled.

    Even better, this language should include ways of hinting to the compiler how to make a chunk of code faster, and if that wasn't enough, you should be able to replace chunks of code seamlessly with highly optimized C code.

    I thought about how to implement a language like this for a while, but when I looked into it I discovered Common Lisp does most of this already. It's static typing isn't perfect, though now there is https://coalton-lang.github.io/ if that's your thing.

    So that did it for me, but really this is only part of what you can do with Common Lisp. I think it still has a niche in places where the "right thing" isn't know yet.

    For example, I read a Reddit post saying that Common Lisp would be a poor choice now for a web startup, and that Paul Graham overstates Common Lisp's case as the reason for Viaweb's success. This is probably true in 2022, but I think it's instructive to look at why Paul claimed Lisp was so helpful back in 1996. There was no Rails or Django, no React or single page web apps. Viaweb built Scheme style continuations onto Common Lisp to simulate an SPA before AJAX was a thing, and on top of that created a slick HTML templating language based off lisp macros.

    To do that in Perl, or C, would have required something like writing a scheme interpreter, and would have taken much longer for a 2 person team. Is that a 100x advantage? Hard to say.

    Ultimately, I do think it still has advantages, you just have to find the areas where nothing else will really do the job.

  • tls1.3

    A Common Lisp implementation of TLS1.3

  • Largely because of myths surrounding it, for example parenthesis syntax and lack of editor support. With paredit, you get meta level direct AST manipulation support in emacs that is still light years ahead of any programming IDE out there. I think the other fear factor is you have to think a lot more about how to approach the problem when writing Common Lisp and it requires a more complete engineer due to a smaller library ecosystem. Usually there is one and sometimes two libraries for doing X and if not you’re up for making a library yourself.

    I’m attaching an example of how quickly you can write TLS 1.3 by a single person in Common Lisp. At the time I wrote this library most websites still struggled with TLS 1.3 support.

    https://github.com/mateuszb/tls1.3

    If you want an example of expressivity you can take a look at

    https://github.com/mateuszb/tls1.3/blob/master/elliptic-curv...

    For EC crypto with a full NIST vector test.

  • InfluxDB

    Power Real-Time Data Analytics at Scale. Get real-time insights from all types of time series data with InfluxDB. Ingest, query, and analyze billions of data points in real-time with unbounded cardinality.

    InfluxDB logo
  • grpc

    gRPC implementation for Common Lisp (by qitab)

  • For building compilers for quantum computers.

    The biggest hurdle has been difficulties with deployment. Open-source Lisp implementations mostly[1] only let you build an executable, and not things like a C ABI-compatible shared library.

    Even if your OK with building an executable, there are limited options in terms of "enterprise integration". Google only very recently released support for gRPC [2], for example, and it's not a first-class citizen in Google's gRPC offering. Most hobbyist Lisp hackers don't exactly care to build a bunch of open source stuff for enterprise use.

    [1] There is a Lisp implementation called "ECL" that compiles Lisp to C, but it's lacking in many other dimensions.

    [2] https://github.com/qitab/grpc

  • vim-sexp-mappings-for-regular-people

    vim-sexp mappings for regular people

  • I think the paredit stuff is a bit overblown but apart from managing parens for you, another simple example is editing single expressions. e.g. in Java you might have a line: "int a = blah.bar(something, thing, whatever);" If you realize you need to actually pass "whatever" first, not last, unless you know an IDE shortcut that can make the edit for you, you're going to have to type stuff. I would probably just move my cursor to the start, type "whatever, ", move my cursor to the comma after "thing" and highlight to the end then delete. If "whatever" was a longer variable, or even more interestingly an entire sub-function call like "whatever(x, y, z)", I might instead highlight it all, cut, backspace the comma, move cursor to the start, paste, type a comma. Oh no, I might miss a comma or somehow mess up a paren/semicolon or typo a name?! Whatever, it's rare for me, and for most mistakes I'd get a red squiggly alerting me to it immediately. I like typing, and prefer most 'helpful' plugins get out of my way for most things, so such a process isn't that annoying to me.

    But I do at least see there's a nicer process if you have something like paredit: you just move you cursor to the "whatever" (even if it's instead "whatever(a,b,c)") and a command will move it to the left/right/etc. and fix up anything that needs fixing up. In Lisp though the base syntax is so simple and uniform that there's not usually much needing "fixing up" -- there's no pesky commas to deal with for instance, and having the opening paren come in front of the function name instead of after simplifies a lot of things. The worst is adding/removing/moving a form that's at the end of a let binding, or perhaps sometimes adding something to the end of a function that previously ended with ))).

    I like to use vim (which does have paredit though I have it disabled) and just having the ability to jump between open/close parens by pressing "%" and to cut jumps as a whole, or the insides, without having to move my cursor character by character, is good enough for me. I still use some paredit-like commands in some instances like moving forms around or in those "worst case issues" I mentioned but I use them with these mappings: https://github.com/tpope/vim-sexp-mappings-for-regular-peopl...

    There are more advanced things but how much I care about them varies; I don't tend to need them for Lisp, though every so often I'll miss something from Eclipse that I suspect not even emacs does (or does well). e.g. I know emacs can do a "templateized" completion just like a Java IDE when you type a function name and insert its arguments as placeholder variables to later define/type over, I don't know though whether emacs can then let you place the cursor over each one in turn and with something as easy as 'ctrl+1' hoist that var to an assignment form just above (I did this all the time in Eclipse to avoid having to choose a name, type it, and type its correct type). (In Lisp it's complicated by needing to introduce a let binding if it doesn't exist or append to one if it does. It wouldn't surprise me if paredit can do this, it's just that I'm aware of some refactoring tools in Slime but they don't tend to approach what Eclipse or IntelliJ users expect even if in theory they could.)

  • I think the paredit stuff is a bit overblown but apart from managing parens for you, another simple example is editing single expressions. e.g. in Java you might have a line: "int a = blah.bar(something, thing, whatever);" If you realize you need to actually pass "whatever" first, not last, unless you know an IDE shortcut that can make the edit for you, you're going to have to type stuff. I would probably just move my cursor to the start, type "whatever, ", move my cursor to the comma after "thing" and highlight to the end then delete. If "whatever" was a longer variable, or even more interestingly an entire sub-function call like "whatever(x, y, z)", I might instead highlight it all, cut, backspace the comma, move cursor to the start, paste, type a comma. Oh no, I might miss a comma or somehow mess up a paren/semicolon or typo a name?! Whatever, it's rare for me, and for most mistakes I'd get a red squiggly alerting me to it immediately. I like typing, and prefer most 'helpful' plugins get out of my way for most things, so such a process isn't that annoying to me.

    But I do at least see there's a nicer process if you have something like paredit: you just move you cursor to the "whatever" (even if it's instead "whatever(a,b,c)") and a command will move it to the left/right/etc. and fix up anything that needs fixing up. In Lisp though the base syntax is so simple and uniform that there's not usually much needing "fixing up" -- there's no pesky commas to deal with for instance, and having the opening paren come in front of the function name instead of after simplifies a lot of things. The worst is adding/removing/moving a form that's at the end of a let binding, or perhaps sometimes adding something to the end of a function that previously ended with ))).

    I like to use vim (which does have paredit though I have it disabled) and just having the ability to jump between open/close parens by pressing "%" and to cut jumps as a whole, or the insides, without having to move my cursor character by character, is good enough for me. I still use some paredit-like commands in some instances like moving forms around or in those "worst case issues" I mentioned but I use them with these mappings: https://github.com/tpope/vim-sexp-mappings-for-regular-peopl...

    There are more advanced things but how much I care about them varies; I don't tend to need them for Lisp, though every so often I'll miss something from Eclipse that I suspect not even emacs does (or does well). e.g. I know emacs can do a "templateized" completion just like a Java IDE when you type a function name and insert its arguments as placeholder variables to later define/type over, I don't know though whether emacs can then let you place the cursor over each one in turn and with something as easy as 'ctrl+1' hoist that var to an assignment form just above (I did this all the time in Eclipse to avoid having to choose a name, type it, and type its correct type). (In Lisp it's complicated by needing to introduce a let binding if it doesn't exist or append to one if it does. It wouldn't surprise me if paredit can do this, it's just that I'm aware of some refactoring tools in Slime but they don't tend to approach what Eclipse or IntelliJ users expect even if in theory they could.)

  • cl-ana

    Free (GPL) Common Lisp data analysis library with emphasis on modularity and conceptual clarity.

  • There are some other active Lisp efforts in the data science space, such as cl-ana.[1]

    [1] https://github.com/ghollisjr/cl-ana

  • awesome-lisp-companies

    Awesome Lisp Companies

  • My previous employer is on this list: https://github.com/azzamsa/awesome-lisp-companies

    The driver is actually that the company needs people with a specific skillset, and their tooling is in lisp. As I saw elsewhere on HN today: you can teach a biologist to program, but you can't teach a programmer biology. I don't think anybody is "desperate for lispers" unless their senior guru is recently departed.

  • WorkOS

    The modern identity platform for B2B SaaS. The APIs are flexible and easy-to-use, supporting authentication, user identity, and complex enterprise features like SSO and SCIM provisioning.

    WorkOS logo
  • portacle

    A portable common lisp development environment

  • You could start with a copy of the book „the land of Lisp” or „practical common Lisp”

    People seem to recommend portacle https://portacle.github.io/ for a first dev environment but I usually set everything up myself. Portacle seems to have all the essentials. You can follow SLIME installation instructions from the quicklisp page of portacle doesn’t come with it.

    Then I recommend slime manual at https://slime.common-lisp.dev/doc/slime.pdf if you’re going to be using Emacs.

    I’m not familiar with other tools.

NOTE: The number of mentions on this list indicates mentions on common posts plus user suggested alternatives. Hence, a higher number means a more popular project.

Suggest a related project

Related posts