您的位置:首页 > 其它

ANSI Common Lisp译本笔记8

2017-10-12 14:00 190 查看



求值

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))
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: