on-lisp要点-----宏(二)

一、宏的引入

1.什么时候需要宏,宏可以做什么

优秀设计的一个通用原则就是:当你发现在程序中的几处都出现了相似的代码时,就应该写一个子例程,并把那些相似的语句换成对这个子例程的调用,lisp中可以使用宏,为我们创建上下文环境,或者利用宏,直接在上下文中计算。

宏可以控制 (或阻止) 对其参数的求值,并且它可以展开进入到主调方的上下文中。

宏的处理主要分为两步,宏展开(构造表达式)求值(对展开的表达式求值)

二、宏的分类

1.创建上下文

(defmacro with-gensyms (syms &body body)
  `(let ,(mapcar #'(lambda (sym) `(,sym (gensym)))
		 syms)
     ,@body))

前面约束系统中一些有用的创建上下文的宏,这些宏都极大简化了程序的编写

(defun as-keyword (sym) (intern (string sym) :keyword))
(defmacro defineclass (name slots)
  `(defclass ,name ()
     ,(loop for slot in slots collect
	   (if (consp slot)
	       (let ((sname (first slot)) (value (second slot)))
		 `(,sname :initform ,value :initarg ,(as-keyword sname)
			  :accessor ,sname))
	       `(,slot :initarg ,(as-keyword slot) :accessor ,slot)))))

(defmacro declare-connectors (&rest connectors)
  `(progn 
     ,@(loop for c in connectors collect
	    `(defvar ,c (make-connector)))))
(defmacro declare-probes (&rest connectors)
  `(progn
     ,@(loop for c in connectors collect
	    `(probe (string ',c) ,c))))

自动递归中定义了一个递归宏,当n个人分别要从n个choice中选取一个,如果每次都写代码,则很麻烦。

(defmacro var-choose-choices (choices (&rest choosers) &rest body)
  (if (null choosers) 
       `(progn ,@body)
       `(choose-bind ,(car choosers) ,choices
	  (var-choose-choices ,choices ,(cdr choosers) ,@body))))




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值