Syntax-case, require, file

Why

(define-syntax (require-file stx)
  (syntax-case stx ()
    [(_ x)
     #'(require (file x))]))

doesn't work (it compiles, but doesn't import identifiers)?

(define-syntax (require-file* stx)
  (syntax-case stx ()
    [(_ x)
      #`(require #,(datum->syntax #'x (list #'file #'x)))]))

works fine.

2 Likes

Hygienic expansion. When a macro defines identifiers (like via require), the expander scopes them to the macro’s generated code — unless the programmer explicitly dictates the macro system that the identifiers should be scoped to the use of the macro.

3 Likes

unless the programmer explicitly dictates the macro system that the identifiers should be scoped to the use of the macro

Thank you! Now I understand, why first version wrong (correct one should be wrapped into syntax-local-introduce).
But now I don't understand, why second version defines identifiers outside the macro. How I "explicitly dictated the macro system that the identifiers should be scoped to the use of the macro"?

1 Like

The question is which context the imported identifiers get.

The documentation for require, states that in (require module-path):

This explains why your second version worked - you changed the context of the module path.

2 Likes

datum->syntax transfers scope context to the file spec in the require, and since you chose a part of the macro’s INPUT from which to transfer scope information, the imported identifiers get the scope of where the x comes from.