► |  | Syntax: Meta-Programming Helpers

1 | Parsing and Specifying Syntax
2 | Syntax Object Helpers
3 | Datum Pattern Matching
4 | Module-Processing Helpers
5 | Macro Transformer Helpers
6 | Reader Helpers
7 | Parsing for Bodies
8 | Unsafe for Clause Transforms
9 | Source Locations
10 | Preserving Source Locations
11 | Non-Module Compilation And Expansion
12 | Trusting Standard Recertifying Transformers
13 | Attaching Documentation to Exports
14 | Contracts for Macro Subexpressions
15 | Macro Testing
16 | Internal-Definition Context Helpers
| Index

▼ | 1 | Parsing and Specifying Syntax

1.1 | Introduction
1.2 | Examples
1.3 | Parsing Syntax
1.4 | Specifying Syntax with Syntax Classes
1.5 | Syntax Patterns
1.6 | Defining Simple Macros
1.7 | Literal Sets and Conventions
1.8 | Library Syntax Classes and Literal Sets
1.9 | Unwindable State
1.10 | Debugging and Inspection Tools
1.11 | Experimental

► | 1.8 | Library Syntax Classes and Literal Sets

1.8.1 | Syntax Classes
1.8.2 | Literal Sets
1.8.3 | Function Headers

On this page:

1.8.1`` Syntax Classes
expr
identifier
boolean
char
keyword
number
integer
exact-integer
exact-nonnegative-integer
exact-positive-integer
regexp
byte-regexp
id
nat
str
character
static
expr/ c
1.8.2`` Literal Sets
kernel-literals
1.8.3`` Function Headers
function-header
formal
formals
formals-no-rest

top ← prev up next →

#### 1.8`` Library Syntax Classes and Literal Sets

##### 1.8.1`` Syntax Classes

> > syntax class

> > expr

Matches anything except a keyword literal (to distinguish expressions from the start of a keyword argument sequence). The term is not otherwise inspected, since it is not feasible to check if it is actually a valid expression.

> > syntax class

> > identifier

> > syntax class

> > boolean

> > syntax class

> > char

> > syntax class

> > keyword

> > syntax class

> > number

> > syntax class

> > integer

> > syntax class

> > exact-integer

> > syntax class

> > exact-nonnegative-integer

> > syntax class

> > exact-positive-integer

> > syntax class

> > regexp

> > syntax class

> > byte-regexp

Match syntax satisfying the corresponding predicates.

> > syntax class

> > string

> > syntax class

> > bytes

As special cases, Racket’s string and bytes bindings are also interpreted as syntax classes that recognize literal strings and bytes, respectively.

Added in version 6.9.0.4 of package base.

> > syntax class

> > id

Alias for identifier.

> > syntax class

> > nat

Alias for exact-nonnegative-integer.

> > syntax class

> > str

Alias for string.

> > syntax class

> > character

Alias for char.

> > syntax class

> > (static predicate description) → syntax class

