Running Lisp in Production (2015)
tech.grammarly.com
tech.grammarly.com
But, this article gives one of the reasons for avoiding its use in a high performance production environment. Provisioning a VM with over 25GB RAM for an application which requires about 4GB of it is a huge waste of resources.
While the common wisdom on HN is that for most applications, developer costs more than physical resources. Physical resources still cost money.
Initially list might be a good option for development velocity. But, over time as the application matures, adding features becomes more complicated and the velocity goes down anyway. Shifting to something which reduces costs by upto 6x might be worth it.
That said, I don't think I'll ever use lisp for front-facing web stuff again. I wrote cl-async, and afterwards and used it in production in a few places, then a bit later started using node heavily. The tooling for CL is just not there. Quicklisp is great, but not being able to pick and choose package versions is limiting, and having to rewrite every single thing for async was a pain (since CL doesn't have continuations, any sort of async that avoids CPS is impossible). I was hoping I would get more community support on cl-async, and I did get many hands helping, but eventually it just became too much to maintain. So if you're doing network stuff on CL, it's probably best to just use threaded, which IMO just doesn't handle the same amount of load evented does, at least when dealing with web APIs.
One thing I used lisp for briefly which I want to do again soon is game dev. Being able to redefine/fix portions of your program while it's running is fantastic, especially when you have huge amounts of state to deal with like you do in games. I wouldn't exactly call that running CL in production, though.
I'm interested exactly what the pain points are with CPS. Do you mean manually rewriting in continuations is tedious or is there a more insidious issue. I haven't tried writing async code in Lisp but macros would appear to eliminate continuation-writing-by-hand.
They don't =]. There's cl-cont, but it's like building a house on a foundation of toothpicks. Not to discount the work the author put in, but you can only do very specific things with it, and last time I looked, error/exception handling was pretty much completely missing.
> I'm interested exactly what the pain points are with CPS
Basically, for example, if I'm going to convert cl-postgres to use async, I have to rip out the protocol parsing from the networking (they are often globbed together) then I have to replace the networking with async and tie it back into the protocol parsing. This in itself isn't too bad, but then anything that calls the new async cl-postgres has to be converted to expect async...all the way up. This can be somewhat alleviated by promises (https://orthecreedence.github.io/blackbird/) but they still don't change the fact that the entire stack is unwound once you call into async.
Continuations would allow building green threads/coroutines which would eliminate CPS and allow you to preserve your stack while calling into async, but CL is pretty much written in stone to not have continuations (or coroutines et al) at this point.
Qlot looks handy, thanks for the tip.
Isn't this the very consequence of going async? I'm reminded of the article on this recently featured here[1]. Once you introduce async, you poison everything up to the event loop (which, with usual async implementations, you don't even see or control).
[0] - http://journal.stuffwithstuff.com/2015/02/01/what-color-is-y... + https://news.ycombinator.com/item?id=16732948
Like I mentioned, depends on the language features. If it has coroutines/green threads/continuations, you can use async without unwinding the entire stack. CL will probably always have this problem, unless the bigger implementations independently decide to implement the necessary building blocks (which they probably won't).
Try explaining that to me 5 years ago, though.
Clojure does this a lot better with Pulsar.
Anything further from your experience and retrospective working on the project would be invaluable to document somewhere for the CL community at some point. Just your insight here in the above comment is very interesting. Over time things may improve.
I do hope things improve over time. I'd love to come back to CL, and actually plan to sometime soon. I'd like to get my pet project, Turtl (which was using cl-async/Wookie in production and is now migrating to node), in a stable place (and hopefully making money from it at some point) and then start dipping my toe into game programming again. I'll almost definitely use CL over anything else. Maybe I'll write the GPG-verifying, version-pinning quicklisp wrapper I've always wanted while I'm at it =].
As far as retrospective, I think I suffered from the part of the lisp community I had always hoped wasn't true (or hoped I could change): people are much quicker to build their own version than to improve on something existing. I think if Wookie had gotten more attention and cl-async had had a few more drivers written (postgres, mysql, etc) it could have gotten a foothold. It didn't though, and I got tired of hacking through the digital reeds with my machete when I already knew javascript pretty well and node had all this stuff figured out already. It's funny, after using Express for ~4 years, I keep having the urge to go back and implement what I've learned into Wookie. I have to tell myself that it's probably best to just let it sit for now.
On another note, my dog, Wookie, who the project was named after, died last week. So it seems even more appropriate to let the whole thing rest. I might re-use the name if I come back to the CL world, though. Seems its doppleganger project got more focus anyway.
I guess containerization solves much of this problem now, but back when I was heavily into CL, containers were just starting to peek their heads out into the world at large.
All in all, I think I just hit one too many problems using cl-async/wookie in production to justify using it vs Node which just kind of works and has a plethora of maintained packages.
<Insert electron/slack joke here>
For 100s to 1000s of servers. The cost starts mattering.
I'm not saying new applications shouldn't be built on lisp. Most applications don't have huge scaling requirements. But, if you expect the application to grow, have a plan in place for migration.
If you need 100s to 1000s of servers you presumably already have customers and money to spend.
Most of the time you aren't gonna need it (because you wont go far anyway as a company). And when you do -- like Twitter and Facebook did, you'll be swimming in users and money already anyway...
Like pretty much every JVM-based application ever? For the last 15 years?
Are you saying that's not true, and that the JVM is actually no better than SBCL? I'd love to read a counterpoint.
> Our Lisp services are conceptually a classical AI application that operates on huge piles of knowledge created by linguists and researchers. It’s mostly a CPU-bound program, and is one of the biggest consumers of computing resources in our network.
CPU-intensive processing is exactly the kind of work that the BEAM is lousy at handling. Elixir would be a terrible implementation language for this kind of thing.
Also, Chicken offers a number of other advantages apart from a much smaller footprint, like elegance, a less crufty and more modern syntax, and the ability to compile down to C.
Chicken:
((lambda (x y #!optional z #!rest r #!key i (j 1))
(list x y z i: i j: j))
3 4 5 i: 6 i: 7)
=> (3 4 5 i: 6 j: 1)
CL: ((lambda (x y &optional z &rest r &key i (j 1))
(list x y z :i i :j j))
3 4 5 :i 6 :i 7)
=> (3 4 5 :I 6 :J 1)
Is the CL code more crufty compared to the almost equivalent Scheme code? Sure not. or is #!optional now more modern than &optional?Guess where the Chicken feature originally came from ...
The difference: the CL code works in every CL implementation.
> and the ability to compile down to C.
There are many implementations which do that. SBCL has the ability to compile to optimized native code with a type-inferencing compiler...
Chicken is a great implementation with a nice ecosystem, but that it is more elegant than CL - while it copies lots of features from CL (like COOPS copies from CLOS) - is an illusion.
http://wiki.call-cc.org/eggref/4/coops
> COOPS provides classes, generic functions and methods, similar in style and use to the classic Lisp object systems like Flavors, Loops or CLOS. For general information about object-oriented programming in the context of Lisp, consult one of the various books and guides available to the subject.
Example:
Chicken:
(define-method (pop (stack <stack>))
(let* ((c (slot-value stack 'content))
(x (car c)))
(set! (slot-value stack 'content) (cdr c))
x))
Let's see how it's in Common Lisp: (defmethod pop ((s stack))
(let* ((c (slot-value s 'content))
(x (car c)))
(setf (slot-value s 'content) (cdr c))
x))
Which is more modern? To me it looks the same. The difference: the CLOS code runs in every CL implementation. (defmethod popm ((s stack)) ;; don't clash with cl:pop macro
(pop (slot-value s 'content))) ;; speaking of which, use it.
I think you have to write your own pop macro in Scheme or find some lib.This HN submission's referenced article ("Running Lisp in Production" (2015)) is about SBCL which compiles down to native code.
There are CL implementations that compile to C, if you think that is better for some reason.
For instance, derivatives of Kyoto Common Lisp, such as GNU Common Lisp.
Or ECL:
https://common-lisp.net/project/ecl/static/manual/ch34s02.ht... "The other type of compilation is the so-called "native" compilation. This process consists on translating the lisp source file to C language. The intermediate file is later compiled using a C compiler."
Most "mainstream" languages aren't any better.
If you have to build rather than buy all the infrastructure that's not your core product, you lose. That's a huge yak to shave, and startups can't -- and mature businesses won't -- absorb the upfront costs of doing all that work.
Which is where Clojure comes in.
Were a significant number of Lispers really waiting for LightTable to be usable for them?
The big deal with tools like LightTable is it's much easier for newcomers to start working on projects. I understand why a user wouldn't want to learn both a language and an editor. One huge issue we struggle with emacs/slime as the editor of choice. Personally I'm a VIM guy, so I got it working there, but that's after I spent some time deep in Vimscript and fiddling with plugins. It's a lot to ask for people that are new, or those that have an editor of choice that isn't supported.
The creator, Chris Granger, abandoned it for his next project, Eve. After it became clear Chris had left, the community tried to pull together and continue, but it looks like it hasn't been updated in months.
> closed as off-topic by kleopatra, Martijn Pieters Jun 19 '15 at 19:55
All the best SO questions get closed.
"Questions asking us to recommend or find a book, tool, software library, tutorial or other off-site resource are off-topic for Stack Overflow as they tend to attract opinionated answers and spam."
The question is asking how to find the specification for an XML format. This is very much a "only one correct answer" kind of question, not a "which X do you like best?" kind of question.
Something along the lines of I'm looking for a spec about X, but I haven't had any luck finding it.
What is the specification for X?
or
What is the name of the specification for X?
or
Is there a specification that defines the output of X?
While most of the answers will likely link to a resource, technically you didn't ask for an offsite resource, however it may be seen as too broad , or still may get closed for asking for offsite resources.