12.11 Syntax Utilities
(require racket/syntax) | package: base |
12.11.1 Creating formatted identifiers
procedure
(format-id lctx fmt v ... [ #:source src #:props props #:cert ignored]) → identifier? lctx : (or/c syntax? #f) fmt : string? v : (or/c string? symbol? identifier? keyword? char? number?) src : (or/c syntax? #f) = #f props : (or/c syntax? #f) = #f ignored : (or/c syntax? #f) = #f
The format string must use only ~a placeholders. Identifiers in the argument list are automatically converted to symbols.
> (define-syntax (make-pred stx) (syntax-case stx () [(make-pred name) (format-id #'name "~a?" (syntax-e #'name))]))
> (make-pred pair) #<procedure:pair?>
> (make-pred none-such) none-such?: undefined;
cannot reference undefined identifier
> (define-syntax (better-make-pred stx) (syntax-case stx () [(better-make-pred name) (format-id #'name #:source #'name "~a?" (syntax-e #'name))]))
> (better-make-pred none-such) none-such?: undefined;
cannot reference undefined identifier
(Scribble doesn’t show it, but the DrRacket pinpoints the location of the second error but not of the first.)
procedure
(format-symbol fmt v ...) → symbol?
fmt : string? v : (or/c string? symbol? identifier? keyword? char? number?)
> (format-symbol "make-~a" 'triple) 'make-triple
12.11.2 Pattern variables
syntax
(define/with-syntax pattern stx-expr)
stx-expr : syntax?
> (define/with-syntax (px ...) #'(a b c))
> (define/with-syntax (tmp ...) (generate-temporaries #'(px ...)))
> #'([tmp px] ...) #<syntax:11:0 ((a9 a) (b10 b) (c11 c))>
> (define/with-syntax name #'Alice)
> #'(hello name) #<syntax:13:0 (hello Alice)>
12.11.3 Error reporting
parameter
(current-syntax-context stx) → void? stx : (or/c syntax? false/c)
procedure
(wrong-syntax stx format-string v ...) → any
stx : syntax? format-string : string? v : any/c
> (wrong-syntax #'here "expected ~s" 'there) eval:14:0: ?: expected there
at: here
> (parameterize ([current-syntax-context #'(look over here)]) (wrong-syntax #'here "expected ~s" 'there)) eval:15:0: look: expected there
at: here
in: (look over here)
(define-syntax (my-macro stx) (parameterize ([current-syntax-context stx]) (syntax-case stx () __)))
12.11.4 Recording disappeared uses
parameter
→ (or/c (listof identifier?) false/c) (current-recorded-disappeared-uses ids) → void? ids : (or/c (listof identifier?) false/c)
syntax
(with-disappeared-uses body-expr ... stx-expr)
stx-expr : syntax?
Changed in version 6.5.0.7 of package base: Added the option to include body-exprs.
procedure
(syntax-local-value/record id predicate) → any/c
id : identifier? predicate : (-> any/c boolean?)
procedure
(record-disappeared-uses id) → void?
id : (or/c identifier? (listof identifier?))
If not used within the extent of a with-disappeared-uses form or similar, has no effect.
Changed in version 6.5.0.7 of package base: Added the option to pass a single identifier instead of requiring a list.
12.11.5 Miscellaneous utilities
procedure
(generate-temporary [name-base]) → identifier?
name-base : any/c = 'g
procedure
(internal-definition-context-apply intdef-ctx stx) → syntax? intdef-ctx : internal-definition-context? stx : syntax?
procedure
(syntax-local-eval stx [intdef-ctx]) → any
stx : syntax? intdef-ctx : (or/c internal-definition-context? #f) = #f
> (define-syntax (show-me stx) (syntax-case stx () [(show-me expr) (begin (printf "at compile time produces ~s\n" (syntax-local-eval #'expr)) #'(printf "at run time produces ~s\n" expr))]))
> (show-me (+ 2 5))
at compile time produces 7
at run time produces 7
> (define-for-syntax fruit 'apple)
> (define fruit 'pear)
> (show-me fruit)
at compile time produces apple
at run time produces pear
syntax
(with-syntax* ([pattern stx-expr] ...) body ...+)
stx-expr : syntax?
> (with-syntax* ([(x y) (list #'val1 #'val2)] [nest #'((x) (y))]) #'nest) #<syntax:21:0 ((val1) (val2))>