![]()
你每天撰寫 if-else
你在終端機執行程式碼然後 REPL 回應你
你在 Python 使用 lambda、在 JavaScript 使用 arrow function、在 Rust 使用 closure
— 這一切 都源自 LISP 語言
而最令人驚訝的是… LISP 從一開始就從未被 planned 成為一門程式語言
1958 — John McCarthy 在 MIT 開始發展 LISP 的概念
1960 年 4 月 — 32 歲的 McCarthy 在 Communications of the ACM (vol. 3, 頁 184-195) 發表論文
“Recursive Functions of Symbolic Expressions and Their Computation by Machine, Part I”
在這篇 12 頁的論文中,McCarthy 提出了程式語言的理念,該語言:
McCarthy 將其寫成 數學理論 — 並無打算實作
但在論文發表前 — 1958-59 年間,研究生 Steve Russell 閱讀了手稿
“I told him, ‘Steve, why don’t you program this eval?’ and he said to me, ‘Oh, I misread what you meant. I thought you meant I should implement the interpreter.'”
— John McCarthy, ACM interview
這位學生 為老師的理論撰寫了解釋器 — LISP 語言就此誕生
Russell 撰寫的第一版程式碼只花了 2-3 天(完整的 LISP 1.5 Programmer’s Manual 則在之後的 1962 年才出版)
回到 1958 年 — 大多數語言只有 GOTO 與類似 assembly 的 branch
McCarthy 創造了 cond(條件表達式)— 這就是我們今天在幾乎所有語言中看到的 if-else 之起源
(cond ((< x 0) 'negative)
((= x 0) 'zero)
(t 'positive))
Enter fullscreen mode
Exit fullscreen mode
C、Java、Python、JavaScript、Go、Rust — 這些語言全都繼承了這份遺產。所有現代語言的條件分支,其結構都與 McCarthy 在人類登月前所構思的一樣
在 LISP 之前 — 程式設計師必須 100% 自己管理記憶體,每一行都要處理 malloc 與 free
LISP 創造了世界上第一個垃圾回收機制 — 其原始版本是 mark-and-sweep 演算法(由 MIT 學生 Daniel Edwards 實作)
如今 GC 已成為幾乎所有高階語言的預設機制 — Java、Python、JavaScript、Go、C#、Ruby 都延續並發展了這個概念
(lambda (x) (* x x))
Enter fullscreen mode
Exit fullscreen mode
LISP 讓函式成為 first-class citizen — 可以將函式當作參數傳遞、回傳函式、將函式存入變數,就像處理字串或整數一樣
這就是以下特性的源頭:
(x) => x * x(Brendan Eich 原本被 Netscape 聘請是要在瀏覽器中實作 Scheme — 但管理階層改變主意,要求語法像 Java)lambda x: x * x
Read-Eval-Print Loop — LISP 在 1960 年代創造了它
在那之前:撰寫程式碼 → 編譯 → 執行 → 除錯 → 重複
在那之後:輸入表達式 → 按下 enter → 立即看到結果
如今當你開啟 Python REPL(>>>)、Node.js console、Ruby IRB、Chrome DevTools、Rust Playground 或 Elixir IEx — 你正坐在與 60 年前 LISP 程式設計師相同的教室裡
'(+ 1 2) ; ← 這是一個 list
(eval '(+ 1 2)) ; ← 這是執行該 list 的程式碼
Enter fullscreen mode
Exit fullscreen mode
LISP 是用… LISP 本身撰寫的 — 程式碼與資料使用相同的結構(S-expression)
這代表 程式可以修改自己 — 無需使用 parser 來分離 AST,也無需撰寫 transformer
這是程式語言中最強大的 macro system 之基礎
沒有任何語言能像 LISP 一樣完整實現 — 但「code as data」的概念出現在:
LISP (1958)
├── Scheme (1975) — minimalist, lexical scoping
│ ├── JavaScript (1995) — Brendan Eich 原本打算在瀏覽器中實作類似 Scheme 的語言
│ │ └── arrow functions, closure, first-class functions
│ └── Racket (1995) — 用於教學與研究的語言
├── Common Lisp (1984) — 工業級、實用導向
│ └── Emacs Lisp (1985) — 編輯器腳本語言 (GNU Emacs)
├── Clojure (2007) — 跑在 JVM 上的 LISP,預設不可變
│ └── 點燃了企業界的功能式程式設計熱潮
└── Python, Ruby, Elixir, Julia, Rust, Swift — 每種語言都採用並調整了 LISP 的概念
Enter fullscreen mode
Exit fullscreen mode
儘管它創造了我們幾乎所有正在使用的創新 — 為什麼 LISP 沒有勝出?
Paul Graham(Y Combinator 創辦人、LISP 鐵粉)在散文 “Beating the Averages” 中解釋道:
Graham 堅稱:
“Lisp is a language that was discovered, not invented.”
而 LISP 的批評者(包括曾經在生產環境使用後轉向其他語言的人)指出了 Graham 未提及的額外問題:
總結:沒有單一原因 — 這是語法差異 + 生錯時代 + 社群分裂 + 缺乏企業贊助(與 Sun 全力支持 Java、Microsoft 全力支持 C# 形成對比)的 完美風暴
這篇文章並非要告訴你「你應該去寫 LISP」
但每當你:
numbers = [1, 2, 3]
squared = list(map(lambda x: x * x, numbers))
Enter fullscreen mode
Exit fullscreen mode
const result = data
.filter(x => x.active)
.map(x => x.value);
Enter fullscreen mode
Exit fullscreen mode
let squared: Vec<_> = numbers.iter().map(|x| x * x).collect();
Enter fullscreen mode
Exit fullscreen mode
— 你其實正在不知不覺中撰寫 LISP
📅 2026 年 8 月 | ⚠️ 資料以撰寫當時為準