在Racket中使用语法参数

时间:2013-09-19 16:47:29

标签: macros racket

我正在尝试定义一个生成匿名函数的宏,该函数使用一个名为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

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

2 个答案:

答案 0 :(得分:4)

您遗漏了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)

=&GT;

#f
#t

答案 1 :(得分:-1)

语法参数不是实现您想到的宏的唯一方法。更简单(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