我为什么用 Lisp 编程
Why I Program in Lisp

原始链接: http://funcall.blogspot.com/2025/04/why-i-program-in-lisp.html

尽管Lisp缺乏主流流行度,但其独特的特性使其成为原型设计和探索性编程的理想选择。它统一的语法(前缀表示法)消除了记住复杂的运算符优先级和括号类型的需要。Lisp擅长函数式编程,支持替换模型和轻松的代码重构。轻松地将值转换为函数的能力促进了抽象思维。Lisp的交互式REPL允许实时程序开发和实验,表达式可以被无缝地测试和集成。调试器和安全的内存管理防止了探索过程中的灾难性故障。动态类型化促进了快速原型设计和临时多态性,实现了可在多种数据类型中工作的通用代码。虽然其他语言可能拥有其中的一些特性,但Lisp将它们全部结合起来,创造了一个强大的思维和解决问题的工具,使编程变得愉快。

这篇 Hacker News 帖子讨论了 Lisp 编程的优点,起因是一篇题为“为什么我用 Lisp 编程”的文章。评论者们就该语言的可读性,特别是括号问题,以及其语法所需的思维调整展开了辩论。一些人发现 Lisp 由于其嵌套结构难以阅读,而另一些人则认为这种语法反映了代码的逻辑结构。讨论扩展到泛函编程,一些参与者讨论了 I/O 与计算的分离以及如何实现纯度。其他人提到了 Common Lisp、Clojure、Haskell 和 Ruby 等替代方案及其优势。该帖子还涉及 Lisp 的优势,例如其表达能力、通过宏进行自定义以及交互式开发。最后,一些评论者谈到了 Lisp 在专业环境中为何不那么流行,以及新的 LLMs 是否会影响该语言的采用。
相关文章
  • (评论) 2024-04-22
  • 超越 Lisp 中传统的模式匹配 2025-04-09
  • 锻造与Lisp 2025-04-06
  • (评论) 2024-09-15
  • (评论) 2024-09-07

  • 原文

    Lisp is not the most popular language. It never was. Other general purpose languages are more popular and ultimately can do everything that Lisp can (if Church and Turing are correct). They have more libraries and a larger user community than Lisp does. They are more likely to be installed on a machine than Lisp is.

    Yet I prefer to program in Lisp. I keep a Lisp REPL open at all times, and I write prototypes and exploratory code in Lisp. Why do I do this? Lisp is easier to remember, has fewer limitations and hoops you have to jump through, has lower “friction” between my thoughts and my program, is easily customizable, and, frankly, more fun.

    Lisp's dreaded Cambridge Polish notation is uniform and universal. I don't have to remember whether a form takes curly braces or square brackets or what the operator precedency is or some weird punctuated syntax that was invented for no good reason. It is (operator operands ...) for everything. Nothing to remember. I basically stopped noticing the parenthesis 40 years ago. I can indent how I please.

    I program mostly functionally, and Lisp has three features that help out tremendously here. First, if you avoid side effects, it directly supports the substitution model. You can tell Lisp that when it sees this simple form, it can just replace it with that more complex one. Lisp isn't constantly pushing you into thinking imperatively. Second, since the syntax is uniform and doesn't depend on the context, you can refactor and move code around at will. Just move things in balanced parenthesis and you'll pretty much be ok.

    Third, in most computer languages, you can abstract a specific value by replacing it with a variable that names a value. But you can perform a further abstraction by replacing a variable that names a quantity with a function that computes a quantity. In functional programming, you often downplay the distinction between a value and a function that produces that value. After all, the difference is only one of time spent waiting for the answer. In Lisp, you can change an expression that denotes an object into an abtraction that computes an object by simply wrapping a lambda around it. It's less of a big deal these days, but properly working lambda expressions were only available in Lisp until recently. Even so, lambda expressions are generally pretty clumsy in other languages.

    Functional programming focuses on functions (go figure!). These are the ideal black box abstraction: values go in, answer comes out. What happens inside? Who knows! Who cares! But you can plug little simple functions together and get bigger more complex functions. There is no limit on doing this. If you can frame your problem as "I have this, I want that", then you can code it as a functional program. It is true that functional programming takes a bit of practice to get used to, but it allows you to build complex systems out of very simple parts. Once you get the hang of it, you start seeing everything as a function. (This isn't a limitation. Church's lambda calculus is a model of computation based on functional composition.)

    Lisp lets me try out new ideas as quickly as I can come up with them. New programs are indistinguishable from those built in to the language, so I can build upon them just as easily. Lisp's debugger means I don't have to stop everything and restart the world from scratch every time something goes wrong. Lisp's safe memory model means that bugs don't trash my workspace as I explore the problem.

    The REPL in lisp evaluates expressions, which are the fundamental fragments of Lisp programs. You can type in part of a Lisp program and see what it does immediately. If it works, you can simply embed the expression in a larger program. Your program takes shape in real time as you explore the problem.

    Lisp's dynamic typing gives you virtually automatic ad hoc polymorphism. If you write a program that calls +, it will work on any pair of objects that have a well-defined + operator. Now this can be a problem if you are cavalier about your types, but if you exercise a little discipline (like not defining + on combinations of strings and numbers, for example), and if you avoid automatic type coercion, then you can write very generic code that works on a superset of your data types. (Dynamic typing is a two-edged sword. It allows for fast prototyping, but it can hide bugs that would be caught at compile time in a statically typed language.)

    Other languages may share some of these features, but Lisp has them all together. It is a language that was designed to be used as a tool for thinking about problems, and that is the fun part of programming.

    联系我们 contact @ memedata.com