Hacker News new | past | comments | ask | show | jobs | submit login
ANSI Common Lisp (1995) (paulgraham.com)
129 points by todsacerdoti on Jan 18, 2020 | hide | past | favorite | 54 comments



I feel like the Common Lisp and Erlang communities have produced writing about software that has really stood the test of time.

From the CL spec, to Norvig's "Paradigms of Artificial Intelligence Programming: Case Studies in Common Lisp," to both of pg's CL books (this one and 'On Lisp') -- these all feel readable, even re-readable, and entertaining.

And of course the same can be said of the Erlang books -- I'll read anything I find by Joe Armstrong or Robert Virding.

In both cases, authors are able to joyously present the language's unique superpowers and ways of thinking (CL-style macros, OTP). But I think a crucial factor is that, since both languages are very practical -- in terms of their reason-to-exist, as well as what they provide 'out of the box' -- the writing tends to be imbued with the energy and possibility of actually building things.


Both came of academic roots (mit/ai, and prolog influences for erlang), to me it gave a very dry but highly structured conceptual foundations. I mean lisp is mostly tree recursion everywhere. Unlike simpler languages that were use-case driven, and iterated over the absorption of better concepts over time, waving between fads.


> I mean lisp is mostly tree recursion everywhere.

Two things:

1. This isn't true. Common Lisp style emphasizes looping; Scheme emphasizes recursion.

2. What's wrong with tree recursion anyway?


1) well I may be cutting corners but to me lisp is vastly about sexp and encoding of interpretation in sexps.

that commonlisp advocates for some linear looping constructs is one thing but, to me, it's only a thin part of the top of the iceberg

2) nothing wrong to me, but I suppose that to the mainstream, if you had to pick between sexps, lambdas and treerec idioms over perl regexes or php arrays/templating, or jQuery dom shenaningans .. it probably look too dry to bear any value (culture shock)

Again, that's only my opinion :)


Many think/prefer that it is a compiler's job to convert conveniently (Algol-style) written program into AST, even if this reduces the macros capabilities - even Norvig switched to Python long time ago :)


Some of us find that writing ASTs directly with a smart editor is much more convenient than writing Algol-style languages.

Norvig switched to Python when he left NASA and went to work for Google. He wasn't going to convert Google's culture to one that embraced Lisp.


This is potentially such a Annie Hall Marshall McLuhan moment. Here's hoping @norvig pops in and replies to this thread.


Let Over Lambda is another classic. I heard HtDP is also good, but I haven't read it.


And Lisp in Small Pieces, discussed here: https://news.ycombinator.com/item?id=8600048


Well, if we're doing a generic Common Lisp thread some of you might be interested in buildLisp.nix[0], my project to write a build system for CL in Nix[1].

The idea here is that Nix should be usable for builds at the same abstraction level as Bazel (i.e. individual build targets), while retaining the power of the rest of the ecosystem.

Example build "manifest" using buildLisp.nix: https://git.tazj.in/tree/third_party/lisp/alexandria/default...

This has a few additional neat benefits, such as making it possible to easily spin up a REPL with the correct Lisp & dependencies loaded from within Emacs[2].

There's also a similar project I did for Go[3] to prove the general viability of the concept.

[0]: https://git.tazj.in/tree/nix/buildLisp/

[1]: https://nixos.org/nix/

[2]: https://git.tazj.in/tree/tools/emacs-pkgs/nix-util/nix-util....

[3]: https://git.tazj.in/tree/nix/buildGo/README.md


Lisp user here. Scratching my head on this one: What's it build exactly? Why would I use this over, say, Quicklisp? Is this just a Nix thing?

Edit: Also, why do you need to specify all the .lisp files in the build(?) file?


> What's it build exactly?

For libraries, it builds an output with a concatenated FASL for all inputs (which reference the sources by their exact hash in the Nix store, which means that they will be distributed alongside).

For programs, it dumps an executable image (save-lisp-and-die with `:executable t`).

