-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathappendix.scrbl
More file actions
50 lines (31 loc) · 2.76 KB
/
appendix.scrbl
File metadata and controls
50 lines (31 loc) · 2.76 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#lang scribble/manual
@(require "util.rkt")
@title{Appendix}
我写这些文章的目的, 不是为了教授Racket. 如果你像掌握Racket语言, 可以参考官方的@hyperlink["#" "导引"]和@hyperlink["#" "参考"]. 另外,
Racket团队出版了许多书籍, 比如@hyperlink["#"]{@italic{How to Design Programs}}和@hyperlink["#"]{@italic{Beautiful Racket}}.
不幸的是, 这些文章全都是英文的. 中文的Racket资料(或者说, Lisp资料)凤毛麟角, 只有一些零散的专栏和博文. 我的目的部分是为了弥补这个.
另一方面, 我更希望传播函数式和元编程的知识. 现代人大多浸淫于过程式和面向对象. 并不是这些范式不好, 但因为它们而忽略了程序世界的另一面未免有些可惜.
Scheme是这两者编程方式的结晶, 并且被设计得适合学习; Racket则将Scheme发扬光大, 加入了多范式的理念和实用的库.
那么, 学习这些方式的意义是什么? 如果指的是工作和进学的话, 可以说, 是@bold{完全没有}意义的. 据我估计, 国内使用Racket的公司是一家也没有; 就算有使用
CL和Clojure的, 也可以用一只手数得过来. 但切莫以为这意味着语言的无用. 北美和欧洲有许多公司(比如波音公司)使用Lisp. 它还曾经垄断人工智能的研究. 许多著名人物, 包括
保罗 格雷厄姆, 埃里克 雷蒙德乃至马修 斯托曼都是Lisp程序员. 并且, 前已述及, 我用的文档生成工具就是用Racket写的.
既然Lisp很强大, 为什么很少有人使用它? 一个原因是, Lisp过于抽象(Abstract)了. 它的S-表达式和一般语言中与数学类似的运算符及函数调用语法截然不同.
但这恰恰是Lisp触及了程序语言的本质的体现. 如果你学过编译原理的话, 你应该知道编译器前端的任务是将线性的字符流转化为嵌套的语法树, 比如Python代码
@codeblock{
if a:
b
else:
c
}
会被编译器转化为这个样子:
If(
test=Name(id='a'),
body=[Expr(value=Name(id='b'))],
orelse=[Expr(value=Name(id='c'))]
)
而在Lisp中, 我们不需要进行这个转化, 因为S-表达式本身就是嵌套的!
这样, 我们就脱出了句法结构的限制, 实现了语法和语义的解耦. 我们可以任意修改, 组装程序. 宏做的就是这样的事情.
这个概念后来被标记语言(Markup Language)重新发明了. 在xml中, 你可以这么表示语法树:
@racketmodfile["syntax-tree.xml"]
很冗长, 不是吗? 这也是它被JSON打败的原因. 而Lisp的S-表达式时人类想出来的表示树形结构的最简单的通用语法. 它允许你以最强大, 最灵活, 最深入的方法编程.
它对"现实世界"没什么帮助, 但能加深你对程序设计这一行为本身的理解-当然, 也充满趣味.