0

我一直在尝试为“包装”函数创建一个宏,即,如果我有一个函数可以获取一个列表并将符号 'a 用于第一个元素,它通常被定义为 lambda (l) (cons 'al),但我想要一个宏,它将接受一个函数和一个整数表达式对列表,并通过创建一个新函数来“包装”该函数,该函数接受旧函数的一些参数并根据对获取其余部分,使用整数作为位置和表达式作为值来给函数。像这样的东西:

(wrap list (0 'blah) (2 'bloo) (4 'blee))

应扩展为:

(lambda (a1 a2 . rest)
  (apply list 'blah a1 'bloo a2 'blee rest))

问题是,我不知道如何让宏找到对中整数的值,它只知道它是一个语法对象。我对宏很陌生,这应该很简单,我只是在文档方面遇到了麻烦,除了关于宏的简单教程之外,我在网上找不到任何信息。任何帮助,将不胜感激。

4

1 回答 1

3

这似乎是一个疯狂的宏,特别是当SRFI 26使用起来更加直观时。而不是(wrap list (0 'blah) (2 'bloo) (4 'blee)),您可以使用:

(cut list 'blah <> 'bloo <> 'blee <...>)

这肯定更容易阅读。


如果你真的必须写这样一个宏,这里有一种方法,将 of 的用法转换为 的wrap等价用法cut

(require (for-syntax syntax/parse) srfi/26)
(define-syntax (wrap stx)
  (syntax-parse stx
    ((_ func:expr (idx:nat expr:expr) ...)
     (let* ((alist (map cons
                        (syntax->datum #'(idx ...))
                        (syntax-e #'(expr ...))))
            (upper (add1 (apply max -1 (map car alist))))
            (listfunc (lambda (i)
                        (cond ((assv i alist) => cdr)
                              (else #'<>)))))
       (with-syntax (((args ...) (build-list upper listfunc)))
         #'(cut func args ... <...>))))))

回答你的问题的关键,关于如何在给定语法对象的情况下获取整数,是使用syntax->datum(for deep syntax-stripping) 或syntax-e(for shallow syntax-stripping)。


(PS(致阅读本文的 Racket 专家。)我是新手syntax-parse,所以我相信syntax-parse专家可以找到更好的方法来编写上述内容。我最初将宏编写为syntax-case宏,然后对syntax-parse语法类进行了处理。就是这样。 )

于 2012-11-12T05:23:12.047 回答