黑客终极语言——Lisp1. .
.
黑客终极语言——Lisp
Jerry Peng
2012-12-11
. . . . . .
Jerry Peng () 黑客终极语言——Lisp 2012-12-11 1 / 27
2. Outline
1. 为什么 Lisp 如此特别?
2. Lisp 的本质探寻
3. JVM 上的 Lisp:Clojure
. . . . . .
Jerry Peng () 黑客终极语言——Lisp 2012-12-11 2 / 27
3. Topic
1. 为什么 Lisp 如此特别?
2. Lisp 的本质探寻
3. JVM 上的 Lisp:Clojure
. . . . . .
Jerry Peng () 黑客终极语言——Lisp 2012-12-11 3 / 27
4. 大牛们怎么说 Lisp 的
.
Eric Raymond
.
“Lisp is worth learning for the profound enlightenment experience
you will have when you finally get it; that experience will make you a
better programmer for the rest of your days, even if you never actually
use Lisp itself a lot.”
.
.
Paul Graham
.
“Within a couple weeks of learning Lisp I found programming in any
other language unbearably constraining.”
.
.
Alan Kay
.
“The greatest single programming language ever designed.”
.
. . . . . .
Jerry Peng () 黑客终极语言——Lisp 2012-12-11 4 / 27
5. 个人的体验(1)
曾经对 Lisp 几乎一无所知
只听闻它可读性很不好,到处都是括号
读《黑客与画家》后,开始有所了解并决定学习
以 Common Lisp 开始 Lisp 学习之路
《Practical Common Lisp》
对 Lisp 独特之处有所体会
因为种种原因没能持续
. . . . . .
Jerry Peng () 黑客终极语言——Lisp 2012-12-11 5 / 27
6. 个人的体验(2)
从 Clojure 开始一发不可收拾
很短的时间就上手了
熟悉 Lisp 就是熟悉了所有的 Lisp 方言
更好、更实用的现代 Lisp 方言
已经在项目中实际使用
Emacs Lisp
因为 Clojure 而开始用 Emacs
不可避免地要 Hack 一下 Emacs Lisp :-)
SICP 和 Scheme 学习中
为什么没能在编程入门阶段阅读到它?
. . . . . .
Jerry Peng () 黑客终极语言——Lisp 2012-12-11 6 / 27
8. Topic
1. 为什么 Lisp 如此特别?
2. Lisp 的本质探寻
3. JVM 上的 Lisp:Clojure
. . . . . .
Jerry Peng () 黑客终极语言——Lisp 2012-12-11 8 / 27
9. Hello World?
(defun say_hello (name)
(format t "Hello, ~a~%" name))
(say_hello "the wonderful Lisp world")
. . . . . .
Jerry Peng () 黑客终极语言——Lisp 2012-12-11 9 / 27
10. 括号!括号!
Lisp is …
Lost In Stupid Parentheses
Lots of Irritating Superfluous Parentheses
.
List Cycles
.
.
. . . . . .
Jerry Peng () 黑客终极语言——Lisp 2012-12-11 10 / 27
11. S-expression
其实括号才是 Lisp 霸气外露的体现!
Lisp 代码的这种括号套括号的表达法被称作 S-expression
Lisp 被发明时,还有个 M-expression 的表达方式
但 M-expression 不受欢迎,被 S-expression 取代
S-expression 本质上是任意树形结构的一个表达法
让我们先 hold 一会
记住 Lisp 代码就是一棵用 S-expression 表达的树
. . . . . .
Jerry Peng () 黑客终极语言——Lisp 2012-12-11 11 / 27
12. 其他语言怎么做的
具备某种特定语法
往往区分 Expression 和 Statement
词法分析 -> 语法分析 -> AST -> 编译/解释
. . . . . .
Jerry Peng () 黑客终极语言——Lisp 2012-12-11 12 / 27
13. Grammer == Restrictions
必须在语法框架下去写程序
无法跳出语法限制下的条条框框
.
在 C 或者 Java 里永远写不出这样的程序
.
printf("Result is %s", switch (input) {
case 1: "A"; break;
case 2: "B"; break;
case 3: "C"; break;
default: "Unknown";
. })
. . . . . .
Jerry Peng () 黑客终极语言——Lisp 2012-12-11 13 / 27
14. Lisp == No Grammer
Lisp 没有语法
Lisp 代码只是用 S-expression 表达出来树形结构
Lisp 求值规则决定了 S-expression 的语义
换言之,Lisp 代码其实就是其他语言的 AST
.
没有语法 == 没有限制
.
(format t "Result is ~a~%" (case input
(1 "A")
(2 "B")
(3 "C")
. (otherwise "Unknown")))
. . . . . .
Jerry Peng () 黑客终极语言——Lisp 2012-12-11 14 / 27
15. Lisp 求值规则(1)
先提出几个概念
atom:原子
symbol 类似其他语言的”变量“
:keyword Intern 过的字符串
“string” 字符串
42 数字
form:可被 Lisp 解释器解释的合法 S-expression
第一个元素必须是 symbol
. . . . . .
Jerry Peng () 黑客终极语言——Lisp 2012-12-11 15 / 27
16. Lisp 求值规则(2)
atom 求值规则
symbol 求值得到 symbol 上绑定的值
其他 atom 求值得到本身
form 求值规则
根据 form 的第一个 symbol 决定语义
. . . . . .
Jerry Peng () 黑客终极语言——Lisp 2012-12-11 16 / 27
17. form 的第一个 symbol 决定了 form 的语义:
symbol 对应一个函数:函数调用
要先将函数所有的参数求值出来才能调用函数
symbol 对应一个 special form
根据 special form 来决定语义,且子 form 代表的含义是固定的
symbol 对应一个宏
调用宏函数来展开宏
这一步一般发生在编译阶段,到运行时所有的宏都应该被完全
展开了
. . . . . .
Jerry Peng () 黑客终极语言——Lisp 2012-12-11 17 / 27
18. 以上就是 Lisp 的所有求值规则
短短几句话就可以总结 Lisp 的运行规则
Lisp 的核心只有 7、8 个核心原语操作
其他的函数、special form 都在此之上实现
if,while,for,case,defun 等等…
这些意味着什么?
. . . . . .
Jerry Peng () 黑客终极语言——Lisp 2012-12-11 18 / 27
19. Lisp 是最高级的语言
用户可以任意定义自己需要的语言功能
if-not,for-even,defprivate…
终极 DSL
直接通过扩展语言来以最自然的方式来表达问题域的概念
通过宏来实现
和 C/C++ 里的宏完全是两个概念
C/C++ 里的宏是简单的字符串替换
Lisp 的宏是以 Lisp 代码为输入/输出的函数
Lisp 语言在任何阶段都是可用的
Read -> Compile -> Eval
Reader Macro
Macro
. . . . . .
Jerry Peng () 黑客终极语言——Lisp 2012-12-11 19 / 27
20. 示例——clojure-control
(defcluster :mycluster
:clients [{:host "a.domain.com" :user "alogin"}
{:host "b.domain.com" :user "blogin"}])
(deftask :deploy "scp files to remote machines"
[file1 file2]
(scp [file1 file2] "/home/alogin/")
(ssh (str "tar zxvf " file1))
(ssh (str "tar zxvf " file2)))
; control run CLUSTER TASK <args>
. . . . . .
Jerry Peng () 黑客终极语言——Lisp 2012-12-11 20 / 27
21. 示例——clojure.java.jdbc
(def mysql-db {:subprotocol "mysql"
:subname "//127.0.0.1:3306/clojure_test"
:user "clojure_test"
:password "clojure_test"})
(sql/with-connection mysql-db
(sql/insert-records :fruit
{:name "Apple" :appearance "rosy" :cost 24}
{:name "Orange" :appearance "round" :cost 49}))
. . . . . .
Jerry Peng () 黑客终极语言——Lisp 2012-12-11 21 / 27
22. 示例——clojure web 开发
(defpage [:post "/"] {:keys [url]}
(layout
[:h3 "Here is your shortened URL"]
[:h3 (short-url-link (shorten-url! url))]
[:p (link-to "/" "Back")]))
. . . . . .
Jerry Peng () 黑客终极语言——Lisp 2012-12-11 22 / 27
23. 个人实践——clj.tr069
(deftr069type Inform
(device-id :child :DeviceId)
(events :child-array :Event
:EventStruct)
(parameter-list :child-array :ParameterList
:ParameterValueStruct)
(retry-count :int :RetryCount)
(current-time :dateTime :CurrentTime)
(max-envelopes :int :MaxEnvelopes))
. . . . . .
Jerry Peng () 黑客终极语言——Lisp 2012-12-11 23 / 27
24. Topic
1. 为什么 Lisp 如此特别?
2. Lisp 的本质探寻
3. JVM 上的 Lisp:Clojure
. . . . . .
Jerry Peng () 黑客终极语言——Lisp 2012-12-11 24 / 27
25. Lisp Reloaded
100% 的 Lisp
REPL 支持
强大的宏
更现代
支持 vector 和 map 的字面量
括号尽可能少
平台更强大——JVM/CLR
性能强大、工业标准
高质量的库支持
无缝的 Java 互操作
ClojureScript,Clojure-Py
. . . . . .
Jerry Peng () 黑客终极语言——Lisp 2012-12-11 25 / 27
26. More Functional
强调不可变性(Immutability)
性能优秀的 Persistent Data Structure
做到 immutable 的同时兼顾性能
强大的 sequence 支持
类似 Python 的 iterator,但更强大
Laziness
Lazy sequences
大量的基本操作都是 lazy 的
自由使用函数式编程风格又无需担心性能
. . . . . .
Jerry Peng () 黑客终极语言——Lisp 2012-12-11 26 / 27
27. Born for Concurrency
简单的原子操作支持(atoms)
软件事务内存(STM,refs)
异步编程(agents)
. . . . . .
Jerry Peng () 黑客终极语言——Lisp 2012-12-11 27 / 27