common lisp的let宏定义如下
(defmacro our-left (binds &body body)
`((lambda ,(mapcar #'(lambda (x)
(if (consp x) (car x) x))
binds)
,@body)
,@(mapcar #'(lambda (x)
(if (consp x) (cadr x) nil))
binds)))
;;;;;;;;;;;;;;;;;;;;;test;;;;
(our-left ((x 1) (y 2))
(+ x y))
展开之后变成
=>((lambda (x y) (+ x y) 1 2)
这里我们不难看出其实let不过是lambda的语法糖:)
scheme的let宏定义如下
(defien-syntax let
(syntax-rules ()
((_ ((x v) ...) e1 e2 ...)
((lambda (x ...) e1 e2 ...) v ...))))
scheme的比上面的那个优雅,直观吧,我们能不费力气的看出这个let内部是如何工作的。
scheme的let*宏如下
(define-syntax my-let*
(syntax-rules ()
((_ ((p v)) b ...)
(let ((p v)) b ...))
((_ ((p1 v1) (p2 v2) ...) b ...)
(let ((p1 v1))
(my-let* ((p2 v2) ...)
b ...)))))
其实scheme的宏是一种模式匹配,所以事先一定要把所有的情况的考虑清楚。
那一堆的使用@来解构真的是没有必要的,看看shceme是如何处理的,根本没有必要先包裹然后解构啊。