racket/collects/syntax/scribblings/parse/ex-exprc.scrbl
Eli Barzilay ac26fe7554 A ton of @scheme*' -> @racket*' and related updates.
Also, updates some of the mzlib files to point at `racket/*' libraries
rather than to `scheme/*' ones.
2011-06-25 04:08:47 -04:00

43 lines
1.5 KiB
Racket

#lang scribble/doc
@(require scribble/manual
scribble/struct
scribble/decode
scribble/eval
"parse-common.rkt"
(for-label racket/class))
@title[#:tag "exprc"]{Experimental: Contracts on macro sub-expressions}
@emph{This section involves facilities that are experimental and
subject to change.}
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 @racket[expr/c] syntax class.
For example, here is a macro @racket[myparameterize] that behaves like
@racket[parameterize] but enforces the @racket[parameter?] contract on
the parameter expressions.
@myinteraction[
(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))
(myparameterize (('whoops 'something))
'whatever)
]
@bold{Important:} Make sure when using @racket[expr/c] to use the
@racket[c] attribute. If the macro above had used @racket[p] in the
template, the expansion would have used the raw, unchecked
expressions. The @racket[expr/c] syntax class does not change how
pattern variables are bound; it only computes an attribute that
represents the checked expression.