第 15 章 返回函数的宏.pdfVIP

  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  4. 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  5. 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  6. 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  7. 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
第 15 章 返回函数的宏

第 15 章 返回函数的宏 第 15 章 返回函数的宏 第五章已经介绍了如何编写返回函数的函数。宏的应⽤使得组合操作符这项⼯作的 度⼤幅降低。本章将说明如何⽤宏来构造抽象结构,这些结构和第 5 章⾥定义的那些 抽象是等价的,但是⽤宏会更清晰和⾼效。 15.1 函数的构造 若 f 和 g 均为函数,则 f ○g(x) = f(g(x))。 第 5.4 节曾介绍过 把 ○ 实现为 Lisp 函数的⽅法,这个函数名叫 compose: [⽰例代码 15.1] 通⽤的⽤于构造函数的宏 (funcall (compose #list #1+) 2) (3) (defmacro fn (expr) #,(rbuild expr)) (defun rbuild (expr) (if (or (atom expr) (eq (car expr) lambda)) expr (if (eq (car expr) compose) (build compose (cdr expr)) (build call (car expr) (cdr expr))))) (defun build call (op fns) (let ((g (gensym))) (lambda (,g) (,op ,@(mapcar #(lambda (f) (,(rbuild f) ,g)) fns))))) (defun build compose (fns) (let ((g (gensym))) (lambda (,g) ,(labels ((rec (fns) (if fns (,(rbuild (car fns)) ,(rec (cdr fns))) g))) (rec fns))))) 在本节中,我们将思考如何⽤宏来定义更好的函数构造器。[⽰例代码 15.1] 中是⼀个 名为 fn 的通⽤函数构造器,它能够根据复合函数的描述来构造它们。它的参数应该 是⼀个形如(operator . arguments) 的表达式。 operator 可以是⼀个函数或宏的名字,也可以是会被区别对待的 compose .Arguments 可以是接受⼀个参数的函数或宏的名字,或者是可作为 fn 参数的表达 式。例如, (fn (and integerp oddp)) 产⽣⼀个等价于: #(lambda (x) (and (integerp x) (oddp x))) 的函数。 如果把 compose ⽤作操作符(operator) ,我们就得到⼀个所有参数复合后得到的函 数,但不需要像 compose 被定义为函数时那样的显式 funcall 调⽤。例如, (fn (compose list 1+ truncate)) 展开成: #(lambda (#:g1) (list (1+ (truncate #:g1)))) 后者允许对 list 和 1+ 这种简单函数进⾏内联编译。fn 宏接受⼀般意义上的操作符 名称; 表达式也是允许的,就像: (fn (compose (lambda (x) (+ x 3)) truncate)) 可以展开成: #(lambda (#:g2) ((lambda (x) (+ x 3)) (truncate #:g2))) 毫⽆疑问,这⾥由λ–表达式表⽰的函数会被内联编译,要是换成⽤ sharp quoted 的λ–表达式作为参数,传给 compose ,那就只得通过 funcall 调⽤了。 第 5.4 节还展⽰了另外三个函数构造器的定义:fif ,fint ,以及 fun。这些函数 现在被统⼀到了通⽤的 fn 宏。使⽤ and 操作符将产⽣⼀个参数操作符的交集: (mapcar (fn (and integerp oddp)) (c 3 p 0)) (NIL T NIL NIL) ⽽ or 操作符则产⽣并集: (mapcar (fn (or integerp symbolp)) (c 3 p 0.2)) (T T T NIL) 并且 if 产⽣的函数,其函数体是条件执⾏的: (map1 n (fn (if oddp 1+ id

文档评论(0)

hhuiws1482 + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

版权声明书
用户编号:5024214302000003

1亿VIP精品文档

相关文档