For `buildLisp.sbclWith` it creates an SBCL that loads an image pre-loaded with all the dependencies.

> Why would I use this over, say, Quicklisp?

Quicklisp is one small bit of the puzzle (the distribution of packages using ASDF).

Using Nix for the task replaces Quicklisp, ASDF, your distribution package manager used to install your Lisp, your distribution package manager used to install native dependencies of your Lisp code (e.g. cl+ssl with openssl[0]), your deployment tooling and generally your entire software packaging and distribution stack which leaves you with one homogeneous system that is easily composed across language boundaries.

> why do you need to specify all the .lisp files in the build(?) file?

I modeled this after the way Bazel rules are normally written, where specifying each source file is common. In fact, ASDF does this too.

[0]: https://git.tazj.in/tree/third_party/lisp/cl-plus-ssl.nix#n2...


Neat. I will try this. Check out Guix. It's similar but defines packages in Scheme, which I prefer greatly to the Nix DSL.


I actually prefer the Nix language[0] over Scheme, mostly because I enjoy not having to deal with namespaces (which also has drawbacks) and instead modifying one large expression.

[0]: https://github.com/tazjin/nix-1p


I read through much of this book as a fun hobby/side project. I felt at times this was a book written by a genius for geniuses... For example, there's a chapter on numerics. Simple, right? PG's "example" was a full ray-tracing library in only about three pages. There were single pages that took me an hour to read and understand fully. Very cool/fun stuff, but also extremely terse, especially if you're new to lisp.


I wonder what Paul Graham thinks of Clojure, which is the only Lisp I really have experience with.

I love being able to take advantage of all the wonderful Java libraries out there. Nowadays, I think you can even use Python libraries from Clojure [0].

[0]: https://github.com/cnuernber/libpython-clj


ANSI Common Lisp is good book to learn Common Lisp.

I especially like the Appendix D: Language Reference. CL already has very good and comprehensive reference: the Hyperspec, but the Reference in the book is good companion to to it, very much like cheat sheet. You can quickly look up things. (my copy is already braking down from the end)


There is also a Common Lisp Quick Reference for self-printing:

http://clqr.boundp.org


The hyperspec is awesome, but kinda rough to read at first glance.


If anyone is interested, this is a project you can use to generate a nice template for a compilable common lisp project for Linux that uses sbcl, which really reduces the initial setup pain for new projects: https://github.com/triclops200/quickapp/

And this is a project that uses that to make quickapp itself a binary you can install: https://github.com/triclops200/quickapp-cli

Both of these projects need a little TLC as I haven't touched them in a while, but they should still work.


I have a copy for home, one for work, and one to lend. "On Lisp" by the same author is a wonderful glimpse into the power of macros.


You use it at work?!


I want to give Common Lisp a try. My previous experience with Lisp (any variant) is almost nil. Would this be a good book to start with?


Try Practical Common Lisp or Land of Lisp instead. They are both much more accessible. Then read ACL.


Seconded, Practical Common Lisp was instrumental getting me to think in a sound modular fashion.


Agreed. Read Graham's books after you're somewhat comfortable with the language, to learn advanced techniques. Norvig's books on Common Lisp are also a good place to start.


Practical Common Lisp (first few chapters)

do a toy project

read a lot of old Common Lisp code floating around on tarballs

then read Paul Graham's books


I would be grateful if you could provide a link to the tarballs


Old tarballs? Really? Well, here:

https://www.cs.cmu.edu/afs/cs/project/ai-repository/ai/lang/...

and some of the software here:

https://www.cs.cmu.edu/afs/cs/project/ai-repository/ai/areas...

But some of that has newer versions in the usual repositories.


ftp://ftp.ai.mit.edu/pub/

http://www.norvig.com/paip/

Have fun


I believe that the absolute shortest way to start with Lisp for somebody that is already familiar with programming is Franz Inc course that is freely avaialable online here: https://franz.com/services/classes/. It goes straight to the point and has exercises. Practical Common Lisp is a good book but takes a too long route to get to the point. I would recommend it only to somebody that is not a programmer by trade.


