► |  | The Racket Guide

1 | Welcome to Racket
2 | Racket Essentials
3 | Built-In Datatypes
4 | Expressions and Definitions
5 | Programmer-Defined Datatypes
6 | Modules
7 | Contracts
8 | Input and Output
9 | Regular Expressions
10 | Exceptions and Control
11 | Iterations and Comprehensions
12 | Pattern Matching
13 | Classes and Objects
14 | Units (Components)
15 | Reflection and Dynamic Evaluation
16 | Macros
17 | Creating Languages
18 | Performance
19 | Running and Creating Executables
20 | More Libraries
21 | Dialects of Racket and Scheme
22 | Command-Line Tools and Your Editor of Choice
| Bibliography
| Index

▼ | 4 | Expressions and Definitions

4.1 | Notation
4.2 | Identifiers and Binding
4.3 | Function Calls (Procedure Applications)
4.4 | Functions (Procedures): lambda
4.5 | Definitions: define
4.6 | Local Binding
4.7 | Conditionals
4.8 | Sequencing
4.9 | Assignment: set!
4.10 | Quoting: quote and '
4.11 | Quasiquoting: quasiquote and ‘
4.12 | Simple Dispatch: case
4.13 | Dynamic Binding: parameterize

top ← prev up next →

#### 4.11`` Quasiquoting: quasiquote and ‘

> > > Quasiquoting: quasiquote, unquote, and unquote-splicing in The Racket Reference also documents quasiquote.

The quasiquote form is similar to quote:

> > ( quasiquote datum)

However, for each ( unquote expr) that appears within the datum, the expr is evaluated to produce a value that takes the place of the unquote sub-form.

Example:

> > ( quasiquote (1 2 ( unquote ( + 1 2)) ( unquote ( - 5 1))))
> '(1 2 3 4)

This form can be used to write functions that build lists according to certain patterns.

Examples:

> > ( define (deep n)
> ( cond
> [( zero? n) 0]
> [ else
> ( quasiquote (( unquote n) ( unquote (deep ( - n 1)))))]))

> > (deep 8)
> '(8 (7 (6 (5 (4 (3 (2 (1 0))))))))

Or even to cheaply construct expressions programmatically. (Of course, 9 times out of 10, you should be using a macro to do this (the 10th time being when you’re working through a textbook like PLAI).)

Examples:

> > ( define (build-exp n)
> (add-lets n (make-sum n)))

> > ( define (add-lets n body)
> ( cond
> [( zero? n) body]
> [ else
> ( quasiquote
> ( let ([( unquote (n->var n)) ( unquote n)])
> ( unquote (add-lets ( - n 1) body))))]))

> > ( define (make-sum n)
> ( cond
> [( = n 1) (n->var 1)]
> [ else
> ( quasiquote ( + ( unquote (n->var n))
> ( unquote (make-sum ( - n 1)))))]))

> > ( define (n->var n) ( string->symbol ( format "x~a" n)))

> > (build-exp 3)
> '(let ((x3 3)) (let ((x2 2)) (let ((x1 1)) (+ x3 (+ x2 x1)))))

The unquote-splicing form is similar to unquote, but its expr must produce a list, and the unquote-splicing form must appear in a context that produces either a list or a vector. As the name suggests, the resulting list is spliced into the context of its use.

Example:

> > ( quasiquote (1 2 ( unquote-splicing ( list ( + 1 2) ( - 5 1))) 5))
> '(1 2 3 4 5)

Using splicing we can revise the construction of our example expressions above to have just a single let expression and a single + expression.

Examples:

> > ( define (build-exp n)
> (add-lets
> n
> ( quasiquote ( + ( unquote-splicing
> ( build-list
> n
> ( λ (x) (n->var ( + x 1)))))))))

> > ( define (add-lets n body)
> ( quasiquote
> ( let ( unquote
> ( build-list
> n
> ( λ (n)
> ( quasiquote
> [( unquote (n->var ( + n 1))) ( unquote ( + n 1))]))))
> ( unquote body))))

> > ( define (n->var n) ( string->symbol ( format "x~a" n)))

> > (build-exp 3)
> '(let ((x1 1) (x2 2) (x3 3)) (+ x1 x2 x3))

If a quasiquote form appears within an enclosing quasiquote form, then the inner quasiquote effectively cancels one layer of unquote and unquote-splicing forms, so that a second unquote or unquote-splicing is needed.

Examples:

> > ( quasiquote (1 2 ( quasiquote ( unquote ( + 1 2)))))
> '(1 2 (quasiquote (unquote (+ 1 2))))
> > ( quasiquote (1 2 ( quasiquote ( unquote ( unquote ( + 1 2))))))
> '(1 2 (quasiquote (unquote 3)))
> > ( quasiquote (1 2 ( quasiquote (( unquote ( + 1 2)) ( unquote ( unquote ( - 5 1)))))))
> '(1 2 (quasiquote ((unquote (+ 1 2)) (unquote 4))))

The evaluations above will not actually print as shown. Instead, the shorthand form of quasiquote and unquote will be used: ` (i.e., a backquote) and , (i.e., a comma). The same shorthands can be used in expressions:

Example:

> > `(1 2 `(,(+ 1 2) ,,( - 5 1)))
> '(1 2 `(,(+ 1 2) ,4))

The shorthand form of unquote-splicing is ,@:

Example:

> > `(1 2 ,@( list ( + 1 2) ( - 5 1)))
> '(1 2 3 4)

top ← prev up next →