> predicate : (-> any/c any/c)
> description : (or/c string? #f)

The static syntax class matches an identifier that is bound in the syntactic environment to static information (see syntax-local-value) satisfying the given predicate. If the term does not match, the description argument is used to describe the expected syntax.

When used outside of the dynamic extent of a macro transformer (see syntax-transforming?), matching fails.

The attribute value contains the value the name is bound to.

If matching succeeds, static additionally adds the matched identifier to the current syntax-parse state under the key 'literals using syntax-parse-state-cons!, in the same way as identifiers matched using #:literals or ~literal.

Changed in version 6.90.0.29 of package base: Changed to add matched identifiers to the syntax-parse state under the key 'literals.

> > syntax class

> > (expr/c |  | contract-expr |  |  |  |
> > | [ | #:arg? arg? |  |  |  |
> > |  | #:positive pos-blame |  |  |  |
> > |  | #:negative neg-blame |  |  |  |
> > |  | #:name expr-name |  |  |  |
> > |  | #:macro macro-name |  |  |  |
> > |  | #:context context |  |  |  |
> > |  | #:phase phase]) |  | → |  | syntax class

> contract-expr : syntax?
> arg? : any/c = #t

> | pos-blame |  | : |  | (or/c syntax? string? module-path-index? 'from-macro 'use-site 'unknown)
> |  |  | = |  | 'from-macro

> | neg-blame |  | : |  | (or/c syntax? string? module-path-index? 'from-macro 'use-site 'unknown)
> |  |  | = |  | 'use-site

> expr-name : (or/c identifier? string? symbol?) = #f
> macro-name : (or/c identifier? string? symbol?) = #f
> context : (or/c syntax? #f) = determined automatically
> phase : exact-integer? = (syntax-local-phase-level)

Accepts an expression (expr) and computes an attribute c that represents the expression wrapped with the contract represented by contract-expr. Note that contract-expr is potentially evaluated each time the code generated by the macro is run; for the best performance, contract-expr should be a variable reference.

The positive blame represents the obligations of the macro imposing the contract—the ultimate user of expr/c. The contract’s negative blame represents the obligations of the expression being wrapped. By default, the positive blame is inferred from the definition site of the macro (itself inferred from the context argument), and the negative blame is taken as the module currently being expanded, but both blame locations can be overridden. When arg? is #t, the term being matched is interpreted as an argument (that is, coming from the negative party); when arg? is #f, the term being matched is interpreted as a result of the macro (that is, coming from the positive party).

The pos-blame and neg-blame arguments are turned into blame locations as follows:

- If the argument is a string, it is used directly as the blame label.

- If the argument is syntax, its source location is used to produce the blame label.

- If the argument is a module path index, its resolved module path is used.

- If the argument is 'from-macro, the macro is inferred from either the macro-name argument (if macro-name is an identifier) or the context argument, and the module where it is defined is used as the blame location. If neither an identifier macro-name nor a context argument is given, the location is "unknown".

- If the argument is 'use-site, the module being expanded is used.

- If the argument is 'unknown, the blame label is "unknown".

The macro-name argument is used to determine the macro’s binding, if it is an identifier. If expr-name is given, macro-name is also included in the contract error message. If macro-name is omitted or #f, but context is a syntax object, then macro-name is determined from context.

If expr-name is not #f, it is used in the contract’s error message to describe the expression the contract is applied to.

The context argument is used, when necessary, to infer the macro name for the negative blame party and the contract error message. The context should be either an identifier or a syntax pair with an identifier in operator position; in either case, that identifier is taken as the macro ultimately requesting the contract wrapping.

The phase argument must indicate the phase level at which the contracted expression will be evaluated. Using the contracted expression at a different phase level will cause a syntax error because it will contain introduced references bound in the wrong phase. In particular:

- Use the default value, (syntax-local-phase-level), when the contracted expression will be evaluated at the same phase as the form currently being expanded. This is usually the case.

- Use (add1 (syntax-local-phase-level)) in cases such as the following: the contracted expression will be placed inside a begin-for-syntax form, used in the right-hand side of a define-syntax or let-syntax form, or passed to syntax-local-bind-syntaxes or syntax-local-eval.

Any phase level other than #f (the label phase level) is allowed, but phases other than (syntax-local-phase-level) and (add1 (syntax-local-phase-level)) may only be used when in the dynamic extent of a syntax transformer or while a module is being visited (see syntax-transforming?), otherwise exn:fail:contract? is raised.

See Contracts on Macro Sub-expressions for examples.

Important: Make sure when using expr/c to use the c attribute. The expr/c syntax class does not change how pattern variables are bound; it only computes an attribute that represents the checked expression.

Changed in version 7.2.0.3 of package base: Added the #:arg? keyword argument and changed the default values and interpretation of the #:positive and #:negative arguments.
Changed in version 7.3.0.3: Added the #:phase keyword argument.

##### 1.8.2`` Literal Sets

> > syntax

> > kernel-literals

Literal set containing the identifiers for fully-expanded code (Fully Expanded Programs). The set contains all of the forms listed by kernel-form-identifier-list, plus module, #%plain-module-begin, #%require, and #%provide.

Note that the literal-set uses the names #%plain-lambda and #%plain-app, not lambda and #%app.

##### 1.8.3`` Function Headers

(require syntax/parse/lib/function-header)
| package: base

> > syntax class

> > function-header

Matches a name and formals found in function header. It also supports the curried function shorthand.

> > > attribute

> > > name : syntax?

> The name part in the function header.

> > > attribute

> > > params : syntax?

> The list of parameters in the function header.

> > splicing syntax class

> > formal

Matches a single formal that can be used in a function header.

> > > attribute

> > > name : syntax?

> The name part in the formal.

> > > attribute

> > > kw : (or/c syntax? #f)

> The keyword part in the formal, if it exists.

> > > attribute

> > > default : (or/c syntax? #f)

> The default expression part in the formal, if it exists.

> > syntax class

> > formals

Matches a list of formals that would be used in a function header.

> > > attribute

> > > params : syntax?

> The list of parameters in the formals.

> > (syntax-parse #'(define ((foo x) y) 1)
> [(_ header:function-header body ...+) #'(header header.name header.params)])

> #<syntax:eval:2:0 (((foo x) y) foo (x y))>

> > (syntax-parse #'(lambda xs xs)
> [(_ fmls:formals body ...+) #'(fmls fmls.params)])

> #<syntax:eval:3:0 (xs (xs))>

> > (syntax-parse #'(lambda (x y #:kw [kw 42] . xs) xs)
> [(_ fmls:formals body ...+) #'(fmls fmls.params)])

> #<syntax:eval:4:0 ((x y #:kw (kw 42) . xs) (x y kw xs))>

> > (syntax-parse #'(lambda (x) x)
> [(_ (fml:formal) body ...+) #'(fml
> fml.name
> (~? fml.kw #f)
> (~? fml.default #f))])

> #<syntax:eval:5:0 ((x) x #f #f)>

> > (syntax-parse #'(lambda (#:kw [kw 42]) kw)
> [(_ (fml:formal) body ...+) #'(fml fml.name fml.kw fml.default)])

> #<syntax:eval:6:0 ((#:kw (kw 42)) kw #:kw 42)>

> > splicing syntax class

> > formals-no-rest

Like formals but without dotted-tail identifier.

> > > attribute

> > > params : syntax?

> The list of parameters.

top ← prev up next →