第 16 章 定义宏的宏.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文档。上传文档
查看更多
第 16 章 定义宏的宏

第 16 章 定义宏的宏 第 16 章 定义宏的宏 代码中的模式通常预⽰着需要新的抽象。这⼀规则对于宏代码本⾝也⼀样适⽤。如 ⼏个宏的定义在形式上⽐较相似,我们就可能写⼀个编写宏的宏来产⽣它们。本章展 ⽰三个宏定义宏的例⼦:⼀个⽤来定义缩略语,另⼀个⽤来定义访问宏,第三个则⽤ 来定义在 14 .1 节中介绍的那种指代宏。 16.1 缩略语 宏最简单的⽤法就是作为缩略语。⼀些 Common Lisp 操作符的名字相当之长。它们中 最典型的 (尽管不是最长的) 是 destructuring-bind ,长达 18 个字符。Steele 原则(4 .3 节) 的⼀个直接推论是,常⽤的操作符应该取个简短的名字。(我们认为加法的成本较 低,部分原因是由于我们只要⽤⼀个字符 + 就可以表⽰它。) 内置的 destructuring- bind 宏引⼊了⼀个新的抽象层,但它在简洁上作出的贡献被它的长名字抹杀了: (let ((a (car x)) (b (cdr x))) ...) (destructuring-bind (a . b) x ...) 和打印出来的⽂本相似,程序在每⾏的字符数不超过 7 的时候,是最容易阅读的。 当单个名字的长度达到这个长度的四分之⼀时,我们就开始觉得不便了。 幸运的是,在像 Lisp 这样的语⾔⾥你完全没有必要逆来顺受设计者的每个决定。只要 定义了: (defmacro dbind (rest args) (destructuring-bind ,@args)) 你就再也不没必要⽤那个长长的名字了。对于名字更长也更常⽤的multiple-value-bind 也是⼀样的道理。 (defmacro mvbind (rest args) (multiple-value-bind ,@args)) 注意到 dbind 和 mvbind 的定义是何等的相似。确实,使⽤这种 rest 和逗号-at 的惯⽤ 法,就已经能为任意⼀个函数 【注1】、宏,或者 special form 定义其缩略语了。 既然我们可以让⼀个宏帮我们代劳,为什么还⽼是照着 mvbind 的模样写出⼀个又⼀ 个的定义呢? 为了定义⼀个定义宏的宏,我们通常会要⽤到嵌套的反引⽤。嵌套反引⽤的难以理解 是出了名的。尽管最终我们会对那些常见的情况了如指掌,但你不能指望随便挑⼀个 反引⽤表达式,都能看⼀眼,就能⽴即说出它可以产⽣什么。这不能归罪于 Lisp 。就 像⼀个复杂的积分,没⼈能看⼀眼就得出积分的结 ,但是我们不能因为这个就把问 题归咎于积分的表⽰⽅法。道理是⼀样的。难点在于问题本⾝,⽽⾮表⽰问题的⽅ 法。 尽管如此,正如在我们在做积分的时候,我们同样也可以把对反引⽤的分析拆成多个 ⼩⼀些的步骤,让每⼀步都可以很容易地完成。假设我们想要写⼀个 abbrev 宏,它允 许我们仅⽤: (abbrev mvbind multiple-value-bind) [⽰例代码 16.1] ⾃动定义缩略语 (defmacro abbrev (short long) (defmacro ,short (rest args) (,,long ,@args))) (defmacro abbrevs (rest names) (progn ,@(mapcar #(lambda (pair) (abbrev ,@pair)) (group names 2)))) 来定义 mvbind 。[⽰例代码 16.1] 给出了⼀个这个宏的定义。它是怎样写出来的呢? 这个宏的定义可以从⼀个⽰例展开式开始。⼀个展开式是: (defmacro mvbind (rest args) (multiple-value-bind ,@args)) 如 我们把 multiple-value-bind 从反引⽤⾥拉出来的话,就会让推导变得更容易些, 因为我们知道它将成为最终要得到的那个宏的参数。这样就得到了等价的定义: (defmacro mvbind (rest args) (let ((name multiple-value-bind)) (,name ,@args))) 现在我们将这个展开式转化成⼀个模板。我们先把反引⽤放在前⾯,然后把可变的表 达式替换成变量。 (defmacro ,short (rest args) (let ((name ,long))

文档评论(0)

精品报告 + 关注
实名认证
文档贡献者

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

1亿VIP精品文档

相关文档