1.2.6 Contracts on Macro Sub-expressions

► |  | 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 | Debugging and Inspection Tools
1.10 | Experimental

▼ | 1.2 | Examples

1.2.1 | Phases and Reusable Syntax Classes
1.2.2 | Optional Keyword Arguments
1.2.3 | Variants with Uniform Meanings
1.2.4 | Variants with Varied Meanings
1.2.5 | More Keyword Arguments
1.2.6 | Contracts on Macro Sub-expressions

top ← prev up next →

##### 1.2.6`` Contracts on Macro Sub-expressions

Just as procedures often expect certain kinds of values as arguments, macros often have expectations about the expressions they are given. And just as procedures express those expectations via contracts, so can macros, using the expr/c syntax class.

For example, here is a macro myparameterize that behaves like parameterize but enforces the parameter? contract on the parameter expressions.

> > (define-syntax (myparameterize stx)
> (syntax-parse stx
> [(_ ((p v:expr) ...) body:expr)
> #:declare p (expr/c #'parameter?
> #:name "parameter argument")
> #'(parameterize ([p.c v] ...) body)]))
> > (myparameterize ([current-input-port
> (open-input-string "(1 2 3)")])
> (read))
> '(1 2 3)
> > (myparameterize (['whoops 'something])
> 'whatever)
> parameter argument of myparameterize: broke its own contract
> promised: parameter?
> produced: 'whoops
> in: parameter?
> contract from: program
> blaming: program
> (assuming the contract is correct)
> at: eval:3.0

Important: Make sure when using expr/c to use the c attribute. If the macro above had used p in the template, the expansion would have used the raw, unchecked expressions. The expr/c syntax class does not change how pattern variables are bound; it only computes an attribute that represents the checked expression.

top ← prev up next →