首页 文章

使用语法列表作为函数的形式参数

提问于
浏览
2

这是场景:给定 [sym ...] 形式的模式(例如 [a b][a b c d] )我想生成(使用宏)函数来连接模式中的符号,但也提供它们作为参数 . 例如, [a b] 转换为某种形式

(define (ab a b) 
  body)

this post,有人通过名为 signal-list 的语法类帮助我生成函数的名称 . 在下面的代码中,我可以将 signals 模式变量与 (sig ...) 形式的模式匹配,然后我可以使用它来生成所需的函数定义 .

(define-syntax (define-something stx)
  (syntax-parse stx
    [(_ (signals:signal-list body ...))
     (syntax-parse #'signals
       [(sig ...)
        #'(define (signals.concatenated-ids sig ...)
               body ...)])]))

与此宏匹配的示例:

(define-something
  ([a b] 'body))

扩展到 (define (ab a b) 'body)

但是,如果我想生成多个函数定义,宏如何工作?例如:

(define-something
  ([a b] 'body)
  ([c d e] 'body))
=>
(begin (define (ab a b) 'body)
       (define (cde c d e) 'body))

我可以在第一个语法分析的模式中添加省略号:

(_ (signals:signal-list body ...) ...)

但是我不能使用第二个语法分析来匹配 signals ,因为它需要省略号 . 是否有一种不同的方式'de-construct' signals 以便我可以将其内容用作函数的形式参数,这与使用省略号兼容?

1 回答

  • 2

    要直接回答您的问题,您可以将 #'(signals ...) (代替现有的 #'signals )传递给内部 syntax-parse 调用 .


    作为一个概念证明,我写了一个宏的 syntax-case 版本(因为我还不知道 syntax-parse ) . 您应该能够轻松地使用相同的技术来适应 syntax-parse

    (define-syntax (define-something outerstx)
      (define (make-name paramstx)
        (datum->syntax outerstx
                       (string->symbol
                        (apply string-append
                               (map symbol->string (syntax->datum paramstx))))))
    
      (define (make-names innerstx)
        (syntax-case innerstx ()
          (()
           #'())
          (((param ...) rest ...)
           (with-syntax ((name (make-name #'(param ...)))
                         ((next ...) (make-names #'(rest ...))))
             #'(name next ...)))))
    
      (syntax-case outerstx ()
        ((_ ((param ...) body ...)
            ...)
         (with-syntax (((name ...) (make-names #'((param ...) ...))))
           #'(define-values (name ...)
               (values (lambda (param ...)
                         body ...)
                       ...))))))
    

相关问题