Hacker News new | past | comments | ask | show | jobs | submit login
Running Lisp in Production (2015) (grammarly.com)
139 points by lisper on May 24, 2020 | hide | past | favorite | 96 comments



Back in Amazon I found some ancient code written in Common Lisp. Doubt any production services left, but I updated the build system to support Clozure CL. My contribution in $BIGCORP :)


Was it the "You may also be interested in:" box on product pages? I remember going to a tech talk, many years ago, by the person who wrote that.


Nah, I implemented a simple wrapper around an internal tool for auto-translating Oracle PLSQL to SparkQL. Data Engineers liked that a lot



Thank you for the links, what a nice discussion back in 2015.

Everything has gotten more corporate. I hardly dare to make a Lisp comment now, because people from $BIGCORP would jump on it.


Really? Please dare. I don't think $BIGCORP is so dominant here, or that things have changed so much since 2015.

Most changes that people notice on HN are random fluctuation. Note that I don't say all changes—just most. The trouble is that it's hard to figure out which ones are vs. aren't, and none of us really tries. We just notice the data points we notice (which, btw, are the ones we're primed to notice—usually whatever we dislike the most) and connect the dots with material from our imagination. It's an amazing thing! Randomness plus cognitive bias equals narrative.

There's a thread about this on the front page right now: https://news.ycombinator.com/item?id=23293462. I've been saying the same thing about people's interpretations of HN for years:

https://hn.algolia.com/?dateRange=all&page=0&prefix=true&que...

https://hn.algolia.com/?dateRange=all&page=0&prefix=true&que...


For normal small team it might be hard to get advise. More diverse users in other eco-system. Even clojure is hard. At least the code is easier to read.


On reddit I found that following questions. I would be glad for some possible answers.

---------

That was a good post.

I wonder if the tech stack still uses Common Lisp after these 5 years, considering all other languages described in the post?

Are there any new lessons learned after running Common Lisp for another 5 years, if it is still actively used?

Would you pick up Common Lisp again or something else, if you can go back in time and get a chance to start fresh?

Thanks!


My previous job was all common lisp. I really enjoyed writing it. The REPL was definitely a job, and having a dynamic runtime environment.


Finally read the reference on lisp reader macros : http://www.lispworks.com/documentation/HyperSpec/Front/X_Mas...

Now I sort of get what #+unix means...


    #+foo A B
This says if the Lisp supports “foo” as a “feature” (a precise term in Common Lisp), the A will be included. Otherwise A will be treated as a comment. B will be included regardless. It’s roughly equivalent to

    #ifdef foo
    A
    #endif
    B
The opposite is #-.

    #-unix A B
is roughly

    #ifndef unix 
    A
    #endif
    B
