【问题标题】:unbound variable in racket macro球拍宏中的未绑定变量
【发布时间】:2022-12-18 11:29:39
【问题描述】:

我正在围绕球拍 syntax-case 宏测试包装器宏。在第 1 步,它没有做任何有趣的事情,只是将所有部分直接传递给 syntax-case,如下所示:

#lang racket

;; definition
(define-syntax guarded-syntax-case
  (lambda (x)
      (syntax-case x ()
        ((guarded-syntax-case y (literal ...) clause ...)
         #'(syntax-case y (literal ...) clause ...)
         ))))

;; test case
(define-syntax (binop stx)
  (guarded-syntax-case stx () ; *problem site*
        [(_ op n1 n2) #'(op n1 n2)]))

但是这个简单的案例失败了,在空括号 () 标记为以下错误问题点上面代码中标注:

; ....rkt:11:27: #%app: missing procedure expression;
;  probably originally (), which is an illegal empty application
;   after encountering unbound identifier (which is possibly the real problem):
;    guarded-syntax-case
;   in: (#%app)

我不知道这个简单的传递宏有什么问题。错误消息似乎表明某处有一个未绑定的变量,我无法识别。我认为 literal ... 应该匹配为空。

有人可以帮助解释出了什么问题以及如何修复宏吗?

【问题讨论】:

    标签: macros racket


    【解决方案1】:

    问题是guarded-syntax-case不被识别为宏在正确的阶段.特别是,当你在你的程序中使用(define-syntax guarded-syntax-case ...)时,你定义了阶段0可用的宏guarded-syntax-case。但是(define-syntax (binop stx) ...)中的表单必须在阶段1。

    有两种方法可以纠正错误。

    1. 您可以将(define-syntax guarded-syntax-case ...) 包裹在begin-for-syntax 内。但是,这样做需要 syntax-case 和其他在第 2 阶段可用的东西。所以你需要一个额外的 (require (for-meta 2 racket/base))。这是完整的代码:
      #lang racket
      
      (require (for-meta 2 racket/base))
      
      ;; definition
      (begin-for-syntax
        (define-syntax guarded-syntax-case
          (lambda (x)
            (syntax-case x ()
              ((guarded-syntax-case y (literal ...) clause ...)
               #'(syntax-case y (literal ...) clause ...))))))
      
      ;; test case
      (define-syntax (binop stx)
        (guarded-syntax-case stx () ; *problem site*
                             [(_ op n1 n2) #'(op n1 n2)]))
      
      (binop + 1 2) ;=> 3
      
      1. 或者,您可以定义一个提供guarded-syntax-case 的(子)模块,然后是require 提供for-syntax 的(子)模块。这是完整的代码:
      #lang racket
      
      (module lib racket
        (provide guarded-syntax-case)
        ;; definition
        (define-syntax guarded-syntax-case
          (lambda (x)
            (syntax-case x ()
              ((guarded-syntax-case y (literal ...) clause ...)
               #'(syntax-case y (literal ...) clause ...))))))
      
      (require (for-syntax 'lib))
      
      ;; test case
      (define-syntax (binop stx)
        (guarded-syntax-case stx () ; *problem site*
                             [(_ op n1 n2) #'(op n1 n2)]))
      
      (binop + 1 2)
      

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-09
      • 1970-01-01
      • 1970-01-01
      • 2012-01-07
      相关资源
      最近更新 更多