语法规则中的文字在 Scheme 的库中不起作用

Literals in syntax-rules don't work in libraries in Scheme

我想定义新语法。如果我在没有库的情况下定义它,只需

(define-syntax sample1
  (syntax-rules (:times)
    [(_ n :times body ...)
     (list n (sample1 body ...))]
    [(c body ...)
     '(body ...)]))

它按预期工作,但如果我将它放入库中:

(library (alib)
  (export sample2)
  (import
    (rnrs))
  (define-syntax sample2
    (syntax-rules (:times)
      [(_ n :times body ...)
       (list n (sample2 body ...))]
      [(c body ...)
       '(body ...)])))

:times 文字停止工作。如果我将 :times 替换为现有宏中存在的文字,如 =>else.

,它会起作用

这是 Chez 中的完整示例:

(define-syntax sample1
    (syntax-rules (:times)
      [(_ n :times body ...)      
       (list n (sample1 body ...))]
      [(c body ...)
       '(body ...)]))
(sample1 a b c d)
;; => (a b c d)

(sample1 10 :times a b c d)
;; => (10 (a b c d))

(library (alib)      
    (export sample2)
    (import 
      (rnrs))
    (define-syntax sample2
      (syntax-rules (:times)
        [(_ n :times body ...)      
         (list n (sample2 body ...))]
        [(c body ...)
         '(body ...)])))
(import (alib))
(sample2 10 :times a b c d)
;; => (10 :times a b c d)

这似乎有效:

Chez Scheme Version 9.5.7.6

> (library (alib)      
      (export sample2 :times)
      (import 
        (rnrs))
      (define :times #f)
      (define-syntax sample2
        (syntax-rules (:times)
          [(_ n :times body ...)      
           (list n (sample2 body ...))]
          [(_ body ...)
           '(body ...)])))
> (import (alib))
> (sample2 10 :times a b c d)
(10 (a b c d))
>

要在多个库中使用文字(辅助关键字),请在语法定义库导入的库中定义:

(library (literals)
  (export :times)
  (import (rnrs))
  (define :times #f))

(library (alib)      
      (export sample1 :times)
      (import (rnrs) (literals))
      (define-syntax sample1
        ...
(library (blib)      
      (export sample2 :times)
      (import (rnrs) (literals))
      (define-syntax sample2
        ...

您可以使用 fender 表达式来替代辅助关键字。

(library (alib)
  (export sample2)
  (import
   (chezscheme)) ;; <= required for syntax-rules fenders
  (define-syntax sample2
    (syntax-rules ()
      [(_ n :times body ...)
       (eq? (datum :times) ':times) ;; <= fender
       (list n (sample2 body ...))]
      [(c body ...)
       '(body ...)])))
(import (alib))
(sample2 10 :times a b c d) ;; => (10 (a b c d))

定义一个keyword?宏来使挡泥板更干净。

(library (meta)
  (export keyword?)
  (import (chezscheme))
  (define-syntax keyword?
    (syntax-rules ()
      [(_ x) (eq? (datum x) 'x)])))

(library (alib)
  (export sample2)
  (import (meta) (chezscheme))
  (define-syntax sample2
    (syntax-rules ()
      [(_ n :times body ...)
       (keyword? :times)
       (list n (sample2 body ...))]
      [(c body ...)
       '(body ...)])))
(import (alib))
(sample2 10 :times a b c d) ;; => (10 (a b c d))