fix formating of duplicated syntax descriptions

This commit is contained in:
Matthew Flatt 2011-07-07 10:10:56 -06:00
parent e1b02e08f7
commit 6c3360c716
6 changed files with 379 additions and 315 deletions

View File

@ -97,15 +97,13 @@ arguments, and (naturally) function calls can invoke functions of zero arguments
@defform[(lambda (variable ...) expression)]{ @defform[(lambda (variable ...) expression)]{
Creates a function that takes as many arguments as given @racket[variables]s, Creates a function that takes as many arguments as given @racket[variable]s,
and whose body is @racket[expression].} and whose body is @racket[expression].}
@defform[(λ (variable ...) expression)]{ @defform[(λ (variable ...) expression)]{
The Greek letter @racket[λ] is a synonym for @racket[lambda].} The Greek letter @racket[λ] is a synonym for @racket[lambda].}
@defform/none[(expression expression ...)]{ @defform/none[(expression expression ...)]{
Calls the function that results from evaluating the first Calls the function that results from evaluating the first
@ -118,19 +116,6 @@ function call, or from a @racket[lambda] expression. The number of argument
@racket[expression]s must be the same as the number of arguments expected by @racket[expression]s must be the same as the number of arguments expected by
the function.} the function.}
In Advanced, @racket[define-struct] introduces one additional function:
@itemize[
@item{@racketidfont{set-}@racket[structure-name]@racketidfont{-}@racket[field-name]@racketidfont{!}
: takes an instance of the structure and a value, and changes
the instance's field to the given value.}
]}
@; ---------------------------------------------------------------------- @; ----------------------------------------------------------------------
@ -299,7 +284,12 @@ Like @racket[when], but the @racket[body-expression] is evaluated when the
@(prim-forms ("advanced") @(prim-forms ("advanced")
define define
lambda lambda
define-struct define-struct
@{In Advanced, @racket[define-struct] introduces one additional function:
@itemize[
@item{@racketidfont{set-}@racket[_structure-name]@racketidfont{-}@racket[_field-name]@racketidfont{!}
: takes an instance of the structure and a value, and
changes the instance's field to the given value.}]}
define-wish define-wish
cond cond
else else
@ -311,7 +301,8 @@ Like @racket[when], but the @racket[body-expression] is evaluated when the
check-error check-error
check-member-of check-member-of
check-range check-range
require) require
true false)
@; ---------------------------------------- @; ----------------------------------------

View File

@ -117,7 +117,7 @@ also be written with @racket[unquote-splicing].}
@prim-forms[("beginner-abbr") @prim-forms[("beginner-abbr")
define define
lambda lambda
define-struct define-struct []
define-wish define-wish
cond cond
else else
@ -129,7 +129,8 @@ also be written with @racket[unquote-splicing].}
check-error check-error
check-member-of check-member-of
check-range check-range
require] require
true false]
@; ---------------------------------------- @; ----------------------------------------

View File

@ -36,6 +36,9 @@
@prim-nonterms[("beginner") define define-struct] @prim-nonterms[("beginner") define define-struct]
@prim-variables[("beginner") empty true false] @prim-variables[("beginner") empty true false]
@; --------------------------------------------------
@section[#:tag "beginner-syntax"]{Syntax} @section[#:tag "beginner-syntax"]{Syntax}
@deftogether[( @deftogether[(
@ -46,14 +49,13 @@
A quoted @racket[name] is a symbol. A symbol is a value, just like A quoted @racket[name] is a symbol. A symbol is a value, just like
@racket[0] or @racket[empty].} @racket[0] or @racket[empty].}
@(define-forms/normal define) @(define-forms/normal define)
@(define-form/explicit-lambda define lambda) @(define-form/explicit-lambda define lambda)
@(prim-forms ("beginner") @(prim-forms ("beginner")
define define
lambda lambda
define-struct define-struct []
define-wish define-wish
cond cond
else else
@ -65,7 +67,10 @@ A quoted @racket[name] is a symbol. A symbol is a value, just like
check-error check-error
check-member-of check-member-of
check-range check-range
require) require
true false)
@; --------------------------------------------------
@section[#:tag "beginner-pre-defined"]{Pre-defined Functions} @section[#:tag "beginner-pre-defined"]{Pre-defined Functions}

View File

@ -52,7 +52,7 @@
@defform[(lambda (variable variable ...) expression)]{ @defform[(lambda (variable variable ...) expression)]{
Creates a function that takes as many arguments as given @racket[variables]s, Creates a function that takes as many arguments as given @racket[variable]s,
and whose body is @racket[expression].} and whose body is @racket[expression].}
@defform[(λ (variable variable ...) expression)]{ @defform[(λ (variable variable ...) expression)]{
@ -94,10 +94,10 @@ the function.}
@(define-forms/normal define) @(define-forms/normal define)
@(prim-forms ("beginner") @(prim-forms ("intermediate-lam")
define define
lambda lambda
define-struct define-struct []
define-wish define-wish
cond cond
else else
@ -109,7 +109,8 @@ the function.}
check-error check-error
check-member-of check-member-of
check-range check-range
require) require
true false)
@section[#:tag "intm-w-lambda-pre-defined"]{Pre-defined Functions} @section[#:tag "intm-w-lambda-pre-defined"]{Pre-defined Functions}

View File

@ -69,10 +69,10 @@
@(define-form/explicit-lambda define lambda) @(define-form/explicit-lambda define lambda)
@(prim-forms @(prim-forms
("beginner") ("intermediate")
define define
lambda lambda
define-struct define-struct []
define-wish define-wish
cond cond
else else
@ -84,7 +84,8 @@
check-error check-error
check-member-of check-member-of
check-range check-range
require) require
true false)

View File

@ -58,67 +58,70 @@
(define-syntax-rule (prim-variables (section-prefix) empty true false) (define-syntax-rule (prim-variables (section-prefix) empty true false)
(make-splice (make-splice
(list (list
@section[#:tag (string-append section-prefix " Pre-Defined Variables")]{Pre-Defined Variables}
@section[#:tag (string-append section-prefix " Pre-Defined Variables")]{Pre-Defined Variables} @defthing[empty empty?]{
@defthing[empty empty?]{
The empty list.} The empty list.}
@defthing[true boolean?]{ @defthing[true boolean?]{
The true value.} The true value.}
@defthing[false boolean?]{ @defthing[false boolean?]{
The false value.} The false value.})))
))) ;; ----------------------------------------
(define-syntax-rule (define-forms/normal define) (define-syntax-rule (define-forms/normal define)
(gen-define-forms/normal #'define @racket[define]))
(make-splice (define (gen-define-forms/normal define-id define-elem)
(list ;; Since `define' has a source location different from the use site,
@defform*[[(define (... (name variable variable ...)) expression)]]{ ;; use the `#:id [spec-id bind-id]' form in `defform*':
(list
@defform*[#:id [define define-id]
[(define (name variable variable ...) expression)]]{
Defines a function named @racket[name]. The @racket[expression] is the body Defines a function named @racket[name]. The @racket[expression] is the body
of the function. When the function is called, of the function. When the function is called,
the values of the arguments are inserted into the body in place of the the values of the arguments are inserted into the body in place of the
@racket[variable]s. The function returns the value of that new expression. @racket[variable]s. The function returns the value of that new expression.
The function name's cannot be the same as that of another function or The function name's cannot be the same as that of another function or
variable.} variable.}
@defform/none[#:literals (define) (define name expression)]{ @defform/none[(@#,define-elem name expression)]{
Defines a variable called @racket[name] with the the value of Defines a variable called @racket[name] with the the value of
@racket[expression]. The variable name's cannot be the same as that of @racket[expression]. The variable name's cannot be the same as that of
another function or variable, and @racket[name] itself must not appear in another function or variable, and @racket[name] itself must not appear in
@racket[expression].} @racket[expression].}))
))) ;; ----------------------------------------
(define-syntax-rule (define-form/explicit-lambda define lambda) (define-syntax-rule (define-form/explicit-lambda define lambda)
(gen-define-form/explicit-lambda @racket[define]
#'lambda @racket[lambda]))
(make-splice (define (gen-define-form/explicit-lambda define-elem lambda-id lambda-elem)
(list (list
@defform/none[(#,define-elem name (#,lambda-elem (variable variable ...) expression))]{
@defform/none[#:literals (define lambda)
(... (define name (lambda (variable variable ...) expression)))]{
An alternate way on defining functions. The @racket[name] is the name of An alternate way on defining functions. The @racket[name] is the name of
the function, which cannot be the same as that of another function or the function, which cannot be the same as that of another function or
variable. variable.
@defidform/inline[lambda] cannot be used outside of this alternate syntax. A @defidform/inline[#,lambda-id] cannot be used outside of this alternate syntax.}))
}
)))
;; ----------------------------------------
(define-syntax-rule (prim-forms (define-syntax-rule (prim-forms
(section-prefix) (section-prefix)
define define
lambda lambda
define-struct define-struct [ds-extra ...]
define-wish define-wish
cond cond
else else
@ -130,210 +133,241 @@ variable.
check-error check-error
check-member-of check-member-of
check-range check-range
require) require
(make-splice true
(list false)
(gen-prim-forms #'define-struct @racket[define-struct] (list ds-extra ...)
#'cond @racket[cond]
#'else @racket[else]
#'if @racket[if]
#'or @racket[or]
#'and @racket[and]
#'check-expect @racket[check-expect]
#'check-within @racket[check-within]
#'check-error @racket[check-error]
#'check-member-of @racket[check-member-of]
#'check-range @racket[check-range]
#'require @racket[require]
@racket[true] @racket[false]))
(define (gen-prim-forms define-struct-id define-struct-elem ds-extras
cond-id cond-elem
else-id else-elem
if-id if-elem
and-id and-elem
or-id or-elem
check-expect-id check-expect-elem
check-within-id check-within-elem
check-error-id check-error-elem
check-member-of-id check-member-of-elem
check-range-id check-range-elem
require-id require-elem
true-elem false-elem)
(list
@; ----------------------------------------------------------------------
@defform*[#:id [define-struct define-struct-id]
[(define-struct structure-name (field-name ...))]]{
@; ---------------------------------------------------------------------- Defines a new structure called @racket[field-name]. The structure's fields are
named by the @racket[field-name]s. After the @define-struct-elem, the following new
functions are available:
@itemize[
@defform*[[(... (define-struct structure-name (field-name ...)))]]{ @item{@racketidfont{make-}@racket[structure-name] : takes in a number of
arguments equal to the number of fields in the structure,
and creates a new instance of that structure.}
Defines a new structure called @racket[field-name]. The structure's fields are @item{@racket[structure-name]@racketidfont{-}@racket[field-name] : takes in an
named by the @racket[field-name]s. After the @racket[define-struct], the following new instance of the structure and returns the value in the field named by
functions are available: @racket[field-name].}
@itemize[ @item{@racket[structure-name]@racketidfont{?} : takes in any value, and returns
@true-elem if the value is an instance of the structure.}
]
@item{@racketidfont{make-}@racket[structure-name] : takes in a number of The name of the new functions introduced by @define-struct-elem
arguments equal to the number of fields in the structure, must not be the same as that of other functions or variables,
and creates a new instance of that structure.} otherwise @define-struct-elem reports an error.
@item{@racket[structure-name]@racketidfont{-}@racket[field-name] : takes in an @ds-extras}
instance of the structure and returns the value in the field named by
@racket[field-name].}
@item{@racket[structure-name]@racketidfont{?} : takes in any value, and returns #|
@racket[true] if the value is an instance of the structure.}
] @defform*[[(define-wish name)]]{
The name of the new functions introduced by @racket[define-struct] must not be the same as that of other functions or
variables, otherwise @racket[define-struct] reports an error.}
#|
@defform*[[(define-wish name)]]{
Defines a function called @racket[name] that we wish exists but have not Defines a function called @racket[name] that we wish exists but have not
implemented yet. The wished-for function can be called with one argument, and implemented yet. The wished-for function can be called with one argument, and
are reported in the test report for the current program. are reported in the test report for the current program.
The name of the function cannot be the same as another function or variable.} The name of the function cannot be the same as another function or variable.}
@defform/none[#:literals (define-wish) @defform/none[#:literals (define-wish)
(define-wish name expression)]{ (define-wish name expression)]{
Similar to the above form, defines a wished-for function named @racket[name]. If the Similar to the above form, defines a wished-for function named @racket[name]. If the
wished-for function is called with one value, it returns the values of @racket[expression]. } wished-for function is called with one value, it returns the values of @racket[expression]. }
|# |#
@; ---------------------------------------------------------------------- @; ----------------------------------------------------------------------
@defform/none[(name expression expression ...)]{
Calls the function named @racket[name]. The value of the call is the
value of @racket[name]'s body when every one of the function's
variables are replaced by the values of the corresponding
@racket[expression]s.
The function named @racket[name] must defined before it can be called. The
number of argument @racket[expression]s must be the same as the number of arguments
expected by the function.}
@; ----------------------------------------------------------------------
@defform*[#:id [cond cond-id]
#:literals (else)
[(cond [question-expression answer-expression] ...)
(#,cond-elem [question-expression answer-expression]
...
[#,else-elem answer-expression])]]{
Chooses a clause base on a condition by finding the first
@racket[question-expression] that evaluates to @true-elem, then
evaluates the corresponding @racket[answer-expression].
If none of the @racket[question-expression]s evaluates to @true-elem,
@cond-elem's value is the @racket[answer-expression] of the
@else-elem clause. If there is no @else-elem, @cond-elem reports
an error. If the result of a @racket[question-expression] is neither
@true-elem nor @false-elem, @cond-elem also reports an error.
An @defidform/inline[#,else-id] cannot be used outside of @|cond-elem|.}
@; ----------------------------------------------------------------------
@defform*[#:id [if if-id]
[(if test-expression then-expression else-expression)]]{
When the value of the @racket[test-expression] is @true-elem,
@if-elem evaluates the @racket[then-expression]. When the test is
@false-elem, @if-elem evaluates the @racket[else-expression].
If the @racket[test-expression] is neither @true-elem nor
@false-elem, @if-elem reports an error.}
@; ----------------------------------------------------------------------
@defform*[#:id [and and-id]
[(and expression expression expression ...)]]{
Evaluates to @true-elem if all the @racket[expression]s are
@|true-elem|. If any @racket[expression] is false, the @and-elem
expression immediately evaluates to @false-elem (and the expressions to the
right of that expression are not evaluated.)
If any of the expressions evaluate to a value other than @true-elem or
@false-elem, @and-elem reports an error.}
@; ----------------------------------------------------------------------
@defform*[[(... (name expression expression ...))]]{ @defform*[#:id [or or-id]
[(or expression expression expression ...)]]{
Calls the function named @racket[name]. The value of the call is the value of Evaluates to @true-elem as soon as one of the
@racket[name]'s body when every one of the function's variables are @racket[expression]s is @true-elem (and the expressions to the right of that
replaced by the values of the corresponding @racket[expression]s. expression are not evaluated.) If all of the @racket[expression]s are false,
the @or-elem expression evaluates to @racket[false].
The function named @racket[name] must defined before it can be called. The If any of the expressions evaluate to a value other than @true-elem or
number of argument @racket[expression]s must be the same as the number of arguments @false-elem, @or-elem reports an error.}
expected by the function.}
@; ----------------------------------------------------------------------
@defform*[#:id [check-expect check-expect-id]
[(check-expect expression expected-expression)]]{
Checks that the first @racket[expression] evaluates to the same value as the
@racket[expected-expression].}
@; ---------------------------------------------------------------------- @defform*[#:id [check-within check-within-id]
[(check-within expression expected-expression delta-expression)]]{
Checks that the first @racket[expression] evaluates to a value within
@racket[delta-expression] of the @racket[expected-expression]. If
@racket[delta-expression] is not a number, @check-within-elem reports an
error.}
@defform*[#:literals (cond else) @defform*[#:id [check-error check-error-id]
[(... (cond [question-expression answer-expression] ...)) [(check-error expression expression)
(... (cond [question-expression answer-expression] ... [else answer-expression]))]]{ (#,check-error-elem expression)]]{
Chooses a clause base on a condition. @racket[cond] finds the first Checks that the first @racket[expression] reports an error,
@racket[question-expression] which evaluates to @racket[true], then it evaluates where the error messages matches the string produced by the second
the corresponding @racket[answer-expression]. @racket[expression], if it is present.}
If none of the @racket[question-expression]s evaluates to @racket[true],
@racket[cond]'s value is the @racket[answer-expression] of the
@racket[else] clause. If there is no @racket[else], @racket[cond] reports
an error. If the result of a @racket[question-expression] is neither
@racket[true] nor @racket[false], @racket[cond] also reports an error.
@defidform/inline[else] cannot be used outside of @racket[cond]. @defform*[#:id [check-member-of check-member-of-id]
} [(check-member-of expression expression expression ...)]]{
Checks that the first @racket[expression] produces the same value
as one of the following @racket[expression]s.}
@; ---------------------------------------------------------------------- @defform*[#:id [check-range check-range-id]
[(check-range expression expression expression)]]{
Checks that the first @racket[expression] produces a number in
between the numbers produced by the second and third
@racket[expression]s, inclusive.}
@; ----------------------------------------------------------------------
@defform*[#:id [require require-id]
[(require string)]]{
Makes the definitions of the module specified by @racket[string]
available in the current module (i.e., the current file), where
@racket[string] refers to a file relative to the current file.
The @racket[string] is constrained in several ways to avoid
problems with different path conventions on different platforms: a
@litchar{/} is a directory separator, @litchar{.} always means the
current directory, @litchar{..} always means the parent directory,
path elements can use only @litchar{a} through @litchar{z}
(uppercase or lowercase), @litchar{0} through @litchar{9},
@litchar{-}, @litchar{_}, and @litchar{.}, and the string cannot be
empty or contain a leading or trailing @litchar{/}.}
@defform*[[(if test-expression then-expression else-expression)]]{ @defform/none[(#,require-elem module-name)]{
When the value of the @racket[test-expression] is @racket[true], Accesses a file in an installed library. The library name is an
@racket[if] evaluates the @racket[then-expression]. When the test is identifier with the same constraints as for a relative-path string
@racket[false], @racket[if] evaluates the @racket[else-expression]. (though without the quotes), with the additional constraint that it
must not contain a @litchar{.}.}
If the @racket[test-expression] is neither @racket[true] nor @defform/none[(#,require-elem (lib string string ...))]{
@racket[false], @racket[if] reports an error.}
@; ---------------------------------------------------------------------- Accesses a file in an installed library, making its definitions
available in the current module (i.e., the current file). The first
@racket[string] names the library file, and the remaining
@racket[string]s name the collection (and sub-collection, and so on)
where the file is installed. Each string is constrained in the same
way as for the @racket[(#,require-elem string)] form.}
@defform*[[(... (and expression expression expression ...))]]{ @defform/none[#:literals (planet)
(#,require-elem (planet string (string string number number)))]{
@racket[and] evaluates to @racket[true] if all the @racket[expression]s are Accesses a library that is distributed on the internet via the
@racket[true]. If any @racket[expression] is false, the @racket[and] @|PLaneT| server, making it definitions available in the current module
expression immediately evaluates to @racket[false] (the expressions to the (i.e., current file).}))
right of that expression are not evaluated.)
If any of the expressions evaluate to a value other than @racket[true] or
@racket[false], it is an error.}
@; ----------------------------------------------------------------------
@defform*[[(... (or expression expression expression ...))]]{
@racket[or] evaluates to @racket[true] as soon as one of the
@racket[expression]s is @racket[true] (the expressions to the right of that
expression are not evaluated.) If all the @racket[expression] are false,
@racket[or] is @racket[false].
If any of the expressions evaluate to a value other than @racket[true] or
@racket[false], @racket[or] reports an error.}
@; ----------------------------------------------------------------------
@defform*[[(check-expect expression expected-expression)]]{
Checks that the first @racket[expression] evaluates to the same value as the
@racket[expected-expression].}
@defform*[[(check-within expression expected-expression delta-expression)]]{
Checks that the first @racket[expression] evaluates to a value within
@racket[delta-expression] of the @racket[expected-expression]. If
@racket[delta-expression] is not a number, @racket[check-within] report an
error.}
@defform*[[(check-error expression expression)
(check-error expression)]]{
Checks that the first @racket[expression] reports an error,
where the error messages matches the string produced by the second
@racket[expression], if it is present.}
@defform*[[(... (check-member-of expression expression expression ...))]]{
Checks that the first @racket[expression] produces the same value as one of
the following @racket[expression]s.}
@defform*[[(check-range expression expression expression)]]{
Checks that the first @racket[expression] produces a number in between the numbers
produced by the second and third @racket[expression]s, inclusive.}
@; ----------------------------------------------------------------------
@defform*[[(require string)]]{
Makes the definitions of the module specified by @racket[string]
available in the current module (i.e., the current file), where @racket[string]
refers to a file relative to the current file.
The @racket[string] is constrained in several ways to avoid problems
with different path conventions on different platforms: a @litchar{/}
is a directory separator, @litchar{.} always means the current
directory, @litchar{..} always means the parent directory, path
elements can use only @litchar{a} through @litchar{z} (uppercase or
lowercase), @litchar{0} through @litchar{9}, @litchar{-}, @litchar{_},
and @litchar{.}, and the string cannot be empty or contain a leading
or trailing @litchar{/}.}
@defform/none[#:literals (require)
(require module-name)]{
Accesses a file in an installed library. The library name is an identifier
with the same constraints as for a relative-path string (though without the
quotes), with the additional constraint that it must not contain a
@litchar{.}.}
@defform/none[#:literals (require lib)
(... (require (lib string string ...)))]{
Accesses a file in an installed library, making its definitions
available in the current module (i.e., the current file). The first
@racket[string] names the library file, and the remaining
@racket[string]s name the collection (and sub-collection, and so on)
where the file is installed. Each string is constrained in the same
way as for the @racket[(require string)] form.}
@defform/none[#:literals (require planet)
(require (planet string (string string number number)))]{
Accesses a library that is distributed on the internet via the PLaneT
server, making it definitions available in the current module (i.e.,
current file).}
)))
;; ----------------------------------------
(define-syntax-rule (define-syntax-rule
(intermediate-forms lambda (intermediate-forms lambda
@ -346,119 +380,150 @@ current file).}
let* let*
let let
time) time)
(gen-intermediate-forms #'lambda @racket[lambda]
#'quote @racket[quote]
#'quasiquote @racket[quasiquote]
#'unquote @racket[unquote]
#'unquote-splicing @racket[unquote-splicing]
#'local @racket[local]
#'letrec @racket[letrec]
#'let* @racket[let*]
#'let @racket[let]
#'time @racket[time]))
(make-splice (define (gen-intermediate-forms lambda-id lambda-elem
(list quote-id quote-elem
quasiquote-id quasiquote-elem
unquote-id unquote-elem
unquote-splicing-id unquote-splicing-elem
local-id local-elem
letrec-id letrec-elem
let*-id let*-elem
let-id let-elem
time-id time-elem)
(list
@deftogether[(
@defform/none[(unsyntax @elem{@racketvalfont{'}@racket[name]})]
@defform/none[(unsyntax @elem{@racketvalfont{'}@racket[part]})]
@defform[#:id [quote quote-id] (quote name)]
@defform/none[(#,quote-elem part)]
)]{
@deftogether[( A quoted name is a symbol. A quote part is an abbreviation for a nested lists.
@defform/none[(unsyntax @elem{@racketvalfont{'}@racket[name]})]
@defform/none[(unsyntax @elem{@racketvalfont{'}@racket[part]})]
@defform[(quote name)]
@defform/none[(quote part)]
)]{
A quoted name is a symbol. A quote part is an abbreviation for a nested lists. Normally, this quotation is written with a @litchar{'}, like
@racket['(apple banana)], but it can also be written with
Normally, this quotation is written with a @litchar{'}, like @quote-elem, like @racket[(@#,quote-elem (apple banana))].}
@racket['(apple banana)], but it can also be written with @racket[quote], like
@racket[(@#,racket[quote] (apple banana))].}
@deftogether[( @deftogether[(
@defform/none[(unsyntax @elem{@racketvalfont{`}@racket[name]})] @defform/none[(unsyntax @elem{@racketvalfont{`}@racket[name]})]
@defform/none[(unsyntax @elem{@racketvalfont{`}@racket[part]})] @defform/none[(unsyntax @elem{@racketvalfont{`}@racket[part]})]
@defform[(quasiquote name)] @defform[#:id [quasiquote quasiquote-id]
@defform/none[(quasiquote part)] (quasiquote name)]
)]{ @defform/none[(#,quasiquote-elem part)]
)]{
Like @racket[quote], but also allows escaping to expression ``unquotes.'' Like @quote-elem, but also allows escaping to expression
``unquotes.''
Normally, quasi-quotations are written with a backquote, @litchar{`}, like Normally, quasi-quotations are written with a backquote,
@racket[`(apple ,(+ 1 2))], but they can also be written with @litchar{`}, like @racket[`(apple ,(+ 1 2))], but they can also be
@racket[quasiquote], like written with @quasiquote-elem, like
@racket[(@#,racket[quasiquote] (apple ,(+ 1 2)))].} @racket[(@quasiquote-elem (apple ,(+ 1 2)))].}
@deftogether[( @deftogether[(
@defform/none[(unsyntax @elem{@racketvalfont{,}@racket[expression]})] @defform/none[(unsyntax @elem{@racketvalfont{,}@racket[expression]})]
@defform[(unquote expression)] @defform[#:id [unquote unquote-id]
)]{ (unquote expression)]
)]{
Under a single quasiquote, @racketfont{,}@racket[expression] escapes from Under a single quasiquote, @racketfont{,}@racket[expression]
the quote to include an evaluated expression whose result is inserted escapes from the quote to include an evaluated expression whose
into the abbreviated list. result is inserted into the abbreviated list.
Under multiple quasiquotes, @racketfont{,}@racket[expression] is really Under multiple quasiquotes, @racketfont{,}@racket[expression] is
the literal @racketfont{,}@racket[expression], decrementing the quasiquote count really the literal @racketfont{,}@racket[expression], decrementing
by one for @racket[expression]. the quasiquote count by one for @racket[expression].
Normally, an unquote is written with @litchar{,}, but it can also be Normally, an unquote is written with @litchar{,}, but it can also be
written with @racket[unquote].} written with @|unquote-elem|.}
@deftogether[( @deftogether[(
@defform/none[(unsyntax @elem{@racketvalfont[",@"]@racket[expression]})] @defform/none[(unsyntax @elem{@racketvalfont[",@"]@racket[expression]})]
@defform[(unquote-splicing expression)] @defform[#:id [unquote-splicing unquote-splicing-id]
)]{ (unquote-splicing expression)]
)]{
Under a single quasiquote, @racketfont[",@"]@racket[expression] escapes from Under a single quasiquote, @racketfont[",@"]@racket[expression]
the quote to include an evaluated expression whose result is a list to escapes from the quote to include an evaluated expression whose
splice into the abbreviated list. result is a list to splice into the abbreviated list.
Under multiple quasiquotes, a splicing unquote is like an unquote; Under multiple quasiquotes, a splicing unquote is like an unquote;
that is, it decrements the quasiquote count by one. that is, it decrements the quasiquote count by one.
Normally, a splicing unquote is written with @litchar{,}, but it can Normally, a splicing unquote is written with @litchar{,}, but it
also be written with @racket[unquote-splicing].} can also be written with @|unquote-splicing-elem|.}
@defform[(... (local [definition ...] expression))]{
Groups related definitions for use in @racket[expression]. Each
@racket[definition] can be either a variable definition, a function
definition, or a structure definition, using the usual syntax.
When evaluating @racket[local], each @racket[definition] is evaluated in
order, and finally the body @racket[expression] is evaluated. Only the
expressions within the @racket[local] (including the right-hand-sides of
the @racket[definition]s and the @racket[expression]) may refer to the
names defined by the @racket[definition]s. If a name defined in the
@racket[local] is the same as a top-level binding, the inner one
``shadows'' the outer one. That is, inside the @racket[local], any
references to that name refer to the inner one.}
@; ----------------------------------------------------------------------
@defform[(... (letrec ([name expr-for-let] ...) expression))]{ @defform[#:id [local local-id]
(local [definition ...] expression)]{
Like @racket[local], but with a simpler syntax. Each @racket[name] defines Groups related definitions for use in @racket[expression]. Each
a variables (or a functions) with the value of the corresponding @racket[definition] can be either a variable definition, a function
@racket[expr-for-let]. If @racket[expr-for-let] is a @racket[lambda], definition, or a structure definition, using the usual syntax.
@racket[letrec] defines a function, otherwise it defines a variable.}
@defform[(... (let* ([name expr-for-let] ...) expression))]{ When evaluating @local-elem, each @racket[definition] is evaluated
in order, and finally the body @racket[expression] is
evaluated. Only the expressions within the @local-elem (including
the right-hand-sides of the @racket[definition]s and the
@racket[expression]) may refer to the names defined by the
@racket[definition]s. If a name defined in the @local-elem is the
same as a top-level binding, the inner one ``shadows'' the outer
one. That is, inside the @local-elem, any references to that name
refer to the inner one.}
Like @racket[letrec], but each @racket[name] can only be used in @; ----------------------------------------------------------------------
@racket[expression], and in @racket[expr-for-let]s occuring after that
@racket[name].}
@defform[(... (let ([name expr-for-let] ...) expression))]{ @defform[#:id [letrec letrec-id]
(letrec ([name expr-for-let] ...) expression)]{
Like @racket[letrec], but the defined @racket[name]s can be used only in Like @local-elem, but with a simpler syntax. Each @racket[name]
the last @racket[expression], not the @racket[expr-for-let]s next to the defines a variable (or a function) with the value of the
@racket[name]s.} corresponding @racket[expr-for-let]. If @racket[expr-for-let] is a
@lambda-elem, @letrec-elem defines a function, otherwise it
defines a variable.}
@; ---------------------------------------------------------------------- @defform[#:id [let* let*-id]
(let* ([name expr-for-let] ...) expression)]{
Like @letrec-elem, but each @racket[name] can only be used in
@racket[expression], and in @racket[expr-for-let]s occuring after
that @racket[name].}
@defform[(time expression)]{ @defform[#:id [let let-id]
(let ([name expr-for-let] ...) expression)]{
Measures the time taken to evaluate @racket[expression]. After evaluating Like @letrec-elem, but the defined @racket[name]s can be used only
@racket[expression], @racket[time] prints out the time taken by the in the last @racket[expression], not the @racket[expr-for-let]s
evaluation (including real time, time taken by the cpu, and the time spent next to the @racket[name]s.}
collecting free memory). The value of @racket[time] is the same as that of @racket[expression].}
))) @; ----------------------------------------------------------------------
@defform[#:id [time time-id]
(time expression)]{
Measures the time taken to evaluate @racket[expression]. After
evaluating @racket[expression], @racket[time] prints out the time
taken by the evaluation (including real time, time taken by the
CPU, and the time spent collecting free memory). The value of
@time-elem is the same as that of @racket[expression].}))
;; ----------------------------------------
(define (prim-ops lib ctx-stx) (define (prim-ops lib ctx-stx)
(let ([ops (map (lambda (cat) (let ([ops (map (lambda (cat)