So you can write portable source code this way.

    (defvar path-separator
      #+unix "/"
      #+windows "\\"
      #-(or unix windows) (error "idk"))
This will define a variable called PATH-SEPARATOR which is / for UNIX, \ for Windows, and a compile-time error otherwise.

The rabbit hole goes deep on this. There’s a reason it uses ‘#’, and as you pointed out, it has to do with built-in (dispatching) reader macros.


For the benefit of everybody else, #+ does feature checking.

The Common Lisp standard defines a standard "special variable" (kind of like a global) named * features * (shouldn't be spaces, but HN italicizes it otherwise), and #+ (and #-) take a "feature expression" and conditionally execute the expression that immediately follows it when the feature expression is true. If the feature check is false, the next expression is ignored.

For example:

    #+freebsd(print "This is FreeBSD")
    #+(not (and 64-bit linux))(print "This is not 64-bit Linux.")
    #+quicklisp (ql:quickload :some-library)
The CL standard lists a few standard features (:common-lisp, :ieee-floating-point, etc.) but for the most part implementations and libraries define their own.

It's not perfect, but works well enough in practice.


The common thing done with it is:

  #+nil(this expression (won't be read))
(Also done with #+and, and #+or.)

This is an unofficial Common Lisp s-expression level comment. One of these incredibly nice things that's missing in most programming languages. It comments out a single s-expression, no matter how complex. It's like a #|block comment|# in that it can span multiple lines, and like ; line comment in that you only put something at the beginning. Have a complex expression within a function, that you need to temporarily shut down? Just shove #+nil in front of it.

(The #+nil version is discouragd because there's a remote chance somebody will define a * feature * called :nil for some reason.)

A less-common thing done with it is library interop. Many libraries tend to add a tag to * features * to indicate they've been loaded, so in your library, you can use #+library_tag to detect that another library is a part of the same project, and conditionally compile-in some extensions or interoperability code.

(@dang, I think HN could use a way to escape the * * formatting marks. For a site and community that has a soft spot for Lisp, not being able to type in the "earmuffs" is something that always bewildered me.)


I would guess that there was a feature :nil defined in the NIL [1] system.

[1] https://en.wikipedia.org/wiki/NIL_(programming_language)


That must be it, thanks!


#+ is only one of many, many standard reader macros (as you can see from that link). You can also define your own, which makes Lisp syntax almost infinitely malleable. For example, it's possible to change the Lisp reader so that it natively reads infix syntax. See:

http://flownet.com/ron/lisp/djbec.lisp

for an example. Scroll down to the definition of xpt-add.


The important thing about reader macros is that they happen at read time. It causes code to be executed at tokenizing time (so you can make your own syntax, e.g. #{ ... } could return a JSON object directly) even before evaluation or macroexpansion.

So #+ and #- really only scratch the surface. Someone wrote a comment about using #+ to define the path delimiter (/ or \), but that is something that could be looked up at runtime. Read-time extension is unusual in programming languages (C++ has such a feature for a more limited set of cases).



You can add "comments>0" to get the ones with comments:

https://hn.algolia.com/?dateRange=all&page=0&prefix=true&que...


Interesting, seems the "comments>0" op is undocumented, couldn't find it anywhere on the algolia page. Is there a page with all the different operators you can use?


It's documented here: https://hn.algolia.com/help. You have to click 'help' at the bottom of the search page, I guess.

Another option I use, which doesn't appear on that page, is storyText=none, if you want to exclude matches from text posts. That one has to go in the URL, though. Note the difference between the link in my GP comment vs. this one:

https://hn.algolia.com/?dateRange=all&page=0&prefix=true&que...

The latter creates much cleaner search results if you want to match just on title and URL.


This is so cool


This is officially the hardest I've laughed at a grammar mistake. At the end of the third line, there's a missing space between "years." and "We". Petty, I know, but I expect a grammar company who took over my Youtube ads earlier about writing perfect emails and blog posts to have perfect blog posts.


Earlier? I still get them


From 2016


2015, no?


Yep, I guess I saw June 26, 2015, and flipped the 5 and the 6. Thanks.


I seriously don’t get why lisp is so popular on HN, it’s basically unreadable to very most of developers. It’s an ivory tower.


"Unreadable" is a choice at this point.

Here's a simple trick to make Lisp instantly readable. Take a line of code from an algol-like language:

  foo(bar(), baz(quux))
then, shift every opening parenthesis one token to the left:

  (foo (bar), (baz quux))
and drop the commas:

  (foo (bar) (baz quux))
Now you have an equivalent piece of Lisp code.


Hard agree. I don't use lisp, but people in an adjacent department do (yes, in prod). It takes a few minutes to learn to read lisp. Arithmetic takes a lil bit to grok, but short expressions are easy. I wouldn't share lisp that I've written with my coworkers ;)


If you prefer to use Lisp with a more conventional syntax, check out "readable Lisp: https://readable.sourceforge.io/

It has three levels of notation, depending on what you want. There is even a quick lisp library.


Personally, I like Lisp the way it is. I fully agree with this image:

https://www.reddit.com/r/lisp/comments/e2e5o/lispovision/


> it’s basically unreadable to very most of developers

The ubiquity of parenthesis has a purpose - it lets you treat code as data. Your argument only makes sense if syntax choice were 100% based on taste. But it's not (simplicity of syntax brings with it practical features), so it's great that some people are exploring other options.

And it's not intrinsically less readable than say, something like: https://gcc.gnu.org/onlinedocs/gcc-4.6.3/libstdc++/api/a0111...


> The ubiquity of parenthesis has a purpose - it lets you treat code as data. Your argument only makes sense if syntax choice were 100% based on taste. But it's not (simplicity of syntax brings with it practical features), so it's great that some people are exploring other options.

Are you sure? Plenty of languages[1,2] allow you to treat code as data and they don't need that many parenthesis.

[1] https://docs.python.org/3.8/library/ast.html

[2] https://docs.julialang.org/en/v1/manual/metaprogramming/inde...


"Python does have access to the abstract syntax tree of programs, but this is not for the faint of heart. On the plus side, the modules are easy to understand, and with five minutes and five lines of code I was able to get this:

    >>> parse("2 + 2")
    ['eval_input', ['testlist', ['test', ['and_test', ['not_test', ['comparison',
     ['expr', ['xor_expr', ['and_expr', ['shift_expr', ['arith_expr', ['term', 
      ['factor', ['power', ['atom', [2, '2']]]]], [14, '+'], ['term', ['factor',
       ['power', ['atom', [2, '2']]]]]]]]]]]]]]], [4, ''], [0, '']]
"This was rather a disapointment to me. The Lisp parse of the equivalent expression is (+ 2 2). It seems that only a real expert would want to manipulate Python parse trees, whereas Lisp parse trees are simple for anyone to use."

-- Peter Norvig, https://norvig.com/python-lisp.html


That's not code as data, that's parsed code as data.

  julia>      :(a + b*c + 1)       ==
         Meta.parse("a + b*c + 1") ==
         Expr(:call, :+, :a, Expr(:call, :*, :b, :c), 1)
  true
Why not just use a single representation (+ a (* b c) 1) ?


> That's not code as data, that's parsed code as data.

I would say: you can execute it, therefore it's code. What am I missing?

> Why not just use a single representation (+ a (* b c) 1) ?

Are you saying you don't like the default print? You can write a println method for type Expr which prints it any way you want. Seems like a miniscule thing to nitpick.


You've convinced me, there is no difference.

Why wouldn't anyone want to write code like this:

  Expr(:call, :+, :a, Expr(:call, :*, :b, :c), 1)


If you remove the Expr, you get something that kind of looks like Lisp.


Yes, if you remove a few elements you get (+ a (* b c) 1), as I said a few messages back, which is lisp code and is also lisp data. So you can treat code as data!

You can of course parse code in any language and treat it as data (and it may resemble lisp code!) but it’s not quite the same thing.


python and julia's way of accomplishing this is infinitely uglier and more adhoc than lisp's


I find languages like MUMPS unreadable, but I also know a few folks that love it and truly confused why I don't. I programmed a lot of production code with Perl, and that confuses the heck out of a lot of programmers. I loved Postscript and Forth, but I keep running into people that think they are complicated and hard to follow when the rules are so simple. People are hateful of selector-syntax in Smalltalk and Objective-C, but I think its the most easily understandable syntax out there because the what the variables are for is right there instead of just a comma separated list of variables with no hints. I truly wonder if the C family of languages gets so ingrained that anything else is just seen as crappy?

Lisp benefits greatly from a decent text editor, but it is quite readable.


Indeed, I have a friend who totally loved Mumps. I have almost 40 years with Common Lisp, love the language, but I have always been fairly open to what customers want. I know people who do amazing things with Python or Java.

I don’t much care about other peoples’ preferences for politics, programming language selection, or religion (or lack thereof).

It seems best for a team to choose a stack by some form consensus, and stick with it.

I have read the linked article several times in the 5 years since it was written, and I enjoy the shared experience. But the article could also have been about using Clojure, or Ruby, etc., etc. And also been interesting.


So, emacs?

We are talking lisp here. I don't think there's anything that compares.


HN is written in Lisp. So anyone interested in cloning HN, better understanding HN, etc, would have reason to be interested in reading up on it, even if it's not something they work with normally.

Humans being human, I would think it strange if a forum written in Lisp failed to have some sort of pro-Lisp bias.


HN itself is written in a lisp.

But I don't understand the unreadability claim: lisp syntax is extremely simple, and therefore (for me, someone is not a developer by profession) extremely readable.

What makes it unreadable for you? The parentheses? (https://i.redd.it/9gwghrz9rcs11.jpg)


The reason is arguably this essay, written by a founder of ycombinator who many here wish to emulate or get the attention of.

http://www.paulgraham.com/avg.html


You're completely right, there's nothing for you in lisp. Nothing to see here. Just move on.


To be fair, bracket abuse is pretty widespread. Lisp, at least, is honest and very consistent in their use. And I don’t find things like [](){} particularly readable (that was valid C++ syntax, BTW).


I haven't done C++ in a very long time.

That's a lambda that does nothing, right?


Correct.


I will explain it for you.

Lisp is hard to master, like playing the violin, but if you master it you can get enormous rewards.

Other languages are more like "playing guitar hero", most of the work is done for you and it it way easier to learn.

HN is like a musician network but for programmers. It attracts lots of people around the world that master lisp like musicians master an instrument.

I will tell you about myself, I had a lisp master that did teach me that what had taken me weeks in c, c++ and python code he could do it in lisp in minutes.

As I saw this man "play his instrument" it was obvious that if I wanted to be a good programmer I should master it myself.

Because I had this master teaching me, I could learn it fast.

The "secret" of Lisp is that you can automate your code writing, making you tens or hundred of times more capable with your code.

"Ivory tower" means it is not related to reality. Lisp is very real, like violins are real.


This sounds like a metaphor designed to stroke the ego of Lisp programmers but quite disconnected from the realities of the various programming languages.

> Other languages are more like "playing guitar hero", most of the work is done for you and it it way easier to learn.

What does that even mean? Python might be easier to learn than Lisp, but surely C++ is much harder to learn and impossible to master. And if you talk about "batteries included", Python may have more but C has obviously much less than Lisp.

Lisp is a fine language, but the ridiculous claims is hurting it more than helping it. I do not believe claims about the amazing productivity of Lisp from someone who doesn't know the difference between C++ and Python.


Could you give me an example of a real-world software engineering task which takes “weeks” in Python and minutes in Lisp?


>Could you give me an example of a real-world software engineering task which takes “weeks” in Python and minutes in Lisp?

Not "weeks vs hours" but let me offer my personal experience. I already had around 3 years of professional experience in Python and about the same in Common Lisp.

Last year I had to create a small utility to help some document scanning process, this included doing some OCR. I had the choice to do this in Lisp or Python or whatever language (I also could as well have written the stuff in Java, C#, C, JS, etc.)

Initially I thought "ok, i have good tesseract binding and PDF output libs in Python, where as the Lisp bindings look unmaintained" so i chose Python.

Well, back into Python's antiquated way of working: No compiler-time checking of anything, and, even worse, upon finding an error, there was no way of correcting the offending function and restarting program execution at that point (restarting a stack frame). No sir, I had to run my whole program again (this was an interaction heavy program) to test it again.

So MANY hours were lost in just having to restart the program again and do all the clicks needed to bring back the program to a specific state.

Where with Common Lisp those hours would be reduced to zero, since I can modify the program while it's running and I can always inspect all stack frames and restart them at will. Not to mention other benefits in terms of being able to write code that is way higher in abstraction level. Not to mention I can actually SAVE the current program's state to disk and resume it back at a later date.

And not to mention that the Lisp program would probably had executed 20 to 30 times faster as well.

So far, that's the last time I chose to use Python for non-trivial tasks.


Not weeks to minutes, but still, try writing an Airlines booking, scheduling application which gets the traveler the best route given his/her requirements.


That is just an algorithm, isn't it? I cant see how it would be simpler to implement in Lisp that Python.

I suspect the issue is that a flight booking system is basically the only significant commercial system written in Lisp, which is why it is always dragged out in these discussions.


The flight search was designed 20 years ago with the goal to disrupt mainframe-based flight search systems domain:

Here is some background on that particular application:

https://www.msri.org/people/members/sara/articles/airfares.p...

http://www.paulgraham.com/carl.html

> I suspect the issue is that a flight booking system is basically the only significant commercial system written in Lisp

How would you know that?


The claim was that something which would take weeks in say Python would take minutes in Lisp. Then this flight search system is presented as evidence.

I just don't see how it is any form of evidence for that rather extraordinary claim? It just shows it is possible to write complex software in Lisp, but I wasn't disputing that. I'm disputing the claim of 100 x productivity.


I was addressing your 'That is just an algorithm, isn't it?', in case you would be interested what that application is actually about.

There was no general claim of 100x productivity. The commenter wrote: "I had a lisp master that did teach me that what had taken me weeks in c, c++ and python code he could do it in lisp in minutes"

That was his personal impression, not a general claim. I can't also imagine how this could be a general claim.


Yes the sauce is in the algorithm and its a non-trivial one. Its a NP hard problem of searching through a combinatorial explosion of possible configuration. I am not aware of any other product that comes close to what ITA offered.

The feature of Lisp that was heavily used in the code was the use of macros and metaprogramming. These are the kinds of problems were lisp excels. ITA made use of the fact that Lisp is a programmable programming language and they adapted programming language to the domain.


Other people tried (and succeeded). Like Sabre (seems to be c++, but most is actually SQL it seems), or Amadeus.

Well, what I mean: can you elaborate a bit more?


The reference is to ITA Software who wrote their code in lisp. The company was acquired by google.

https://en.m.wikipedia.org/wiki/ITA_Software


I am not doubting that Lisp is a language with which can be used to write succesful commercial applications. I am questioning the claim that it is vastly more productive for commercial applications. Of course it is not really possible to say how somebody else in a different language would have needed, so maybe a compromise would be to see some 'magical'lisp code examples.


ITA software would definitely be worth looking at, but you would need to get hired by the right team.

More details here http://www.paulgraham.com/carl.html you can also glean more information by searching over older discussions about ITA on HN.


This is really interesting. I am amazed by the circumvention of the GC for large data; this thought would have never occured to me.


If it runs on C++ now, it's been rewritten. Sabre predates C by many, many years and it almost predates Bjarne Stroustrup himself. I suspect a lot of it got moved to IBM assembly when they moved to S/360 mainframes in the early 70's. TPF is a descendant of that project.


I interviewed for a job working on Sabre in the late 80s, I was told it was written in C.


I suppose it no longer runs on IBM mainframes either. The original 360 port was in assembly and a dialect of PL/1.


Thats the story beeing told. Since I havent seen it, my critical mind starts to think, that this is actually a myth. Do you know of any published (in the sense one can reas the code) examples that show this claim (and the reddit v1 is not such an example)

(Of course anybody can chime in, it should be actually easy, if the claim that here the experts are lingering around)


See S-expressions in another way like this http://cirru.org/ .


I have a complaint. Each comment from the parent poster has been downvoted, so much so that I struggle to read them.

Is this what we do now? Instead of agreeing to disagree, or (better!) explaining our viewpoint, we make comments fade into the background? Whatever happened to edification?

Because, these are valid comments! The real world bears them out! I strongly disagree, but that does not make me (or anyone else) right. This is a forum for discussion, so - discuss!


Well said.


I think you answered your own question.


There is no good reason to use an esoteric language in production except in order to make yourself irreplaceable.


I wouldn't say Common Lisp is a esoteric language. Esoteric makes me think Brainfuck and other similar languages. Common Lisp and lisps in general are languages you can be productive in, in a "building a product" sense, which you cannot say about most esoteric languages.


The author himself says it’s esoteric


He didn't.

He wrote: 'Contrary to popular opinion, Lisp is an incredibly practical language for building production systems.'


[flagged]


I've read it.

It says: 'We’ve built an esoteric application (even by Lisp standards)'

The application was considered by the author to be esoteric in 2015, not the programming language.

Quote: "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 it is one of the biggest consumers of computing resources in our network."

The application is the compute core of a cloud-based grammar checker with lots of complex lingustic knowledge, which generates a lot of processing load.

And "(even by Lisp standards)" just means that there are other applications in the Natural Language Processing domain, which were written in Lisp, like software to do machine translation between language or text content checking systems for technical documents.


Also, if you’re really willing to go into it you could be productive in Brainfuck. Doesn’t mean it applies to the general crowd.


It’s not a good comparison at all. Learning lisp or understanding it is a good base knowledge regardless of your primarily language. It’s not a language that’s truly esoteric and difficult to reason about by nature. Metaprogramming/macros can be difficult for those inexperienced, but not impossible. Esoteric languages are often created to either use unfamiliar syntax compared to common languages or unfamiliar paradigms to those. In the end, a lot of things are very similar in nature with esoteric languages, just a very different way, with syntax that’s not as readable as common languages. Lisp is certainly readable and easy to grin even if you have little knowledge of the language


Please don't do programming language flamewars on HN. They're tedious.


Erm, Lisps were used back in time for many production systems when C++ wasn't even started. Looks like your definition of esoteric and production is based on couple of years of cheap CS courses.


Oxford's definition of esoteric: "intended for or likely to be understood by only a small number of people with a specialized knowledge or interest."

Today, C++ is a dominant programming language. Lisp is only used in niche applications. Therefore, it is likely only to be understood by a small number of people with specialized knowledge -- hence, it is esoteric.


Upon conception it was neither "intended" nor "likely" "to be understood by only a small number of people with a specialized knowledge or interest" and it is still not intended that way nor likely, that only few people _can_ understand it. It is just that people choose not to take time and understand it.

I don't agree with the conclusion you draw from a definition of esoteric, that is without context anyway, taken from a natural language dictionary.


>Lisp is only used in niche applications

Which niche btw?


You are ignorant of reality, and the first thing that you ignore is that you are ignorant.

With Lisp you don't even need to write lisp code. You can write java, c++,c, swift code... using lisp.

That is , you can write lisp code without people realizing you are writing lisp code. The only thing they will notice is that your code looks almost too perfect, too well formatted and justified, are extremely productive and never make mistakes.


How can one write C for example using lisp? Are you talking about compiling to C?


Sometimes people write Lisp code and use translators to C or C++. Some of that code then will be maintained in C / C++. Some of these tools were custom developed, but there existed also specialized Lisp to C translators, which produced 'maintainable' code.

For example the first version of the .net garbage collector was written in Common Lisp and then translated to C++. Since then it was maintained and enhanced in the C++ version.

https://web.archive.org/web/20150307034829/http://blogs.msdn...


Interesting, I was not aware of this, thank you.


Languages have strengths and weaknesses. Learning the right language to express a solution is easier than doing it the hard way in the wrong language just because you happen to know it.


There's also onanism.


And that’s the epitome of selfishness




Is it so hard to click "hide"?




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: