such as define-place have the same
status as built-in forms such as define and lambda.
To make this shift, you can put the
define-verbs, define-place, define-thing, and define-everywhere definitions in their own module, called world.rkt.
(define-thing ....) ...
(define-place ....) ...
This module imports txtadv.rkt,
which exports define-verbs as well
as functions used in verb responses
such as save-game and load-game.
Meanwhile, txtadv.rkt keeps private
the structures and other functions that
implement the world data types.
(provide define-verbs define-thing
(struct verb ....)
Where to Find
the Code Online
CoMPLete GaMe iMPLeMentation:
ReViseD GaMe iMPLeMentation:
MoDuLaR GaMe iMPLeMentation:
GaMe with a txtaDV.RKt LanGuaGe:
CoDe foR the GaMe with statiC CheCKs:
GaMe CoDe with nonPaRentheses syntax:
CoDe foR GaMe with a DRRaCKet PLuG-in:
The #lang racket line that starts
each module indicates that the module
is implemented in the racket language.
In world.rkt, require additionally imports both the syntactic extensions
and functions that are exported by the
Since macro binding is part of the
Racket language, as opposed to being
implemented as a separate preproces-
sor, macro bindings can work with
module imports and exports the same
as variable bindings. In particular,
the definition of the define-verbs
macro can see the verb constructor
function because of the rules of lexi-
cal scope, while code in the world.rkt
module cannot access verb directly be-
cause of the same scoping rules. Since
a use of define-verbs in world.rkt
expands to a use of verb, considerable
language machinery is required for
Racket to maintain lexical scope in the
presence of macro expansion, but the
result is that syntactic extension is easy
Although the world.rkt module cannot directly access constructor functions such as verb, the module still
has access to all of the Racket language and, via require, any other
module’s exports. More constraints
on world.rkt may be appropriate to
ensure that assumptions of txtadv.rkt
To exert further control, you can
convert txtadv.rkt from a module
that exports a language extension to
one that exports a language. Then,
instead starting with #lang racket,
world.rkt starts with
#lang s-exp "txtadv.rkt"
For now, s-exp indicates that the
language of world.rkt uses S-expression notation (that is, parentheses),
while txtadv.rkt defines syntactic
forms. Later, the S-expression and
syntactic-form specifications are combined into a single name, analogous to
Along with changing world.rkt, you
can change txtadv.rkt to export everything from racket:
(provide define-verbs ....
Instead of (all-from-out racket), you could use (except-out (
all-from-out racket) require) to withhold the require form from world.