(Chez)隐藏Lambda的Scheme宏 [英] (Chez) Scheme macro for hiding lambdas

查看:98
本文介绍了(Chez)隐藏Lambda的Scheme宏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想编写一个宏来创建用于隐藏更多冗长的lambda表达式的速记语法,但我一直在努力了解如何编写宏(我意识到这是反对使用它们的一个论点).

I would like to write a macro to create shorthand syntax for hiding more verbose lambda expressions, but I'm struggling to understand how to write macros (which I realize is an argument against using them).

给出以下示例:

(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,它使我可以编写类似于以下内容的最后两个表达式:

I would like to write a macro, with-alist, that would allow me to write the last two expressions similar to this:

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

有什么建议或建议吗?

推荐答案

以下是基于我在其他答案和评论中收到的反馈的syntax-rules解决方案:

Here is a syntax-rules solution based on the feedback that I received in the other answer and comments:

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

(define-syntax with-alist
  (syntax-rules ()
    [(_ alist names expr)
     (let ([alist-local alist])
       (apply map (lambda names expr)
              (map (lambda (name) ($ alist-local name)) (quote names))))]))

以下是一些用法示例:

> (define alist-example
  '((x 1 2 3) (y 4 5 6) (z 7 8 9)))
> (with-alist alist-example (x) (+ x 2))
(3 4 5)
> (with-alist alist-example (x y) (+ x y))
(5 7 9)
> (with-alist alist-example (x y z) (+ x y z))          
(12 15 18)

这个答案没有解决我的问题中更复杂的示例(with-alist alist-example (/ y (apply max y))),但是我认为这对我来说是一种合理的方法:

This answer stops short of solving the more complicated example, (with-alist alist-example (/ y (apply max y))), in my question, but I think this is a reasonable approach for my purposes:

> (with-alist alist-example (y) (/ y (apply max ($ alist-example 'y))))
(2/3 5/6 1)

经过一些额外的修改后,我得出了一个稍微不同的解决方案,我认为它将提供更大的灵活性.

After some additional tinkering, I arrived at a slightly different solution that I think will provide more flexibility.

我的新宏npl将速写表达式扩展为名称和过程列表.

My new macro, npl, expands shorthand expressions into a list of names and procedures.

(define-syntax npl
  (syntax-rules ()
    [(_ (names expr) ...)
     (list 
      (list (quote names) ...)
      (list (lambda names expr) ...))]))

此宏的输出传递到常规过程with-list-map,该过程包含上面with-alist宏中的大多数核心功能.

The output of this macro is passed to a regular procedure, with-list-map, that contains most the core functionality in the with-alist macro above.

(define (with-alist-map alist names-proc-list)
  (let ([names-list (car names-proc-list)]
        [proc-list (cadr names-proc-list)])
    (map (lambda (names proc)
           (apply map proc
                  (map (lambda (name) ($ alist name)) names)))
         names-list proc-list)))

上面的with-alist用法的3个示例可以在一次调用with-alist-map的情况下捕获.

The 3 examples of with-alist usage above can be captured in a single call to with-alist-map.

> (with-alist-map alist-example
                (npl ((x) (+ x 2))
                     ((x y) (+ x y))
                     ((x y z) (+ x y z))))
((3 4 5) (5 7 9) (12 15 18))

这篇关于(Chez)隐藏Lambda的Scheme宏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