Wednesday, September 6, 2017

What made lisp different?

Paul Graham 的文章 Waht made lisp different 真的好難懂。不過,我最近也寫過了 Clojure 的 macro ,疑似有理解一些了。

The whole language always available. There is no real distinction between read-time, compile-time, and runtime. You can compile or run code while reading, read or run code while compiling, and read or compile code at runtime.

這一段舉了四個例子來說明:
1. Running code at read-time lets user reprogram Lisp's syntax.
這是在講 Read macro 。
Common Lisp 的 read macro 是 reader 的 plugin ,可以註冊在 reader 裡。 而 Clojure 的話,內建了許多 read macro,但是不開放『自訂 read macro 』的功能。

2. Running code at compile-time is the basis of macros.
macro 可以視為是 compiler 的 plugin 。 在 Clojure 的例子是用 defmacro 。

3. Compiling at runtime is the basis of Lisp's use as an extension language in program like Emacs.
在 Clojure 的例子,使用 clojure.core/load , clojure.core/require 可以在執行期間啟動 compiler 。在 Riemann monitoring system 裡,就是利用 clojure.core/load 來讓 clojure 作為 Riemann 本身的 extension language 。而類似的 monitoring system 比方說像 Kapacitor 的話,則是還要特別定義一個專用的 extension language 。

4. Reading at runtime enables programs to communicate using s-expressions, an idea recently reinvented as XML.
在 Clojure 的例子,最接近的函數應該是 clojure.edn/read ,因為可以用於 untrusted source 。在 javascript 則是 JSON.parse() 。現代 web application 的前後端溝通所使用的 json 格式,也可以視為是一種 reading at runtime 特性的應用。