schemelispchez-scheme

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


I want to define new syntax. If I define it without a library, just

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

it works as expected, but if I put it in a library:

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

the :times literal stops working. It works if I replace :times with a literal present in an already existing macro, like => or else.

Here's full example in 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)

Solution

  • This seems to work:

    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))
    >
    

    To use a literal (auxiliary keyword) in multiple libraries, define in a library imported by the syntax defining libraries:

    (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
            ...