Get a copy of Racket, take notes, type in the programs for yourself, experiment. This video is the best most direct introduction I have yet found.

https://www.youtube.com/watch?v=a5p8DPbaokE

Learning Lisp, Scheme or Clojure is more about learning ideas than anything else.

Later you might want to learn Alonzo Church's Lambda calculus after learning some set theory and mathematical logic.


Racket is not Common Lisp. It's not a bad idea to learn it, but the questioner specifically asked about Common Lisp.


Skip CL for now, and use Clojure or Racket. CL's ecosystem requires some hacking to make it work pretty often, and the only true editor for it is Emacs and Slime, so it's not a great out of the box experience.

Racket comes with an editor and a ton of libraries, so I'd recommend checking that out first (and then coming back to CL later maybe)


Why is lisp still so uncommon today as a practical, business-needs language? Everyone I know who uses it loves it, but it’s virtually nonexistent in today’s enterprise.


Things could change though when you look at the landscape of computer languages today:

- OOP is trending downward, and for good reasons, look at Java and C#, too verbose, too top-down.

- dynamic languages are not efficient enough, especially in the cloud where they require 10 VM to do the work that could be done on a single machine with lower level languages.

- c/c++ are too low-level, hard to master/difficult to maintain.

- Rust is a mess, too verbose, too complex.

- In the FP universe, which is trending up, Haskell is too complex, F# is good but the libraries (.NET) are OOP mainly so the integration sucks. Clojure, not sure, didn't play with it but my guess is it suffers the same problem than F#.

So, personally, and not trying to convince anyone here, lisp, and especially Common Lisp with its large number of available libraries and its good development environments (emacs/slime), is getting more interesting every day.


Just want to throw D into the ring as a candidate here. It's a smashing language. I think it satisfies the very compromise you are seeking from your evaluations of other languages.


Thank you for reading me so well :) It's a very interesting language for sure, checks a lot of boxes. How is the market trending for it job wise? What I'm finding online so far seems pretty mixed.


Java is mediocre (better than it used to be), but Scala and Kotlin benefit from those huge investments in JVM optimization and have a lot of potential if you don't need the minimal footprint of Rust.


Scala is an interesting language, but now, it's back to java ugliness as soon as you need to import some existing java classes. That's my issue with all the JVM languages (and .NET is even worse here).


In theory there's no reason it shouldn't be used. CL has OOP, GC, very mature optimizing compilers. It was used in industry a lot as the faster-to-develop alternative to C, but then Java/Python pretty much took over since the dotcom era.

In Java/Python (and now Go), there's generally only one way to do any given thing. A business can hire people who were trained the same way to stamp out idiomatic code. Lisp hackers create works of art that no one else can figure out after they leave.

If you're working on something on your own, or with a small group of people, then you don't have to dumb yourself down. You can always rewrite it later in Java/Python/Go if the project gets big enough that replaceable cogs need to be hired.


> Lisp hackers create works of art that no one else can figure out after they leave.

It's possible, but it's not necessarily so. There are many Lisp code bases which are 20, 30, 40 or even 50 years old and still maintained, passing on the work to new generations of programmers.

Maxima has bits from the end 60s. Cyc is under continuous development from the early 80s onwards. SBCL is based on Spice Lisp code developed at CMU from 1981. The commercial implementations Allegro CL and LispWorks with their IDEs and libraries are under development since mid/end 80s. Axiom/Fricas computer algebra systems started the code base in the 70s at IBM as Scratchpad 2. The first MIT LOOP macro implementation was written in the 70s and then modified as Lisp dialects changed. The G2 process control system by Gensym started mid/end 80s and is still being sold. The SPIKE telescope scheduling system from NASA is still in use for various large earth and space telescopes - originally development started in the end 80s.

I've seen code bases which I could not understand from looking at them - rare, though. The biggest problems were code bases which were tied to a particular implementation and OS. For example the Sk8 multimedia development environment written by Apple is non-portable, since the Lisp code uses Mac native graphics/multimedia libraries everywhere directly from Lisp and is not abstracted in a layer.


