zoukankan      html  css  js  c++  java
  • 自定义宏

    <实用Common.Lisp编程> 第8章 如何自定义宏
     
    1.宏的展开期和运行期
      理解宏的关键在于必须清楚地知道那些生成代码的代码(宏)和那些最终构成程序的代码(所有其他内容)之间的区别。当编写宏时,你是在编写那些将被编译器用来生成代码并随后编译的程序。只有当所有的宏都被完全展开并且产生的
    代码被编译后,程序才可以实际运行。宏运行的时期被称为宏展开期(macro expansion time),这和运行期(runtime)是不同的,后者是正常的代码(包括那些有宏生成的代码)实际运行的阶段。
      牢记这一区别很重要,因为运行在宏展开期的代码与那些运行在运行期的代码相比,它们的运行环境不同。也就是说,在宏展开期无法访问那些仅存在于运行期的数据。
      当Lisp被解释而非编译时,宏展开期和运行期之间的区别不甚明显,因为它们临时纠缠在了一起。同样,语言标准并未规定解释器处理宏的具体方式——它可能 在被解释的形式中展开所有的宏,然后解释执行那些宏所生成的代码,也可能是直接解释一个形式并在每次遇到宏的时候展开。无论哪种情况,总是还有宏传递那些 代表宏形式的未经求值的Lisp对象,并且宏的作用仍然是生成做某些事情的代码,而非直接做任何事情。
     
    2.编写宏的步骤:
    (1)编写示例的宏调用以及它应当展开成的代码,反之亦然;
    (2)编写示例调用的参数中生成手写展示式的代码;
    (3)确保宏抽象不产生“泄露”。
     
    3.编写宏的注意点
    (1)除非有特殊理由,否则需要将需要展示式中的任何子形式放在一个位置上,使其求值顺序与宏调用的子形式相同。
    (2)除非有特殊理由,否则需要确保子形式仅被求值一次,方法是在展开式中创建变量来持有求值参数形式所得到的值,然后在展开式中所有需要用到该值的地方使用这个变量。
    (3)在宏展开期使用GENSYM来创建展开式中用到的变量名。
     (defmacro with-gensyms ((&rest names) &body body) `(let ,(loop for n in names collect `(,n (gensym)))) ,@body) 自定义宏
  • 相关阅读:
    screen:多重视窗管理程序
    tcpdump、nc网络工具使用
    Linux下查看系统版本号信息的方法
    python列表模拟堆栈和队列
    Linux Service and Security
    day2 列表
    Python常用方法
    Nginx1.6.0+MySQL5.6.19+PHP5.5.14(centos)
    LINUX Mysql5.6.19 安装
    python+django+pycharm 环境配置 (window7)
  • 原文地址:https://www.cnblogs.com/arcticant/p/2964268.html
Copyright © 2011-2022 走看看