Common Lisp学习之一:初识CL的语法与语义

Lisp是一类语言的统称,指那些使用前缀表达式和S表达式进行代码编写和编译的语言。此类语言有CL,Scheme,Racket,Clojure等。Lisp语言和其他语言相比,其优势在于无比强大的抽象能力。可以在代码层面上进行抽象,利用Lisp的元编程技术,构造特定领域的DSL,进行自底向上的逐层开发。

CL作为其中发展比较完善和标准化的一个分支,完全可以完成各种大型项目的开发需要。CL的学习资源也比较多。其中比较权威的如下:

ANSI Common Lisp中文翻译  http://acl.readthedocs.org/en/latest/
实用CommonLisp编程的英文版  http://gigamonkeys.com/book/  本书获得了第16届Jolt生产效率奖

本系列的文章主要以实用CommonLisp为主,辅以ANSI CL的部分内容。

Common Lisp定义了两个黑箱,每个黑箱都定义了一个语法层面: 一个将文本转换为Lisp对象(S-表达式),称其为读取器; 另一个将Lisp对象转换转换为Lisp的语义,称此为求值器。

读取器定义字符串如何转换为S表达式,而求值器定义了构建在S表达式之上的Lisp形式的语法。并非所有的S表达式都是合法的Lisp形式,当然并非所有字符序列都是合法的S表达式。

下面先展示一段Lisp代码,定义了求值一个列表中最值的函数,通过它,认识一下CL的样子。
(defun (max-list alist)
  (if (empty? (rest alist))
      (first alist)
      (let ((defun rest-max (max-list (rest alist))))
        (if (> (first alist) rest-max)
            (first alist)
            rest-max))))

(max-list '(1 2 3 4 5)) //5
从这个例子中,直观上看到的是一堆的括号,括号中是一系列的关键字、函数名、变量等。其中每个可匹配的括号内都是一个列表,这也是LISP语言的由来,即LISt Process语言。

1 S-表达式
S-表达式的基本元素是列表和原子。

列表由括号包围,包含任何数量由空格分隔的元素,列表可以为嵌套的。如(1 2 (3 4)) ()均为列表,后者为空列表。

原子是所有其他内容,如数字、字符串和名字。如2、"hello world"和alist

数字支持分数1/2、浮点数、整数、复数等。
字符串由双引号包围,\作为转义字符。因此必须要转义的字符是双引号和\本身。此外诸如括号,引号,冒号等10个标点如果想放在符号里也需要转义,或者用||框起来。
名字可以是变量名、函数名、宏名。

2 符合Lisp形式的S-表达式
原子被分成两类:符号和除符号外其他内容。

符号在作为Lisp形式被求值时被视为一个变量名如例子中的alist,并且会被求值为变量的当前值。
除了符号外而其他的原子,包含数字和字符串,都是自求值的对象。

列表的求值更复杂一些,合法的列表均以一个符号开始,根据符号类型不同分为三种表达式,即函数调用、宏形式和特殊形式。

2.1 函数调用
函数调用形式的求值规则很简单,对以Lisp形式存在的列表其他元素进行求值并将结果传递到命名函数中。这一规则要求列表元素自身必须也是形态良好的Lisp形式。例如示例中的
(max-list '(1 2 3 4 5))

2.2 特殊操作符
由于在函数调用之前,函数参数都必须被求值。对于某些不必要先求值的时刻,使用函数便无法达到目的。因此不能将所有的操作都定义成函数,需要语言提供特殊的符号,即关键字。如IF,quoto等,CommonLisp提供了25个关键字。

2.3 宏
宏提供了Lisp强大的扩展能力。宏接受S-表达式,并输出其转换形式。在编译时,所有的宏会被展开。所以在执行时代码中不包含宏。

3 真、假与等价
NIL是唯一的假值,其余都是真值,T是标准的真值。同时NIL即是原子也是空列表。
相等测试有EQ,EQL,EQUAL和EQUALP,建议不要使用EQ。这几个符号支持的类型趋向于宽松。
EQL只有当两个对象是同一对象时才返回真,而EQUAL只要两个对象打印出来的值相等,就返回真。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值