12.12 Syntax Utilities

► |  | The Racket Reference

1 | Language Model
2 | Notation for Documentation
3 | Syntactic Forms
4 | Datatypes
5 | Structures
6 | Classes and Objects
7 | Units
8 | Contracts
9 | Pattern Matching
10 | Control Flow
11 | Concurrency and Parallelism
12 | Macros
13 | Input and Output
14 | Reflection and Security
15 | Operating System
16 | Memory Management
17 | Unsafe Operations
18 | Running Racket
| Bibliography
| Index

▼ | 12 | Macros

12.1 | Pattern-Based Syntax Matching
12.2 | Syntax Object Content
12.3 | Syntax Object Bindings
12.4 | Syntax Transformers
12.5 | Syntax Parameters
12.6 | Local Binding with Splicing Body
12.7 | Syntax Object Properties
12.8 | Syntax Taints
12.9 | Expanding Top-Level Forms
12.10 | Serializing Syntax
12.11 | File Inclusion
12.12 | Syntax Utilities
12.13 | Phase and Space Utilities

► | 12.12 | Syntax Utilities

12.12.1 | Creating formatted identifiers
12.12.2 | Pattern variables
12.12.3 | Error reporting
12.12.4 | Recording disappeared uses
12.12.5 | Miscellaneous utilities

On this page:

12.12.1`` Creating formatted identifiers
format-id
format-symbol
12.12.2`` Pattern variables
define/ with-syntax
12.12.3`` Error reporting
current-syntax-context
wrong-syntax
12.12.4`` Recording disappeared uses
current-recorded-disappeared-uses
with-disappeared-uses
syntax-local-value/ record
record-disappeared-uses
12.12.5`` Miscellaneous utilities
generate-temporary
internal-definition-context-apply
syntax-local-eval
with-syntax*

top contents ← prev up next →

#### 12.12`` Syntax Utilities🔗ℹ

(require racket/syntax) | package: base

The bindings documented in this section are provided by the racket/syntax library, not racket/base or racket.

##### 12.12.1`` Creating formatted identifiers🔗ℹ