Thanks so much for this comment. I've only scratched the surface of Cyc and SPIKE and half an hour is already gone.

I hope someday to work on something even remotely as challenging and worthy of applying one's brain power to as these honest projects are. In the meantime, I have to bear the "full stack developer" mania and its zombie friends.


Because it's not popular, and managers like popular languages because they imply a large supply of fungible programmers. Whether the language is actually powerful (or even useful) is never as important as popularity.


It's more that a language and its relative expressive power is not nearly as important to project success as the ecosystem around it. Who can I hire? If I lose them who can I replace them with? What frameworks can we use? How can I get support?


this is tangential to your point, but I feel as though I personally use this justification often in technical projects, a wide base of users often means a large base of accessible supporting material and community. while I'm sure of the utilitarian justification I can't help but feel it's also laziness on my part.


It's not used in business because it's not popular. One of the two factors that hinder its popularity is the friction needed to set-up a proper development environment and the learning curve that one has to take to master it.

- To code effectively one has to learn how to edit at the sexp level rather than at the word level.

- The only free editors that provide proper debugging and repl support are the ones that offer a plugin for Swank. Amongst these the best two are Emacs and Vi(m) with Emacs that has an advantage in terms of additional support for CL.

- Installing and configuring properly all the above requires some work.

- There have been recently attempts to mitigate this (e.g. Portacle) but in any case one has to learn Emacs (or Vim), Swank commands and a Lisp supporting mode such as lispy,paredit,parinfer, etc.

- Windows is a second rate citizen: there is no free Windows implementation that allows to step native code. Emacs is a second rate citizen on Windows as well. (This is mitigated by the fact that SBCL runs on Windows Subsystem for Linux).

- The commercial implementations are very good but expensive.

Now compare all of this with the typical developer that just downloads Visual Studio code and starts to write Javascript on Linux, Windows or Mac. All of the points above are of course not insurmountable but require some investment in time. One has to take a couple of weeks to start to become proficient in all above. The typical young developer doesn't have this patience.

This is exactly why CL is more common amongst who uses Emacs already: if you master Emacs the jump to CL is almost consequential.


Very little concept of security, privacy and a default paradigm of "lisp assumes it owns the environment".

This may no longer be true, but it's a large barrier against being adopted in many industries. That and it's kind of hard to do modern graphics with many implementations.... although they can do html serving pretty well.

LISP environments may be the start of GUI, but that code is largely locked up, or in systems that can no longer be used (I think?) Anyway, all stuff worth putting some attention on!

(note : just a lisp fan, and only an edge one, so likely no longer accurate on many points Most of the above came from reading 50s through 90s texts, and trying lisp environments at the time)


Because it rewards depth-first expertise rather than breadth-first, and there are few deep experts and many broad experts.


For a long time, the answer was probably performance. Lots of people were trained to use Lisp in their computer science courses, and lots of people admired it. But it was never anywhere near as fast as C, and in the seventies and eighties squeezing every darn bit of speed out of your hardware was what counted.

The language had another chance in the nineties, when it became important to save not just execution time, but the programmer's time also. This is when interpreted languages like Perl and Python started showing up in a big way. I'm less confident why Lisp lost out that time, but its weird syntax is probably at least part of the reason.


Perl was quirky at best, but performed very well on simple string manipulation, so it briefly replaced a lot of "grep | sed | awk" use cases where interpreted Python or Lisp might have been 100x slower.

As an imperative language for novices, Python (based on GvR's earlier ABC) was slow but more approachable than Lisp, and the industry had a huge influx of novices at the time (arguably still does). Now that GC and closures are table stakes, Lisp no longer has major advantages until you're ready to create DSLs.


Lisp was more or less abandoned in the 90s.


Other languages stole many of the nice features from lisp and the things they didn't (or couldn't steal) were not that important.


Unless you are doing web stuff, you'll face significant resistance from your platform with no clear gain imo




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

Search: