ANSI Common Lisp译本笔记8

来源:互联网 发布:淘宝首页怎么加载数据 编辑:程序博客网 时间:2024/06/05 06:06


求值

eval:接收一个表达式,将其求值并返回。


eval缺点:
1.效率低,eval处理的是原始列表,要不当下编译它,或用直译器求值。这两种方法都比执行编译过来的代码慢。
2.表达式在没有词法语境的情况下被求值。如:在let中调用eval,传给eval的表达式无法参照由let设置的变量。

eval主要的作用是作为lisp的概念模型。

函数coerce和compile可将列表转成代码。
如:传给coerce一个lamda表达式,将其成为函数。

宏是通过转换而实现的操作符。
通过说明一个调用应该要翻译成什么,来定义一个宏,这种翻译称为宏展开。宏展开是编译器自动完成的。

defmacro:定义一个宏
格式:defmacro 宏名称 应用到展开式的参数列表 宏主体(展开式)
如:(defmacro nil! (x)

(list 'setf x nil))


macroexpand:用于展开宏,返回一个宏展开式


反引号

反引号读取宏,使从模板构建列表成为可能。
反引号为键盘1的左边的键位 ` 。且为半角输入,即英文输入状态。

单引号可保护其参数不被求值。
反引号的优点:在一个反引号表达式中,可用逗号(,)和@来重启求值。即:在一个反引号表达式中,在一个符号前加逗号的话,则此符号会被求值。@和逗号类似,若在符号前加,且此符号为列表时,则会将列表展开
如:逗号例子:
(setf a 1 b 2)
`(a is ,a and b is ,b)→(A IS 1 AND B IS 2)

@例子:
(setf lst '(a b c))
`(lst is ,lst)→(LST IS (A B C))

`(lst's elements are ,@lst)→(LST'S ELEMENTS ARE A B C)


一般,一个宏一般用剩余参数表示代码主体的宏。
如:
(defmacro while (test &rest body)
  `(do ()

((not ,test))


原创粉丝点击