> > procedure
> > (format-id |  | lctx |  |  |  |
> > |  | fmt |  |  |  |
> > |  | v ... |  |  |  |
> > | [ | #:source src |  |  |  |
> > |  | #:props props |  |  |  |
> > |  | #:cert ignored |  |  |  |
> > |  | #:subs? subs? |  |  |  |
> > |  | #:subs-intro subs-introducer]) |  | → |  | identifier?
> lctx : (or/c syntax? #f)
> fmt : string?
> | v |  | : |  |
> (or/c string? symbol? keyword? char? number?
> (syntax/c (or/c string? symbol? keyword? char? number?)))
> src : (or/c syntax? #f) = #f
> props : (or/c syntax? #f) = #f
> ignored : (or/c syntax? #f) = #f
> subs? : boolean? = #f
> | subs-introducer |  | : |  | (-> syntax? syntax?)
> |  |  | = |  | (if (syntax-transforming?) syntax-local-introduce values)

Like format, but produces an identifier using lctx for the lexical context, src for the source location, and props for the properties. An argument supplied with #:cert is ignored. (See datum->syntax.)

The format string must use only ~a placeholders. Syntax objects in the argument list are automatically unwrapped (e.g., identifiers will be automatically converted to symbols).

Examples:

> > (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 an identifier before its definition
> in module: top-level
> > (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 an identifier before its definition
> in module: top-level

(Scribble doesn’t show it, but the DrRacket pinpoints the location of the second error but not of the first.)

If subs? is #t, then a 'sub-range-binders syntax property is added to the result that records the position of each identifier in the vs. The subs-intro procedure is applied to each identifier, and its result is included in the sub-range binder record. This property value overrides a 'sub-range-binders property copied from props.

Example:

> > (syntax-property (format-id #'here "~a/~a-~a" #'point 2 #'y #:subs? #t)
> 'sub-range-binders)
> '(#(#<syntax point/2-y> 8 1 0.5 0.5 #<syntax:eval:8:0 y> 0 1 0.5 0.5)
> #(#<syntax point/2-y> 0 5 0.5 0.5 #<syntax:eval:8:0 point> 0 5 0.5 0.5))

Changed in version 7.4.0.5 of package base: Added the #:subs? and #:subs-intro arguments.
Changed in version 8.7.0.7: Allowed v to be a syntax object wrapping a string, a keyword, a character, or a number.

> procedure (format-symbol fmt v ...) → symbol?
> fmt : string?
> | v |  | : |  |
> (or/c string? symbol? keyword? char? number?
> (syntax/c (or/c string? symbol? keyword? char? number?)))

Like format, but produces a symbol. The format string must use only ~a placeholders. Syntax objects in the argument list are automatically unwrapped (e.g., identifiers will be automatically converted to symbols).

Example:

> > (format-symbol "make-~a" 'triple)
> 'make-triple

Changed in version 8.7.0.7 of package base: Allowed v to be a syntax object wrapping a string, a keyword, a character, or a number.

##### 12.12.2`` Pattern variables🔗ℹ

> syntax (define/with-syntax pattern stx-expr)
> | stx-expr |  | : |  | syntax?

Definition form of with-syntax. That is, it matches the syntax object result of stx-expr against pattern and creates pattern variable definitions for the pattern variables of pattern.

Examples:

> > (define/with-syntax (px ...) #'(a b c))
> > (define/with-syntax (tmp ...) (generate-temporaries #'(px ...)))
> > #'([tmp px] ...)
> #<syntax:eval:12:0 ((a9 a) (b10 b) (c11 c))>
> > (define/with-syntax name #'Alice)
> > #'(hello name)
> #<syntax:eval:14:0 (hello Alice)>

##### 12.12.3`` Error reporting🔗ℹ

> parameter (current-syntax-context) → (or/c syntax? #f)
> (current-syntax-context stx) → void?
> stx : (or/c syntax? #f)

The current contextual syntax object, defaulting to #f. It determines the special form name that prefixes syntax errors created by wrong-syntax.

> procedure (wrong-syntax stx format-string v ...) → any
> stx : syntax?
> format-string : string?
> v : any/c

Raises a syntax error using the result of (current-syntax-context) as the “major” syntax object and the provided stx as the specific syntax object. (The latter, stx, is usually the one highlighted by DrRacket.) The error message is constructed using the format string and arguments, and it is prefixed with the special form name as described under current-syntax-context.

Examples:

> > (wrong-syntax #'here "expected ~s" 'there)
> eval:15:0: ?: expected there
> at: here
> > (parameterize ([current-syntax-context #'(look over here)])
> (wrong-syntax #'here "expected ~s" 'there))
> eval:16:0: look: expected there
> at: here
> in: (look over here)

A macro using wrong-syntax might set the syntax context at the very beginning of its transformation as follows:

> (define-syntax (my-macro stx)
> (parameterize ([current-syntax-context stx])
> (syntax-case stx ()
> __)))

Then any calls to wrong-syntax during the macro’s transformation will refer to my-macro (more precisely, the name that referred to my-macro where the macro was used, which may be different due to renaming, prefixing, etc).

##### 12.12.4`` Recording disappeared uses🔗ℹ

> parameter (current-recorded-disappeared-uses)
> → (or/c (listof identifier?) #f)
> (current-recorded-disappeared-uses ids) → void?
> ids : (or/c (listof identifier?) #f)

Parameter for tracking disappeared uses. Tracking is “enabled” when the parameter has a non-false value. This is done automatically by forms like with-disappeared-uses.

> syntax (with-disappeared-uses body-expr ... stx-expr)
> | stx-expr |  | : |  | syntax?

Evaluates the body-exprs and stx-expr, catching identifiers looked up using syntax-local-value/record. Adds the caught identifiers to the 'disappeared-use syntax property of the syntax object produced by stx-expr.

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

Looks up id in the syntactic environment (as syntax-local-value). If the lookup succeeds and returns a value satisfying the predicate, the value is returned and id is recorded as a disappeared use by calling record-disappeared-uses. If the lookup fails or if the value does not satisfy the predicate, #f is returned and the identifier is not recorded as a disappeared use.

> procedure (record-disappeared-uses id [intro?]) → void?
> id : (or/c identifier? (listof identifier?))
> intro? : boolean? = (syntax-transforming?)

Add id to (current-recorded-disappeared-uses). If id is a list, perform the same operation on all the identifiers. If intro? is true, then syntax-local-introduce is first called on the identifiers.

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.
Changed in version 7.2.0.11: Added the intro? argument.

##### 12.12.5`` Miscellaneous utilities🔗ℹ

> procedure (generate-temporary [name-base]) → identifier?
> name-base : any/c = 'g

Generates one fresh identifier. Singular form of generate-temporaries. If name-base is supplied, it is used as the basis for the identifier’s name.

> > procedure
> > (internal-definition-context-apply |  | intdef-ctx |  |  |  |
> > |  | stx) |  | → |  | syntax?
> intdef-ctx : internal-definition-context?
> stx : syntax?

Equivalent to (internal-definition-context-introduce intdef-ctx stx 'add). The internal-definition-context-apply function is provided for backwards compatibility; the internal-definition-context-add-scopes function is preferred.

> procedure (syntax-local-eval stx [intdef-ctx]) → any
> stx : any/c
> | intdef-ctx |  | : |  |
> (or/c internal-definition-context?
> #f
> (listof internal-definition-context?))
> |  |  | = |  | '()

Evaluates stx as an expression in the current transformer environment (that is, at phase level 1). If intdef-ctx is not #f, the value provided for intdef-ctx is used to enrich stx’s lexical information and extend the local binding context in the same way as the fourth argument to local-expand.

Examples:

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

Changed in version 6.90.0.27 of package base: Changed intdef-ctx to accept a list of internal-definition contexts in addition to a single internal-definition context or #f.

> > syntax
> > (with-syntax* ([pattern stx-expr] ...)
> > body ...+)
> | stx-expr |  | : |  | syntax?

Similar to with-syntax, but the pattern variables of each pattern are bound in the stx-exprs of subsequent clauses as well as the bodys, and the patterns need not bind distinct pattern variables; later bindings shadow earlier bindings.

Example:

> > (with-syntax* ([(x y) (list #'val1 #'val2)]
> [nest #'((x) (y))])
> #'nest)
> #<syntax:eval:22:0 ((val1) (val2))>

top contents ← prev up next →