doc work
svn: r6692
This commit is contained in:
parent
516146bb5c
commit
2fe7c75dc1
|
@ -154,7 +154,7 @@
|
||||||
(provide defproc defproc* defstruct defthing defform defform* defform/subs defform*/subs defform/none
|
(provide defproc defproc* defstruct defthing defform defform* defform/subs defform*/subs defform/none
|
||||||
specform specform/subs
|
specform specform/subs
|
||||||
specsubform specspecsubform specsubform/inline
|
specsubform specspecsubform specsubform/inline
|
||||||
schemegrammar
|
schemegrammar schemegrammar*
|
||||||
var svar void-const undefined-const)
|
var svar void-const undefined-const)
|
||||||
|
|
||||||
(define void-const
|
(define void-const
|
||||||
|
@ -295,8 +295,16 @@
|
||||||
(syntax-rules ()
|
(syntax-rules ()
|
||||||
[(_ #:literals (lit ...) id clause ...) (*schemegrammar '(lit ...)
|
[(_ #:literals (lit ...) id clause ...) (*schemegrammar '(lit ...)
|
||||||
'(id clause ...)
|
'(id clause ...)
|
||||||
(lambda () (list (scheme id) (schemeblock0 clause) ...)))]
|
(lambda () (list (list (scheme id) (schemeblock0 clause) ...))))]
|
||||||
[(_ id clause ...) (schemegrammar #:literals () id clause ...)]))
|
[(_ id clause ...) (schemegrammar #:literals () id clause ...)]))
|
||||||
|
(define-syntax schemegrammar*
|
||||||
|
(syntax-rules ()
|
||||||
|
[(_ #:literals (lit ...) [id clause ...] ...) (*schemegrammar '(lit ...)
|
||||||
|
'(id ... clause ... ...)
|
||||||
|
(lambda ()
|
||||||
|
(list
|
||||||
|
(list (scheme id) (schemeblock0 clause) ...) ...)))]
|
||||||
|
[(_ [id clause ...] ...) (schemegrammar #:literals () [id clause ...] ...)]))
|
||||||
(define-syntax var
|
(define-syntax var
|
||||||
(syntax-rules ()
|
(syntax-rules ()
|
||||||
[(_ id) (*var 'id)]))
|
[(_ id) (*var 'id)]))
|
||||||
|
@ -589,27 +597,34 @@
|
||||||
sub-procs))))
|
sub-procs))))
|
||||||
(flow-paragraphs (decode-flow (content-thunk)))))))
|
(flow-paragraphs (decode-flow (content-thunk)))))))
|
||||||
|
|
||||||
(define (*schemerawgrammar nonterm clause1 . clauses)
|
(define (*schemerawgrammars nonterms clauseses)
|
||||||
(make-table
|
(make-table
|
||||||
'((valignment baseline baseline baseline baseline baseline)
|
'((valignment baseline baseline baseline baseline baseline)
|
||||||
(alignment left left center left left))
|
(alignment right left center left left))
|
||||||
(let ([empty-line (make-flow (list (make-paragraph (list (tt 'nbsp)))))]
|
(let ([empty-line (make-flow (list (make-paragraph (list (tt 'nbsp)))))]
|
||||||
[to-flow (lambda (i) (make-flow (list (make-paragraph (list i)))))])
|
[to-flow (lambda (i) (make-flow (list (make-paragraph (list i)))))])
|
||||||
(cons
|
(apply append
|
||||||
(list (to-flow nonterm)
|
(map
|
||||||
empty-line
|
(lambda (nonterm clauses)
|
||||||
(to-flow "=")
|
(cons
|
||||||
empty-line
|
(list (to-flow nonterm)
|
||||||
(make-flow (list clause1)))
|
empty-line
|
||||||
(map (lambda (clause)
|
(to-flow "=")
|
||||||
(list empty-line
|
empty-line
|
||||||
empty-line
|
(make-flow (list (car clauses))))
|
||||||
(to-flow "|")
|
(map (lambda (clause)
|
||||||
empty-line
|
(list empty-line
|
||||||
(make-flow (list clause))))
|
empty-line
|
||||||
clauses)))))
|
(to-flow "|")
|
||||||
|
empty-line
|
||||||
|
(make-flow (list clause))))
|
||||||
|
(cdr clauses))))
|
||||||
|
nonterms clauseses)))))
|
||||||
|
|
||||||
(define (*schemegrammar lits s-expr clauses-thunk)
|
(define (*schemerawgrammar nonterm clause1 . clauses)
|
||||||
|
(*schemerawgrammars (list nonterm) (list (cons clause1 clauses))))
|
||||||
|
|
||||||
|
(define (*schemegrammar lits s-expr clauseses-thunk)
|
||||||
(parameterize ([current-variable-list
|
(parameterize ([current-variable-list
|
||||||
(let loop ([form s-expr])
|
(let loop ([form s-expr])
|
||||||
(cond
|
(cond
|
||||||
|
@ -619,7 +634,8 @@
|
||||||
[(pair? form) (append (loop (car form))
|
[(pair? form) (append (loop (car form))
|
||||||
(loop (cdr form)))]
|
(loop (cdr form)))]
|
||||||
[else null]))])
|
[else null]))])
|
||||||
(apply *schemerawgrammar (clauses-thunk))))
|
(let ([l (clauseses-thunk)])
|
||||||
|
(*schemerawgrammars (map car l) (map cdr l)))))
|
||||||
|
|
||||||
(define (*var id)
|
(define (*var id)
|
||||||
(to-element (*var-sym id)))
|
(to-element (*var-sym id)))
|
||||||
|
|
|
@ -13,7 +13,7 @@ nevertheless implemented as structures, and we defer discussion of
|
||||||
objects to @secref["classes"].
|
objects to @secref["classes"].
|
||||||
|
|
||||||
@; ------------------------------------------------------------
|
@; ------------------------------------------------------------
|
||||||
@section{Simple Structure Types}
|
@section{Simple Structure Types: @scheme[define-struct]}
|
||||||
|
|
||||||
To a first approximation, the syntax of @scheme[define-struct] is
|
To a first approximation, the syntax of @scheme[define-struct] is
|
||||||
|
|
||||||
|
|
|
@ -87,6 +87,4 @@ form, a @scheme[_thing] is either an identifier or a keyword.
|
||||||
@include-section["cond.scrbl"]
|
@include-section["cond.scrbl"]
|
||||||
@include-section["begin.scrbl"]
|
@include-section["begin.scrbl"]
|
||||||
@include-section["set.scrbl"]
|
@include-section["set.scrbl"]
|
||||||
|
@include-section["quote.scrbl"]
|
||||||
@section{Quoted Data: @scheme[quote] and @scheme[quasiquote]}
|
|
||||||
|
|
||||||
|
|
|
@ -37,10 +37,6 @@ In the reference manual, the documentation for each procedure
|
||||||
describes the acceptable arguments and the result of the procedure
|
describes the acceptable arguments and the result of the procedure
|
||||||
using @idefterm{contracts}.
|
using @idefterm{contracts}.
|
||||||
|
|
||||||
@; ----------------------------------------------------------------------
|
|
||||||
@include-section["for.scrbl"]
|
|
||||||
|
|
||||||
|
|
||||||
@; ----------------------------------------------------------------------
|
@; ----------------------------------------------------------------------
|
||||||
@section[#:tag "classes"]{Classes and Objects}
|
@section[#:tag "classes"]{Classes and Objects}
|
||||||
|
|
||||||
|
@ -50,15 +46,11 @@ using @idefterm{contracts}.
|
||||||
|
|
||||||
|
|
||||||
@; ----------------------------------------------------------------------
|
@; ----------------------------------------------------------------------
|
||||||
@section[#:tag "threads"]{Threads}
|
@include-section["for.scrbl"]
|
||||||
|
|
||||||
|
|
||||||
@; ----------------------------------------------------------------------
|
@; ----------------------------------------------------------------------
|
||||||
@section[#:tag "guide:i/o"]{Input and Output}
|
@include-section["io.scrbl"]
|
||||||
|
|
||||||
|
|
||||||
@; ----------------------------------------------------------------------
|
|
||||||
@section[#:tag "guide:networking"]{Networking}
|
|
||||||
|
|
||||||
|
|
||||||
@; ----------------------------------------------------------------------
|
@; ----------------------------------------------------------------------
|
||||||
|
@ -68,11 +60,22 @@ using @idefterm{contracts}.
|
||||||
@; ----------------------------------------------------------------------
|
@; ----------------------------------------------------------------------
|
||||||
@section[#:tag "match"]{Pattern Matching}
|
@section[#:tag "match"]{Pattern Matching}
|
||||||
|
|
||||||
|
@subsection{Simple Dispatch: @scheme[case]}
|
||||||
|
|
||||||
|
The @scheme[case] form dispatches to a clause by matching the result
|
||||||
|
of an expression to the values for the clause:
|
||||||
|
|
||||||
|
@specform[(case [(_datum ...+) expr ...+]
|
||||||
|
...)]
|
||||||
|
|
||||||
|
|
||||||
@; ----------------------------------------------------------------------
|
@; ----------------------------------------------------------------------
|
||||||
@section[#:tag "units"]{Units (Higher-Order Modules)}
|
@section[#:tag "units"]{Units (Higher-Order Modules)}
|
||||||
|
|
||||||
|
|
||||||
|
@; ----------------------------------------------------------------------
|
||||||
|
@section[#:tag "threads"]{Threads}
|
||||||
|
|
||||||
@; ----------------------------------------------------------------------
|
@; ----------------------------------------------------------------------
|
||||||
@section[#:tag "guide:macros"]{Syntactic Extension@aux-elem{ (Modules and Macros)}}
|
@section[#:tag "guide:macros"]{Syntactic Extension@aux-elem{ (Modules and Macros)}}
|
||||||
|
|
||||||
|
@ -84,7 +87,6 @@ using @idefterm{contracts}.
|
||||||
@; ----------------------------------------------------------------------
|
@; ----------------------------------------------------------------------
|
||||||
@section[#:tag "macros"]{Reader Extension}
|
@section[#:tag "macros"]{Reader Extension}
|
||||||
|
|
||||||
|
|
||||||
@; ----------------------------------------------------------------------
|
@; ----------------------------------------------------------------------
|
||||||
@section[#:tag "security"]{Security}
|
@section[#:tag "security"]{Security}
|
||||||
|
|
||||||
|
|
14
collects/scribblings/guide/io.scrbl
Normal file
14
collects/scribblings/guide/io.scrbl
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
#reader(lib "docreader.ss" "scribble")
|
||||||
|
@require[(lib "manual.ss" "scribble")]
|
||||||
|
@require[(lib "eval.ss" "scribble")]
|
||||||
|
@require["guide-utils.ss"]
|
||||||
|
|
||||||
|
@title[#:tag "guide:i/o"]{Input and Output}
|
||||||
|
|
||||||
|
@; ----------------------------------------------------------------------
|
||||||
|
@section[#:tag "guide:networking"]{Networking}
|
||||||
|
|
||||||
|
|
||||||
|
@; ----------------------------------------------------------------------
|
||||||
|
@include-section["qq.scrbl"]
|
||||||
|
|
|
@ -157,7 +157,7 @@ an @scheme[_id] is referenced before its value is ready, the result is
|
||||||
@include-section["named-let.scrbl"]
|
@include-section["named-let.scrbl"]
|
||||||
|
|
||||||
@; ----------------------------------------
|
@; ----------------------------------------
|
||||||
@section{Multiple Values: @scheme[let-values], @scheme[let*-values], and @scheme[letrec-values]}
|
@section{Multiple Values: @scheme[let-values], @scheme[let*-values], @scheme[letrec-values]}
|
||||||
|
|
||||||
In the same way that @scheme[define-values] binds multiple
|
In the same way that @scheme[define-values] binds multiple
|
||||||
results in a definition (see @secref["guide:multiple-values"]),
|
results in a definition (see @secref["guide:multiple-values"]),
|
||||||
|
|
46
collects/scribblings/guide/qq.scrbl
Normal file
46
collects/scribblings/guide/qq.scrbl
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
#reader(lib "docreader.ss" "scribble")
|
||||||
|
@require[(lib "manual.ss" "scribble")]
|
||||||
|
@require[(lib "eval.ss" "scribble")]
|
||||||
|
@require["guide-utils.ss"]
|
||||||
|
|
||||||
|
@title{Quasiquoting}
|
||||||
|
|
||||||
|
[Explain why...]
|
||||||
|
|
||||||
|
@;------------------------------------------------------------------------
|
||||||
|
@section{Escapes: @scheme[quasiquote], @scheme[unquote], and @scheme[unquote-splicing]}
|
||||||
|
|
||||||
|
The @scheme[quasiquote] form is similar to @scheme[quote]:
|
||||||
|
|
||||||
|
@specform[(#,(schemekeywordfont "quasiquote") datum)]
|
||||||
|
|
||||||
|
However, for each @scheme[(#,(schemekeywordfont "unquote") _expr)]
|
||||||
|
that appears within the @scheme[_datum], the @scheme[_expr] is
|
||||||
|
evaluated to produce a value that takes the place of the
|
||||||
|
@scheme[unsyntax] sub-form.
|
||||||
|
|
||||||
|
@examples[
|
||||||
|
(eval:alts (#,(schemekeywordfont "quasiquote") (1 2 (#,(schemekeywordfont "unquote") (+ 1 2)) (#,(schemekeywordfont "unquote") (- 5 1))))
|
||||||
|
`(1 2 ,(+ 1 2), (- 5 1)))
|
||||||
|
]
|
||||||
|
|
||||||
|
The @scheme[unquote-splicing] form is similar to @scheme[unquote], but
|
||||||
|
its @scheme[_expr] must produce a list, and the
|
||||||
|
@scheme[unquote-splicing] form must appear in a context that produces
|
||||||
|
either a list of vector. As the name suggests, the resulting list
|
||||||
|
spliced into the context of its use.
|
||||||
|
|
||||||
|
@examples[
|
||||||
|
(eval:alts (#,(schemekeywordfont "quasiquote") (1 2 (#,(schemekeywordfont "unquote-splicing") (list (+ 1 2) (- 5 1))) 5))
|
||||||
|
`(1 2 ,@(list (+ 1 2) (- 5 1)) 5))
|
||||||
|
]
|
||||||
|
|
||||||
|
If a @scheme[quasiquote] form appears within an enclosing
|
||||||
|
@scheme[quasiquote] form, then the inner @scheme[quasiquote]
|
||||||
|
effectively cancels one layer of @scheme[unquote] and
|
||||||
|
@scheme[unquote-splicing] forms, so that a second @scheme[unquote]
|
||||||
|
or @scheme[unquote-splicing] is needed.
|
||||||
|
|
||||||
|
@;------------------------------------------------------------------------
|
||||||
|
@section{Abbreviating with @schememetafont{`}, @schememetafont{,}, and @schememetafont[",@"]}
|
||||||
|
|
65
collects/scribblings/guide/quote.scrbl
Normal file
65
collects/scribblings/guide/quote.scrbl
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
#reader(lib "docreader.ss" "scribble")
|
||||||
|
@require[(lib "manual.ss" "scribble")]
|
||||||
|
@require[(lib "eval.ss" "scribble")]
|
||||||
|
@require["guide-utils.ss"]
|
||||||
|
|
||||||
|
@title{Quoting: @scheme[quote] and @schemevalfont{'}}
|
||||||
|
|
||||||
|
The @scheme[quote] form produces a constant:
|
||||||
|
|
||||||
|
@specform[(#,(schemekeywordfont "quote") datum)]
|
||||||
|
|
||||||
|
The syntax of a @scheme[datum] is technically specified as anything
|
||||||
|
that the @scheme[read] function parses as a single element. The value
|
||||||
|
of the @scheme[quote] form is the same value that @scheme[read] would
|
||||||
|
produce given @scheme[_datum].
|
||||||
|
|
||||||
|
To a good approximation, the resulting value is such that
|
||||||
|
@scheme[_datum] is the value's printed representation. Thus, it can be
|
||||||
|
a symbol, a boolean, a number, a (character or byte) string, a
|
||||||
|
character, a keyword, an empty list, a pair (or list) containing more
|
||||||
|
such values, a vector containing more such values, a hash table
|
||||||
|
containing more such values, or a box containing another such value.
|
||||||
|
|
||||||
|
@examples[
|
||||||
|
(eval:alts (#,(schemekeywordfont "quote") apple) 'apple)
|
||||||
|
(eval:alts (#,(schemekeywordfont "quote") #t) #t)
|
||||||
|
(eval:alts (#,(schemekeywordfont "quote") 42) 42)
|
||||||
|
(eval:alts (#,(schemekeywordfont "quote") "hello") "hello")
|
||||||
|
(eval:alts (#,(schemekeywordfont "quote") ()) '())
|
||||||
|
(eval:alts (#,(schemekeywordfont "quote") ((1 2 3) #2("z" x) . the-end)) '((1 2 3) #2("z" x) . the-end))
|
||||||
|
(eval:alts (#,(schemekeywordfont "quote") (1 2 #,(schemeparenfont ".") (3))) '(1 2 . (3)))
|
||||||
|
]
|
||||||
|
|
||||||
|
As the last example above shows, the @scheme[_datum] does not have to
|
||||||
|
be the normalized printed form of a value. For example, A
|
||||||
|
@scheme[_datum] cannot be a printed representation that starts with
|
||||||
|
@litchar{#<}, however, so it cannot be @|void-const|,
|
||||||
|
@|undefined-const|, or a procedure.
|
||||||
|
|
||||||
|
The @scheme[quote] form is rarely used for a @scheme[_datum] that is a
|
||||||
|
boolean, number, or string by itself, since the printed forms of those
|
||||||
|
values can already be used as constants. The @scheme[quote] form is
|
||||||
|
more typically used for symbols and lists, which have other meanings
|
||||||
|
(identifiers, function calls, etc.) when not quoted.
|
||||||
|
|
||||||
|
An expression
|
||||||
|
|
||||||
|
@specform[(quote #,(scheme _datum))]
|
||||||
|
|
||||||
|
is a shorthand for
|
||||||
|
|
||||||
|
@schemeblock[
|
||||||
|
(#,(schemekeywordfont "quote") #,(scheme _datum))
|
||||||
|
]
|
||||||
|
|
||||||
|
and this shorthand is almost always used instead of
|
||||||
|
@scheme[quote]. The shorthand applies even within the @scheme[_datum],
|
||||||
|
so it can produce a list containing @scheme[quote].
|
||||||
|
|
||||||
|
@examples[
|
||||||
|
'apple
|
||||||
|
'"hello"
|
||||||
|
'(1 2 3)
|
||||||
|
(display '(you can 'me))
|
||||||
|
]
|
|
@ -164,5 +164,5 @@ they're fundamental limitations of the traditional top-level
|
||||||
environment, which Scheme and Lisp implementations have historically
|
environment, which Scheme and Lisp implementations have historically
|
||||||
fought with ad hoc command-line flags, compiler directives, and
|
fought with ad hoc command-line flags, compiler directives, and
|
||||||
build tools. The module system is to designed to avoid the problems,
|
build tools. The module system is to designed to avoid the problems,
|
||||||
so start with @schemefont{#module}, and you'll be happier with Scheme
|
so start with @schemefont{#module}, and you'll be happier with
|
||||||
in the long run.
|
PLT Scheme in the long run.
|
||||||
|
|
|
@ -3,47 +3,48 @@
|
||||||
|
|
||||||
@title[#:tag "mz:expansion"]{Syntax Expansion}
|
@title[#:tag "mz:expansion"]{Syntax Expansion}
|
||||||
|
|
||||||
Expansion recursively processes a syntax-wrapped datum to parse it. In
|
Expansion recursively processes a syntax object to parse it. In
|
||||||
general, the parsing of a datum depends on its outermost shape:
|
general, the parsing of a datum depends on its outermost shape:
|
||||||
|
|
||||||
@itemize{
|
@itemize{
|
||||||
|
|
||||||
@item{If it is a (syntax-wrapped) symbol, also known as an
|
@item{If it is a syntax-object symbol, also known as an
|
||||||
@defterm{identifier}, then a binding is determined using symbol
|
@defterm{identifier}, then a binding is determined using symbol
|
||||||
along with the lexical information in the symbol's syntax
|
along with the lexical information in the identifier. The
|
||||||
wrapper. The binding determines the next parsing step.}
|
binding determines the next parsing step.}
|
||||||
|
|
||||||
@item{If it is a (syntax-wrapped) pair whose first element is an
|
@item{If it is a syntax-object pair whose first element is an
|
||||||
identifier, then the identifier's binding is used (as in the
|
identifier, then the identifier's binding is used (as in the
|
||||||
preceding case).}
|
preceding case).}
|
||||||
|
|
||||||
@item{If it is a (syntax-wrapped) pair, then the symbol
|
@item{If it is a syntax-object pair, then a new syntax-object symbol
|
||||||
@scheme['#%app] is wrapped with the lexical context of the
|
@scheme['#%app] is created using the lexical context of the
|
||||||
pair's syntax wrapper. If the resulting @scheme[#%app]
|
pair. If the resulting @scheme[#%app] identifier has no
|
||||||
identifier has no binding, parsing fails with an
|
binding, parsing fails with an @scheme[exn:fail:syntax]
|
||||||
@scheme[exn:fail:syntax] exception. Otherwise, the new
|
exception. Otherwise, the new identifier is combined with the
|
||||||
identifier is @scheme[cons]ed with the pair, and then the pair
|
original pair to form a new syntax-object pair (using the same
|
||||||
is wrapped using the same context as the @scheme[#%app]
|
context as the original pair), and parsing starts again (i.e.,
|
||||||
identifier, and parsing starts again (i.e., it continues with
|
it continues with the preceding case).}
|
||||||
the preceding case).}
|
|
||||||
|
|
||||||
@item{If it is any other (syntax-wrapped) value, then the symbol
|
@item{If it is any other syntax object, then a new syntax-object
|
||||||
@scheme['#%datum] is wrapped with the lexical context of the
|
symbol @scheme['#%datum] is created using the lexical context
|
||||||
values syntax wrapper. If the resulting @scheme[#%datum]
|
of the original syntax object. If the resulting
|
||||||
identifier has no binding, parsing fails with an
|
@scheme[#%datum] identifier has no binding, parsing fails with
|
||||||
@scheme[exn:fail:syntax] exception. Otherwise, the new
|
an @scheme[exn:fail:syntax] exception. Otherwise, the new
|
||||||
identifier is @scheme[cons]ed with the pair, and then the pair
|
identifier is combined with the original syntax object in a new
|
||||||
is wrapped using the same context; parsing starts again (i.e.,
|
syntax-object pair (using the same context as the original
|
||||||
it continues with the second case above).}
|
pair), and parsing starts again (i.e., it continues with the
|
||||||
|
second case above).}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
For either of the first two steps, if the identifier has no binding,
|
For either of the first two steps, if the identifier has no binding,
|
||||||
then the symbol @scheme['#%top] is wrapped with the same lexical
|
then a new syntax-object symbol @scheme['#%top] is created using the
|
||||||
context as the identifier; is this @scheme[#%top] identifier has no
|
lexical context of the identifier; if this @scheme[#%top] identifier
|
||||||
binding, then parsing fails with an @scheme[exn:fail:syntax]
|
has no binding, then parsing fails with an @scheme[exn:fail:syntax]
|
||||||
exception. Otherwise, parsing starts again, using the binding for
|
exception. Otherwise, the new identifier is combined with the
|
||||||
@scheme[#%top].
|
original identifier in a new syntax-object pair (using the same
|
||||||
|
context as the original identifier), and parsing starts again.
|
||||||
|
|
||||||
Thus, the possibilities that do not fail lead to an identifier with a
|
Thus, the possibilities that do not fail lead to an identifier with a
|
||||||
particular binding. This binding refers to one of three things:
|
particular binding. This binding refers to one of three things:
|
||||||
|
@ -55,24 +56,24 @@ particular binding. This binding refers to one of three things:
|
||||||
associated value is to a procedure of one argument, the
|
associated value is to a procedure of one argument, the
|
||||||
procedure is called as a syntax transformer (see
|
procedure is called as a syntax transformer (see
|
||||||
@secref["transformers"]), and parsing starts again with the
|
@secref["transformers"]), and parsing starts again with the
|
||||||
syntax result. If the transformer binding is to any other kind
|
syntax-object result. If the transformer binding is to any
|
||||||
of value, parsing fails with an @scheme[exn:fail:syntax]
|
other kind of value, parsing fails with an
|
||||||
exception.}
|
@scheme[exn:fail:syntax] exception.}
|
||||||
|
|
||||||
@item{A variable binding, such as introduced by a module-level
|
@item{A variable binding, such as introduced by a module-level
|
||||||
@scheme[define] or by @scheme[let]. In this case, if the form
|
@scheme[define] or by @scheme[let]. In this case, if the form
|
||||||
being parsed is just an identifier, then it is parsed as a
|
being parsed is just an identifier, then it is parsed as a
|
||||||
run-time reference to the location of the corersponding
|
run-time reference to the location of the corersponding
|
||||||
variable. If the form being parsed is a (syntax-wrapped) list,
|
variable. If the form being parsed is a syntax-object list,
|
||||||
then an @scheme[#%app] is added to the from of the list in the
|
then an @scheme[#%app] is added to the front of the
|
||||||
same way as when the kfirst thing in the list is not an
|
syntax-object list in the same way as when the first item in
|
||||||
identifier (third case in the prvious enumeration), and parsing
|
the syntax-object list is not an identifier (third case in the
|
||||||
continues.}
|
previous enumeration), and parsing continues.}
|
||||||
|
|
||||||
@item{Core syntax, which is parsed as described in the reminder of
|
@item{Core syntax, which is parsed as described in
|
||||||
this section. Parsing core syntactic forms typically involves
|
@secref["mz:syntax"]. Parsing core syntactic forms typically
|
||||||
recursive parsing of sub-forms, and may introduce bindings that
|
involves recursive parsing of sub-forms, and may introduce
|
||||||
control the parsing of sub-forms.}
|
bindings that control the parsing of sub-forms.}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,58 +102,101 @@ possible contexts are as follows:
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Different core syntax forms parse sub-forms in different contexts. For
|
||||||
|
example, a @scheme[let] form always parses the right-hand expressions
|
||||||
|
of a binding in an expression context, but it starts parsing the body
|
||||||
|
in an internal-definition context.
|
||||||
|
|
||||||
@section[#:tag "mz:intdef-body"]{Internal Definitions}
|
@section[#:tag "mz:intdef-body"]{Internal Definitions}
|
||||||
|
|
||||||
@section{Fully Expanded Programs}
|
An internal-definition context corresponds to a partial expansion
|
||||||
|
step. A form that supports internal definitions starts by expanding
|
||||||
|
its first form in an internal-definition context, but only
|
||||||
|
partially. That is, it recursively expands only until the form becomes
|
||||||
|
one of the following:
|
||||||
|
|
||||||
|
@itemize{
|
||||||
|
|
||||||
|
@item{A @scheme[define-values] or @scheme[define-syntaxes] form: The
|
||||||
|
definition form is not expanded further. Instead, the next form
|
||||||
|
is expanded partially, and so on. As soon as an expression form
|
||||||
|
is found, the accumulated definition forms are converted to a
|
||||||
|
@scheme[letrec-values] (if no @scheme[define-syntaxes] forms
|
||||||
|
were found) or @scheme[letrec-syntaxes+values] form, moving the
|
||||||
|
expression forms to the body to be expanded in expression
|
||||||
|
context.
|
||||||
|
|
||||||
|
When a @scheme[define-values] form is discovered, the lexical
|
||||||
|
context of all syntax objects for the body sequence is
|
||||||
|
immediately enriched with bindings for the
|
||||||
|
@scheme[define-values] form before expansion continues. When a
|
||||||
|
@scheme[define-syntaxes] form is discovered, the right-hand
|
||||||
|
side is executed and a transformer binding is installed before
|
||||||
|
expansion continues.}
|
||||||
|
|
||||||
|
@item{A primitive expression form other than @scheme[begin]: The
|
||||||
|
expression will be further expanded in an expression context,
|
||||||
|
along with all remaining body forms. If any definitions were
|
||||||
|
found, this expansion takes place after conversion to a
|
||||||
|
@scheme[letrec-values] or @scheme[letrec-syntaxes+values]
|
||||||
|
form. Otherwise, the expressions are expanded immediately in an
|
||||||
|
expression context.}
|
||||||
|
|
||||||
|
@item{A @scheme[begin] form: The sub-forms of the @scheme[begin] are
|
||||||
|
spliced into the internal-definition sequence, and partial
|
||||||
|
expansion continues with the first of the newly-spliced forms
|
||||||
|
(or the next form, if the @scheme[begin] had no sub-forms).}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@section[#:tag "mz:fully-expanded"]{Fully Expanded Programs}
|
||||||
|
|
||||||
A fully expanded program---that is, a parsed program---is represented
|
A fully expanded program---that is, a parsed program---is represented
|
||||||
in the same way as an unparsed program: as a syntax-wrapped
|
in the same way as an unparsed program: as a syntax-object. However, a
|
||||||
combination of symbols, pairs, and other values. However, a fully
|
fully expanded program fits a specific grammar.
|
||||||
expanded program fits a specific grammar.
|
|
||||||
|
|
||||||
@schemeblock[
|
@schemegrammar*[
|
||||||
#, @is-one-of[@scheme[_top-level-expr]]
|
#:literals (#%expression module #%plain-module-begin begin provide
|
||||||
_general-top-level-expr
|
define-values define-syntaxes define-values-for-syntax
|
||||||
(#%expression _expr)
|
require require-for-syntax require-for-template
|
||||||
(module _id _name-id
|
#%plain-lambda case-lambda if begin begin0 let-values letrec-values
|
||||||
(#%plain-module-begin _module-level-expr ...))
|
set! quote-syntax quote with-continuation-mark
|
||||||
(begin _top-level-expr ...)
|
#%plain-app #%datum #%top #%variable-reference)
|
||||||
code:blank
|
[top-level-form general-top-level-form
|
||||||
#, @is-one-of[@scheme[_module-level-expr]]
|
(#%expression expr)
|
||||||
_general-top-level-expr
|
(module id name-id
|
||||||
(provide _provide-spec ...)
|
(#%plain-module-begin
|
||||||
code:blank
|
module-level-form ...))
|
||||||
#, @is-one-of[@scheme[_general-top-level-expr]]
|
(begin top-level-form ...)]
|
||||||
_expr
|
[module-level-form general-top-level-form
|
||||||
(define-values (_id ...) _expr)
|
(provide provide-spec ...)]
|
||||||
(define-syntaxes (_id ...) _expr)
|
[general-top-level-form expr
|
||||||
(define-values-for-syntax (_id ...) _expr)
|
(define-values (id ...) expr)
|
||||||
(require _require-spec ...)
|
(define-syntaxes (id ...) expr)
|
||||||
(require-for-syntax _require-spec ...)
|
(define-values-for-syntax (id ...) expr)
|
||||||
(require-for-template _require-spec ...)
|
(require require-spec ...)
|
||||||
code:blank
|
(require-for-syntax require-spec ...)
|
||||||
#, @is-one-of[@scheme[_expr]]
|
(require-for-template require-spec ...)]
|
||||||
_id
|
[expr id
|
||||||
(lambda _formals _expr ...+)
|
(#%plain-lambda formals expr ...+)
|
||||||
(case-lambda (_formals _expr ...+) ...)
|
(case-lambda (formals expr ...+) ...)
|
||||||
(if _expr _expr)
|
(if expr expr)
|
||||||
(if _expr _expr _expr)
|
(if expr expr expr)
|
||||||
(begin _expr ...+)
|
(begin expr ...+)
|
||||||
(begin0 _expr _expr ...)
|
(begin0 expr expr ...)
|
||||||
(let-values (((_id ...) _expr) ...) _expr ...+)
|
(let-values (((id ...) expr) ...)
|
||||||
(letrec-values (((_id ...) _expr) ...) _expr ...+)
|
expr ...+)
|
||||||
(set! _id _expr)
|
(letrec-values (((id ...) expr) ...)
|
||||||
(#, @scheme[quote] _datum)
|
expr ...+)
|
||||||
(quote-syntax _datum)
|
(set! id expr)
|
||||||
(with-continuation-mark _expr _expr _expr)
|
(#, @scheme[quote] datum)
|
||||||
(#%app _expr ...+)
|
(quote-syntax datum)
|
||||||
(#%datum . _datum)
|
(with-continuation-mark expr expr expr)
|
||||||
(#%top . _id)
|
(#%plain-app expr ...+)
|
||||||
(#%variable-reference _id)
|
(#%datum . datum)
|
||||||
(#%variable-reference (#%top . _id))
|
(#%top . id)
|
||||||
code:blank
|
(#%variable-reference id)
|
||||||
#, @is-one-of[@scheme[_formals]]
|
(#%variable-reference (#%top . id))]
|
||||||
(_id ...)
|
[formals (id ...)
|
||||||
(_id ...+ . _id)
|
(id ...+ . id)
|
||||||
_id
|
id]]
|
||||||
]
|
|
||||||
|
|
|
@ -137,7 +137,7 @@ each of its sub-expression. In addtion, some procedures (notably
|
||||||
a certain number of values.
|
a certain number of values.
|
||||||
|
|
||||||
@;------------------------------------------------------------------------
|
@;------------------------------------------------------------------------
|
||||||
@section{Top-Level and Module-Level Bindings}
|
@section{Top-Level and Module-Level Variables}
|
||||||
|
|
||||||
Given
|
Given
|
||||||
|
|
||||||
|
@ -147,7 +147,7 @@ then an algebra student simplifies @tt{x + 1} as follows:
|
||||||
|
|
||||||
@verbatim{ x + 1 = 10 + 1 = 11}
|
@verbatim{ x + 1 = 10 + 1 = 11}
|
||||||
|
|
||||||
Scheme works much the same way, in that a set of top-level bindings
|
Scheme works much the same way, in that a set of top-level variables
|
||||||
are available for substitutions on demand during evaluation. For
|
are available for substitutions on demand during evaluation. For
|
||||||
example, given
|
example, given
|
||||||
|
|
||||||
|
@ -191,7 +191,7 @@ a module is essentially a prefix on a defined name, so that different
|
||||||
modules can define the name.
|
modules can define the name.
|
||||||
|
|
||||||
Using @scheme[set!], a program can change the value associated with an
|
Using @scheme[set!], a program can change the value associated with an
|
||||||
existing top-level binding:
|
existing top-level variable:
|
||||||
|
|
||||||
@prog-steps/no-obj[
|
@prog-steps/no-obj[
|
||||||
[{(define x 10)}
|
[{(define x 10)}
|
||||||
|
@ -208,7 +208,7 @@ existing top-level binding:
|
||||||
@section{Objects and Imperative Update}
|
@section{Objects and Imperative Update}
|
||||||
|
|
||||||
In addition to @scheme[set!] for imperative update of top-level
|
In addition to @scheme[set!] for imperative update of top-level
|
||||||
bindings, various procedures enable the modification of elements
|
variables, various procedures enable the modification of elements
|
||||||
within a compound data structure. For example, @scheme[vector-set!]
|
within a compound data structure. For example, @scheme[vector-set!]
|
||||||
modifies the content of a vector.
|
modifies the content of a vector.
|
||||||
|
|
||||||
|
@ -292,8 +292,8 @@ create objects, such as @scheme[vector], add to the set of objects:
|
||||||
11]
|
11]
|
||||||
]
|
]
|
||||||
|
|
||||||
The distinction between a top-level binding is an object reference is
|
The distinction between a top-level variable is an object reference is
|
||||||
crucial. A top-level binding is not a value; each time a binding
|
crucial. A top-level variable is not a value; each time a variable
|
||||||
expression is evaluated, the value is extracted from the current set
|
expression is evaluated, the value is extracted from the current set
|
||||||
of definitions. An object reference, in contrast is a value, and
|
of definitions. An object reference, in contrast is a value, and
|
||||||
therefore needs no further evaluation. The model evaluation steps
|
therefore needs no further evaluation. The model evaluation steps
|
||||||
|
@ -409,14 +409,14 @@ new location:
|
||||||
17]
|
17]
|
||||||
]
|
]
|
||||||
|
|
||||||
A location is the same as a top-level binding, but when a location is
|
A location is the same as a top-level variable, but when a location is
|
||||||
generated, it (conceptually) uses a name that has not been used before
|
generated, it (conceptually) uses a name that has not been used before
|
||||||
and that cannot not be generated again or accessed directly.
|
and that cannot not be generated again or accessed directly.
|
||||||
|
|
||||||
Generating a location in this way means that @scheme[set!] evaluates
|
Generating a location in this way means that @scheme[set!] evaluates
|
||||||
for local variables in the same way as for top-level bindings, because
|
for local variables in the same way as for top-level variables,
|
||||||
the variable is always replaced with a location by the time the
|
because the local variable is always replaced with a location by the
|
||||||
@scheme[set!] form is evaluated:
|
time the @scheme[set!] form is evaluated:
|
||||||
|
|
||||||
@prog-steps[
|
@prog-steps[
|
||||||
[{(define <p1> (lambda (x) (begin (set! x 3) x)))}
|
[{(define <p1> (lambda (x) (begin (set! x 3) x)))}
|
||||||
|
@ -459,7 +459,7 @@ instance of @scheme[x] in @scheme[_expr].
|
||||||
@section{Identifiers, Variables, and Locations}
|
@section{Identifiers, Variables, and Locations}
|
||||||
|
|
||||||
A @defterm{variable} is a placeholder for a value, and an expressions
|
A @defterm{variable} is a placeholder for a value, and an expressions
|
||||||
in an initial program refer to variables. A top-level binding is both
|
in an initial program refer to variables. A top-level variable is both
|
||||||
a variable and a location. Any other variable is always replaced by a
|
a variable and a location. Any other variable is always replaced by a
|
||||||
location at run-time, so that evaluation of expressions involves only
|
location at run-time, so that evaluation of expressions involves only
|
||||||
locations. A single non-top-level variable, such as a procedure
|
locations. A single non-top-level variable, such as a procedure
|
||||||
|
@ -509,21 +509,87 @@ The syntax of a Scheme program is defined by
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
For details on the read phase, see @secref["mz:reader"]. Source code is
|
For details on the read phase, see @secref["mz:reader"]. Source code
|
||||||
normally read in @scheme[read-syntax] mode, otherwise it must be
|
is normally read in @scheme[read-syntax] mode, otherwise it must be
|
||||||
converted to syntax using @scheme[datum->syntax-object]; the expand
|
converted to syntax using @scheme[datum->syntax]; the expand phase is
|
||||||
phase is defined in terms of syntax objects.
|
defined in terms of syntax objects.
|
||||||
|
|
||||||
Expansion recursively processes a syntax-wrapped datum; for details,
|
An identifier, for example, is a syntax-object symbol, and the
|
||||||
see @secref["mz:expansion"]. Ultimately, expansion leads to the
|
identifier's binding is determined by lexical information attached to
|
||||||
synactic forms described in @secref["mz:syntax"].
|
the identifier. Expansion recursively processes a syntax object,
|
||||||
|
both using its lexical information and extending the information for
|
||||||
|
nested objects. For details, see @secref["mz:expansion"].
|
||||||
|
|
||||||
...
|
Ultimately, expansion produces a syntax object matching the grammar
|
||||||
|
of the forms in @secref["mz:fully-expanded"]. This fully-expanded
|
||||||
|
datum corresponds to a parsed expression, and lexical information on
|
||||||
|
its identifiers indicates the parse. For example, a @scheme[car]
|
||||||
|
identifier might have lexical information that designates it as the
|
||||||
|
@scheme[car] from the @schememodname[big] language (i.e., the built-in
|
||||||
|
@scheme[car]). Similarly, a @scheme[lambda] identifier's lexical
|
||||||
|
information may indicate that it represents a procedure form.
|
||||||
|
|
||||||
@;------------------------------------------------------------------------
|
@;------------------------------------------------------------------------
|
||||||
@section{Namespaces}
|
@section{Namespaces}
|
||||||
|
|
||||||
|
A @idefterm{namespace} is a top-level mapping from symbols to binding
|
||||||
|
information. It is the starting point for expanding an expression; a
|
||||||
|
syntax object produced by @scheme[read-syntax] has no initial
|
||||||
|
lexical context; the syntax object can be expanded after
|
||||||
|
initializing it with the mappings of a particular namespace.
|
||||||
|
|
||||||
|
A namespace maps each symbol to one of three possible bindings:
|
||||||
|
|
||||||
|
@itemize{
|
||||||
|
|
||||||
|
@item{a particular module-level binding from a particular module}
|
||||||
|
|
||||||
|
@item{a top-level transformer binding named by the symbol}
|
||||||
|
|
||||||
|
@item{a top-level variable named by the symbol}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
An ``empty'' namespace maps all symbols to top-level
|
||||||
|
variables. Importing a module into the top-level adjusts the namespace
|
||||||
|
bindings for all of the imported named. Evaluating a top-level
|
||||||
|
@scheme[define] form updates the namespace's mapping to refer to a
|
||||||
|
variable (if it does not already) and installs a value into the
|
||||||
|
variable.
|
||||||
|
|
||||||
|
In addition to its main mapping, each namespace encapsulates a
|
||||||
|
distinct set of top-level variables, as well as a potentially distinct
|
||||||
|
set of module instances. After a namespace is created, module
|
||||||
|
instances from existing namespaces can be attached to the new
|
||||||
|
namespace.
|
||||||
|
|
||||||
|
At all times during evaluation, some namespace is designated as the
|
||||||
|
@defterm{current namespace}. The current namespace has no particular
|
||||||
|
relationship, however, with the namespace used to expand the code that
|
||||||
|
is executing. Furthermore, a namespace is purely a top-level concept;
|
||||||
|
it does not encapsulate the full environment of an expression within
|
||||||
|
local binding forms.
|
||||||
|
|
||||||
|
In terms of the evaluation model, top-level variables from different
|
||||||
|
namespaces essentially correspond to definitions with different
|
||||||
|
prefixes. In particular, changing the current namespace during
|
||||||
|
evaluation does not change the variables to which executing
|
||||||
|
expressions refer.
|
||||||
|
|
||||||
@;------------------------------------------------------------------------
|
@;------------------------------------------------------------------------
|
||||||
@section{Threads}
|
@section{Threads}
|
||||||
|
|
||||||
|
Scheme supports multiple, pre-emptive threads of evaluation. In terms
|
||||||
|
of the evaluation model, this means that each step in evaluation
|
||||||
|
actually consists of multiple concurrent expressions, rather than a
|
||||||
|
single expression. The expressions all share the same objects and
|
||||||
|
top-level variables, so that they can communicate through shared
|
||||||
|
state. Most evaluation steps involve a single step in a single
|
||||||
|
expression, but certain synchronization primitives require multiple
|
||||||
|
threads to progress together in one step.
|
||||||
|
|
||||||
|
In addition to shared state, each thread has its own private state
|
||||||
|
that is accessed through @defterm{thread cells} and
|
||||||
|
@defterm{parameters}. In particular, the current namespace is a
|
||||||
|
thread-specific property implemented by a parameter; it is not a
|
||||||
|
global property.
|
||||||
|
|
|
@ -144,6 +144,9 @@ according to their order in the application form.
|
||||||
(#%app cons)
|
(#%app cons)
|
||||||
]}
|
]}
|
||||||
|
|
||||||
|
@defform[(#%plain-app proc-expr arg-expr ...)]{
|
||||||
|
Like @scheme[#%app], but without support for keyword arguments.
|
||||||
|
}
|
||||||
|
|
||||||
@;------------------------------------------------------------------------
|
@;------------------------------------------------------------------------
|
||||||
@section[#:tag "mz:lambda"]{Procedure Expressions: @scheme[lambda] and @scheme[case-lambda]}
|
@section[#:tag "mz:lambda"]{Procedure Expressions: @scheme[lambda] and @scheme[case-lambda]}
|
||||||
|
@ -284,6 +287,10 @@ support keyword and optional arguments.
|
||||||
(f 1 2 3)))
|
(f 1 2 3)))
|
||||||
]}
|
]}
|
||||||
|
|
||||||
|
@defform[(#%plain-lambda formals body ...+)]{
|
||||||
|
Like @scheme[lambda], but without support for keyword or optional arguments.
|
||||||
|
}
|
||||||
|
|
||||||
@;------------------------------------------------------------------------
|
@;------------------------------------------------------------------------
|
||||||
@section{Local Binding: @scheme[let], @scheme[let*], and @scheme[letrec]}
|
@section{Local Binding: @scheme[let], @scheme[let*], and @scheme[letrec]}
|
||||||
|
|
||||||
|
@ -513,10 +520,31 @@ ignoring the @scheme[body] results. The results of the @scheme[expr]
|
||||||
are the results of the @scheme[begin0] form, but the @scheme[expr] is
|
are the results of the @scheme[begin0] form, but the @scheme[expr] is
|
||||||
in tail position only if no @scheme[body]s are present.
|
in tail position only if no @scheme[body]s are present.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@examples[
|
@examples[
|
||||||
(begin0
|
(begin0
|
||||||
(values 1 2)
|
(values 1 2)
|
||||||
(printf "hi\n"))
|
(printf "hi\n"))
|
||||||
]}
|
]}
|
||||||
|
|
||||||
|
@;------------------------------------------------------------------------
|
||||||
|
@section{Continuation Marks: @scheme[with-continuation-marks]}
|
||||||
|
|
||||||
|
@defform[(with-continuation-mark key-expr val-expr result-expr)]{
|
||||||
|
Evaluates @scheme[key-expr] and @scheme[val-expr] in order to obtain a key and
|
||||||
|
value, respectively. The key and value are attached as a mark to the
|
||||||
|
current continuation frame (see @secref["mz:contmarks"]), and then
|
||||||
|
@scheme[result-expr] is evaluated in tail position.
|
||||||
|
}
|
||||||
|
|
||||||
|
@;------------------------------------------------------------------------
|
||||||
|
@section{Syntax Quoting: @scheme[quote-syntax]}
|
||||||
|
|
||||||
|
@defform[(quote-syntax datum)]{
|
||||||
|
Produces a syntax object that preserves
|
||||||
|
lexical and source-location information attached to @scheme[datum]
|
||||||
|
at expansion time.
|
||||||
|
|
||||||
|
@examples[
|
||||||
|
(syntax? (quote-syntax x))
|
||||||
|
]
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user