首页 文章

在Racket中使用语法参数

提问于
浏览
3

我正在尝试定义一个生成匿名函数的宏,它使用一个名为it的参数,以简洁,以便代替

(λ (it) body)
我可以写
(λλ body)

(换句话说, (λλ body) 转换为 (λ (it) body)

(define-syntax-parameter it #f)
(define-syntax λλ
  (syntax-rules ()
    ((_ body)
     (λ (x) (syntax-parameterize ((it x)) body)))))
(λλ (< it 0)) ; For testing

我在 (define-syntax-parameter if #f) 得到 operators.rkt:13:28: ?: literal data is not allowed; no #%datum syntax transformer is bound in the transformer environment in: #f ,但据我所知,这与球拍的doc中给出的如何使用 define-syntax-parameter 的示例完全相同 . 我可以通过用函数替换 #f 来抑制错误(我使用 member ,但不是出于任何真正的原因),但在这之后,我得到 operators.rkt:17:38: x: identifier used out of context in: x . 我究竟做错了什么?

2 回答

  • -1

    你遗漏了example中的 syntax-id-rules 部分 . 它是指定 it 应扩展为 x 的部分 . 或者,您可以使用make-rename-transformer

    #lang racket
    (require racket/stxparam)
    
    (define-syntax-parameter it #f)
    (define-syntax λλ
      (syntax-rules ()
        ((_ body)
         (λ (x) (syntax-parameterize ([it (make-rename-transformer #'x)]) body)))))
    ((λλ (< it 0)) 5)
    ((λλ (< it 0)) -5)
    

    =>

    #f
    #t
    
  • 4

    语法参数不是实现您想到的宏的唯一方法 . 更简单(IMO)的方法是使用 datum->syntax 来注入标识符 it

    (define-syntax (λλ stx)
      (syntax-case stx ()
        ((_ body ...)
         (with-syntax ((it (datum->syntax stx 'it)))
           #'(λ (it) body ...)))))
    

    要使用您的示例:

    (define my-negative? (λλ (< it 0)))
    (my-negative? -1)   ;; => #t
    

相关问题