首页 > 解决方案 > (Chez) 隐藏 lambda 的 Scheme 宏

问题描述

我想编写一个宏来创建用于隐藏更冗长的 lambda 表达式的速记语法,但我很难理解如何编写宏(我意识到这是反对使用它们的论据)。

给定这个例子:

(define alist-example
  '((x 1 2 3) (y 4 5 6) (z 7 8 9)))

(define ($ alist name)
  (cdr (assoc name alist)))

((lambda (a) (map (lambda (x y z) (+ x y z)) ($ a 'x) ($ a 'y) ($ a 'z))) alist-example)
((lambda (a) (map (lambda (y) (/ y (apply max ($ a 'y)))) ($ a 'y))) alist-example)

我想写一个宏,with-alist,它可以让我写出最后两个类似的表达式:

(with-alist alist-example (+ x y z))
(with-alist alist-example (/ y (apply max y)))

有什么意见或建议吗?

标签: macrosschemeassociative-arraychez-scheme

解决方案


我看到的直接问题是没有办法知道选择哪些绑定。例如。是applyalist 中的元素之一还是全局变量?那要看。我建议你这样做:

(with-alist ((x y z) '((x 1 2 3) (y 4 5 6) (z 7 8 9)))
  (+ x y z))

(let ((z 10))
  (with-alist ((x y) alist-example)
    (+ x y z)))

它应该转化为:

(let ((tmp '((x 1 2 3) (y 4 5 6) (z 7 8 9))))
  (apply map (lambda (x y z) (+ x y z))
         (map (lambda (name) ($ tmp name)) '(x y z))))

(let ((z 10))
  (let ((tmp alist-example))
    (apply map (lambda (x y) (+ x y z))
           (map (lambda (name) ($ tmp name)) '(x y)))))

这就是直截了当的处理syntax-rules。例如。制作一个图案并写下替换。祝你好运。


推荐阅读