我应该学哪种 Lisp 方言?

我知道 Lisp 有几种不同的方言。在决定了学习 Lisp 将是一种全新的智力体验之后,我想知道要学哪种 Lisp 方言,以及为什么。

有没有一个比其他的更受欢迎?其中有没有更“完整”的,比如,更好的文档化和支持?这种方言的优点和缺点是什么?

38365 次浏览

I would say Scheme, solely because of the Little Schemer, which is one of the most mind-blowingly fun yet extremely hard books I've ever tried to read.

I prefer CL, since I like object-oriented programming, and CLOS is the nicest object system around.

I learned Scheme in school. It was a great learning experience and I will never forget the fundamentals of functional programming. It probably doesn't matter which version of LISP you pick up, as long as you understand the core of its usefulness - stateless lambda calculus.

Here's an interesting article on Why MIT switched from Scheme to Python in its introductory programming course.

Also Clojure is a gaining a lot of mindshare these days, and for good reason. Great data structures, profoundly good concurrency support (puts Scheme and CL to shame in this regard), and a great community. It's also relatively simple, CL is as at least as complicated as C++.

This isn't to say I don't enjoy CL or Scheme. I learned Scheme with SICP. And CL brought me to Clojure. It all depends on your goals I suppose. If you want to learn a Lisp that is immensely practical go for Clojure. Otherwise CL or Scheme are both great.

I can recommend Common Lisp on SBCL. This combination is fast, powerful, mature and well-documented.

I would say all of them, at least at first. Eventually you will probably develop a preference for Scheme or Common Lisp, but they both have enough differences that it's best to get a handle on everything that's out there.

Scheme has continuations for example, and it's good to learn about those in Scheme, even though they can be implemented in Common Lisp.

Learning the difference between lexical and dynamic scope is important, and if you learn both Common Lisp and elisp you'll come across the implications of both.

You want to look for a balance between simplicity and cleanliness, attractive features, and a platform that will allow you to write interesting and useful software (to yourself) as well as serve as a learning tool. (This last will keep you going and learning for a lot longer.) Here are some possibilities:

  1. Scheme. Probably the cleanest of all dialects. This is no doubt why The Little Schemer was translated from LISP into Scheme. The fifth Scheme standard specification, R5RS, is a wonderful education in and of itself; it may be the nicest language and library specification I've ever read, as well as the shortest that's reasonably comprehensive. The PLT Scheme (now Racket) platform includes a fairly decent interpreter and compiler, is good for scripting, and also has some visual tools that make it excellent for learning.

  2. Common Lisp. Probably the most portable and comprehensive variant, this is most likely what you want if you want to be writing things such as commercial software. The standard defines extensive libraries, and many more are available beyond that, it has CLOS, which will probably teach you more about OO than any OO language could, and some of the compilers are very good. Disadvantages include some warts that Scheme doesn't have (such as having a separate namespace for variables that refer to functions), not being as clean and simple (as is the case with anything that has had to have the extensions and make the compromises necessary for large applications in the real world), not having hygienic macros, and emphasizing recursion much less than Scheme.

  3. Clojure. This runs on the JVM, which may give it a leg up right there for Java developers. It's got a few warts (e.g., you must explicitly ask for tail call optimization, though this may change one day if TCO is added to the JVM). The macros, while not hygienic, do have some features to help you avoid variable capture, so you can capture variables if you really want to, while running less risk of accidentally doing so than in CL. You've got easy access to all the Java libraries; that's probably a good thing for "real world" code, and fairly pointless in terms of learning. It's got a set of libraries for persistent data structures and support for STM, which make it very interesting from a concurrent point of view; this makes it probably your best bet if you're interested in learning more about new methods of dealing with concurrent and parallel programming. It appears as if Clojure is as usable for large, production applications as Java, in the sense that it's going to have the ability to do the "ugly stuff" you do in production apps that you'd rather not do and don't do when you're learning.

  4. Emacs Lisp. In terms of a LISP, this is not one of the better examples out there. One of its biggest faults is dynamic scoping, but there are many others. However, if you're an Emacs user, this may be the most powerful tool you can learn to improve your use of the editor. How much you'd really learn from learning Emacs Lisp, beyond how to extend Emacs, is for me an open question however; I don't know how often interesting techniques such as high-order functions are really used in Emacs Lisp.

2018 Update

It's been almost a decade since I wrote this post and the Lisp family of languages now appears to be gaining significant traction in the general programmer consciousness. Much of this appears to be related to Clojure which has not only become a properly separate dialect of Lisp in its own right, introducing many of its own good ideas, but also now has a near-identical version targeting JavaScript and has inspired many other Lisps targeting other platforms. For example, Hy targets the CPython AST and bytecode, aiming first for interoperability with Python, but using Clojure ideas "when in doubt." (Though from the latest commits, the latter may be changing a bit.)

The big change this brings in your decision-making process is that you should also be looking at whatever Lisps or Lisp-like languages are available for and interoperate with languages or platforms you already use, be it Perl, Ruby, Erlang, Go or even C++ on microcontrollers.

LFE (Lisp Flavored Erlang) would be nice. You can have the lisp syntax on top of the Erlang VM.

Was a kind of "loaded" question to begin with but OP probably didn't know about it. Generally, Common and Scheme lispers are like PC and Apple computer "people", they don't mix. Which one is best is probably not as relevant as which one "works" for you. Really, there is not that much difference. Likely a preference for one over the other maybe influenced by which one you learn first. (To me, an empty list should be "nothing", known in CL as NIL, and that makes me a Common Lisper.) I like the integration of SBCL with Slime using EMACS, but SBCL is not for everyone. For one thing, SBCL is very strict. If you just want to "have fun" the GNU clisp is easy and available for virtually every platform.