6.3 Certifying References in Static Information
Synopsis: Certify identifiers stored in static information to avoid reference from uncertified context errors.
Examples: define-struct and match; other examples from Static Information
Unresolved pattern tag: "static-info-store-certifier"
When static info contains identifiers that are intended to be used as references to other bindings, the identifiers should be certified using a certifier for the module where the static information binding occurs.
References to a module’s private (not provided) members occurring outside of that module must be certified; otherwise, it raises an “uncertified context” error. Ordinary macros can expand into code referring to provide members because macros automatically certify their results – the certification is handled by the macro system; macro writers don’t have to worry about it. References extracted from static info, however, are not automatically certified; they must be certified by hand.
Identifiers are certified using a certifier obtained by calling the syntax-local-certifier procedure.
6.3.1 Example 1
(module a scheme |
(provide access-point) |
(define private-variable 'the-secret) |
(define-syntax access-point |
#'private-variable)) |
(module b scheme |
(require 'a) |
(provide client) |
(define-syntax (client stx) |
(syntax-local-value #'access-point)) |
(client)) |
The client macro uses syntax-local-value to obtain an uncertified identifier that refers to a private member of a module. It produces the uncertified reference in another module, and the macro expander signals an error, preventing the access.
(module a scheme |
(provide access-point) |
(define private-variable 'the-secret) |
(define-syntax access-point |
((syntax-local-certifier) #'private-variable))) |
(module b scheme |
(require 'a) |
(provide client) |
(define-syntax (client stx) |
(syntax-local-value #'access-point)) |
(client)) |
Beware: Uncertified access errors tend crop up only when code gets sufficiently complicated. In particular, such errors often first appear when a small prototype system is separated into multiple modules. For example, if the client macro above were moved into the first module, there would be no access error even if the certification step were removed. The reason is that the client macro’s automatic certifier would permit the access to private-variable because it is defined in the same module as the macro – even though the manner that client acquired the identifier is potentially unsafe.
Only simple syntax constants (usually identifiers) should have a certifier pre-applied. If the static information contains procedures that act as special-purpose transformers (see Unresolved pattern tag: "pseudo-macros"), the certifier should be retained as part of the static information. The Unresolved pattern tag: "static-info-store-certifier" section elaborates.