reference-manual work

svn: r6495
This commit is contained in:
Matthew Flatt 2007-06-06 01:13:51 +00:00
parent 5598e20814
commit 8d61bb4c70
22 changed files with 455 additions and 46 deletions

View File

@ -34,9 +34,9 @@
[(_ lang rest ...)
(with-syntax ([modtag (datum->syntax-object
#'here
'(unsyntax (schemefont "#module "))
`(unsyntax (schemefont ,(format "#module ~a" (syntax-e #'lang))))
#'lang)])
#'(schemeblock modtag lang rest ...))]))
#'(schemeblock modtag rest ...))]))
(define (to-element/result s)
(make-element "schemeresult" (list (to-element/no-color s))))
@ -137,8 +137,17 @@
;; ----------------------------------------
(provide margin-note)
(define (margin-note . c)
(make-styled-paragraph (list (make-element "refcontent"
c))
"refpara"))
;; ----------------------------------------
(provide defproc defproc* defstruct defthing defform defform* defform/none
specsubform specsubform/inline
specform specsubform specsubform/inline
var svar void-const undefined-const)
(define void-const
@ -190,11 +199,15 @@
(define-syntax specsubform
(syntax-rules ()
[(_ spec desc ...)
(*specsubform 'spec (lambda () (schemeblock0 spec)) (lambda () (list desc ...)))]))
(*specsubform 'spec #f (lambda () (schemeblock0 spec)) (lambda () (list desc ...)))]))
(define-syntax specform
(syntax-rules ()
[(_ spec desc ...)
(*specsubform 'spec #t (lambda () (schemeblock0 spec)) (lambda () (list desc ...)))]))
(define-syntax specsubform/inline
(syntax-rules ()
[(_ spec desc ...)
(*specsubform 'spec #f (lambda () (list desc ...)))]))
(*specsubform 'spec #f #f (lambda () (list desc ...)))]))
(define-syntax defthing
(syntax-rules ()
[(_ id result desc ...)
@ -429,9 +442,9 @@
forms form-procs))
(content-thunk)))))
(define (*specsubform form form-thunk content-thunk)
(define (*specsubform form has-kw? form-thunk content-thunk)
(parameterize ([current-variable-list
(append (let loop ([form form])
(append (let loop ([form (if has-kw? (cdr form) form)])
(cond
[(symbol? form) (if (meta-symbol? form)
null

View File

@ -1,7 +1,8 @@
(module scheme mzscheme
(require "struct.ss"
"basic.ss"
(lib "class.ss"))
(lib "class.ss")
(lib "for.ss"))
(provide define-code
to-element
@ -92,7 +93,8 @@
[l (syntax-line c)])
(let ([new-line? (and l (l . > . line))])
(when new-line?
(out "\n" no-color)
(for ([i (in-range (- l line))])
(out "\n" no-color))
(set! line l)
(set! col-map next-col-map)
(set! next-col-map (make-hash-table 'equal))

View File

@ -0,0 +1,50 @@
#reader(lib "docreader.ss" "scribble")
@require[(lib "manual.ss" "scribble")]
@require[(lib "eval.ss" "scribble")]
@require["guide-utils.ss"]
@title[#:tag "guide:application"]{Procedure Applications}
An expression of the form
@specsubform[
(_proc-expr _arg-expr ...)
]
is a procedure application when @scheme[_proc-expr] is not an
identifier that is bound as a transformer. The @scheme[...] in this
syntactic sketch means ``zero or more repetitions of the preceeding
element;'' that is, zero or more @scheme[_arg-expr]s.
A procedure application is evaluated by first evaluating the
@scheme[_proc-expr] and all @scheme[_arg-expr]s in order (left to
right). Then, if @scheme[_proc-expr] produced a procedure that accepts
as many arguments as supplied @scheme[_arg-expr]s, the procedure is
aplied. Otherwise, an exception is raised.
@examples[
(cons 1 null)
((lambda (x y z) (+ x y z)) 1 2 3)
(cons 1 2 3)
(1 2 3)
]
Some procedures, such as @scheme[cons], accept a fixed number of
arguments. Some procedures, such as @scheme[list], accept any number
of arguments. Some procedures accept a range of argument counts; for
example @scheme[substring] accepts either two or three arguments.
Some procedures accept @defterm{keyword arguments} in addition to
by-position arguments. To supply a keyword argument, include a keyword
followed by the addociated argument value. The order of keyword
arguments does not matter, nor does their position relative to
non-keyword arguments (as long as they follow the procedure
expression); keyword arguments are recognized by an applied procedure
using only the associated keyword, not the order.
@examples[
(need-an-example 1 #:arg 2)
(need-an-example #:arg 2 1)
]
@refdetails["mz:application"]{procedure applications}

View File

@ -0,0 +1,82 @@
#reader(lib "docreader.ss" "scribble")
@require[(lib "manual.ss" "scribble")]
@require[(lib "eval.ss" "scribble")]
@require["guide-utils.ss"]
@title{Identifiers and Binding}
The context of an expression determines the meaning of identifiers
that appear in the expression. In particular, starting a module with
the language @schememodname[big], as in
@schememod[big]
means that, within the module, the identifiers described in this guide
have the the meaning described here: @scheme[cons] refers to the
procedure that creates a pair, @scheme[car] refers to the procedure
that extracts the first element of a pair, and so on.
@margin-note{For information on the syntax of identifiers, see
@secref["symbols"].}
Forms like @scheme[define], @scheme[lambda], and @scheme[let]
associate a meaning with one or more identifiers; that is, they
@defterm{bind} identifier. The part of the program for which the
binding applies is the @defterm{scope} of the binding. The set of
bindings in effect for a given expression is the expression's
@defterm{environment}.
For example, in
@schememod[
big
(define f
(lambda (x)
(let ([y 5])
(+ x y))))
(f 10)
]
the @scheme[define] is a binding of @scheme[f], the @scheme[lambda]
has a binding for @scheme[x], and the @scheme[let] has a binding for
@scheme[y]. The scope of the binding for @scheme[f] is the entire
module; the scope of the @scheme[x] binding is @scheme[(let ([y 5]) (+
x y))]; and the scope of the @scheme[y] binding is just @scheme[(+ x
y)]. The environment of @scheme[(+ x y)] includes bindings for
@scheme[y], @scheme[x], and @scheme[f], as well as everything in
@schememodname[big].
A module-level @scheme[define] can bind only identifiers that are not
already bound within the module. For example, @scheme[(define cons 1)]
is a syntax error in a @schememodname[big] module, since @scheme[cons]
is provided by @schememodname[big]. A local @scheme[define] or other
binding forms, however, can give a new local binding for an identifier
that already has a binding; such a binding @defterm{shadows} the
existing binding.
@defexamples[
(define f
(lambda (append)
(define cons (append "ugly" "confusing"))
(let ([append 'this-was])
(list append cons))))
(f list)
]
Even identifiers like @scheme[define] and @scheme[lambda] get their
meanings from bindings, though they have @defterm{transformer}
bindings (whcih means that they define syntactic forms) instead of
value bindings. Since @scheme[define] has a transformer binding, the
identifier @schemeidfont{define} cannot be used by itself to get a
value. However, the normal binding for @schemeidfont{define} can be
shadowed.
@examples[
define
(eval:alts (let ([#, @schemeidfont{define} 5]) #, @schemeidfont{define}) (let ([define 5]) define))
]
Shadowing standard bindings in this way is rarely a good idea, but the
possibility is an inherent part of Scheme's flexibility.

View File

@ -5,7 +5,7 @@
@title[#:tag "datatypes" #:style 'toc]{Built-In Datatypes}
The @seclink["to-scheme"]{little Scheme section} introduced some of
The @seclink["to-scheme"]{previous chapter} introduced some of
Scheme's built-in datatype: numbers, booleans, strings, lists, and
procedures. This section provides a more complete coverage of the
built-in datatypes for simple forms of data.

View File

@ -0,0 +1,10 @@
#reader(lib "docreader.ss" "scribble")
@require[(lib "manual.ss" "scribble")]
@require[(lib "eval.ss" "scribble")]
@require["guide-utils.ss"]
@title{Definitions}
A definition can have the form
@specform[(define _id _expr)]

View File

@ -5,7 +5,7 @@
@interaction-eval[(require (lib "for.ss"))]
@title[#:tag "for"]{Iterations and Comprehensions}
@title[#:tag "guide:for"]{Iterations and Comprehensions}
The @scheme[for] family of syntactic forms support iteration over
@defterm{sequences}. Lists, vectors, strings, byte strings, input
@ -425,3 +425,5 @@ patterns that provide good performance is extensible, just like the
set of sequence values. The documentation for a sequence constructor
should indicate the performance impliciations of using it directly in
a @scheme[for] @scheme[_clause].
@refdetails["mz:for"]{iterations and comprehensions}

View File

@ -3,12 +3,18 @@
@require[(lib "eval.ss" "scribble")]
@require["guide-utils.ss"]
@title[#:tag "scheme-forms" #:style 'toc]{Programs and Expressions}
@title[#:tag "scheme-forms" #:style 'toc]{Expressions and Definitions}
The @secref["to-scheme"] chapter introduced some of Scheme's syntactic
forms: definitions, procedure applications, conditionals, procedures,
local binding, and some iteration forms. This section provides a more
complete coverage of the basic Scheme syntactic forms.
@local-table-of-contents[]
@include-section["module-basics.scrbl"]
@include-section["binding.scrbl"]
@include-section["apply.scrbl"]
@include-section["lambda.scrbl"]
@include-section["define.scrbl"]
@include-section["for.scrbl"]

View File

@ -22,14 +22,12 @@
(apply item (bold name) ", " desc))
(define/kw (refdetails tag #:body s)
(let ([c (decode-content (append (list "For more on ")
(apply margin-note
(decode-content (append (list "For more on ")
s
(list ", see "
(refsecref tag)
".")))])
(make-styled-paragraph (list (make-element "refcontent"
c))
"refpara")))
".")))))
(define (refsecref s)
(make-element #f (list (secref s) " in " MzScheme))))

View File

@ -28,6 +28,8 @@ precise details to @|MzScheme| and other reference manuals.
@include-section["forms.scrbl"]
@include-section["module-basics.scrbl"]
@; ----------------------------------------------------------------------
@section[#:tag "contracts"]{Contracts}

View File

@ -6,19 +6,27 @@
@title[#:tag "keywords"]{Keywords}
A @defterm{keyword} is similar to a symbol (see @secref["symbols"]),
but its printed form is prefixed with @schemefont{#:}. Unlike a
symbol, it's printed form is also its expression form.
but its printed form is prefixed with @schemefont{#:}.
@refdetails["mz:parse-keyword"]{the syntax of keywords}
@examples[
(string->keyword "apple")
#:apple
(eq? #:apple (string->keyword "apple"))
'#:apple
(eq? '#:apple (string->keyword "apple"))
]
Although keywords are values, they are intented for use as special
markers in argument lists and in certain syntactic forms.
Although keywords are values, an unquoted keyword is not an
expression, just as an unquoted identifier does not produce a symbol:
@examples[
not-a-symbol-expression
#:not-a-keyword-expression
]
Despite their similarities, keywords are used differently than
symbols. Keywords are intented for use (unquoted) as special markers
in argument lists and in certain syntactic forms.
@italic{Need some examples here, once we have more keyword-based
procedures and syntax in place...}

View File

@ -0,0 +1,159 @@
#reader(lib "docreader.ss" "scribble")
@require[(lib "manual.ss" "scribble")]
@require[(lib "eval.ss" "scribble")]
@require["guide-utils.ss"]
@title[#:tag "guide:lambda"]{Procedures}
A @scheme[lambda] expression creates a procedure. In the simplest
case, a @scheme[lambda] expression has the form
@specform[
(lambda (arg-id ...)
body-expr ...+)
]
The @scheme[...+] in this syntactic sketch means ``one or more
repetitions of the preceeding element;'' that is, one or more
@scheme[_body-expr]s.
A @scheme[lambda] form with @math{n} @scheme[_arg-id]s accepts
@math{n} arguments:
@interaction[
((lambda (x) x)
1)
((lambda (x y) (+ x y))
1 2)
((lambda (x y) (+ x y))
1)
]
A @scheme[lambda] expression can also have the form
@specform[
(lambda rest-id
body-expr ...+)
]
That is, a @scheme[lambda] expression can have a single
@scheme[_rest-id] that is not surrounded by parentheses. The resulting
procedure accepts any number of arguments, and the arguments are put
into a list bound to @scheme[_rest-id].
@examples[
((lambda x x)
1 2 3)
((lambda x x))
((lambda x (car x))
1 2 3)
]
Combining thes two styles, a @scheme[lambda] expression can have the
form
@specform[
(lambda (arg-id ...+ . rest-id)
body-expr ...+)
]
The result is a procedure that requires at least as many arguments as
@scheme[_arg-id]s, and also accepts any number of additional
arguments.
@examples[
((lambda (a b . x) (cons (/ a b) x))
1 2 3 4)
((lambda (a b . x) (cons (/ a b) x))
1 2)
((lambda (a b . x) (cons (/ a b) x))
1)
]
Support for optional and keyword arguments lead to even more
possibilities:
@itemize{
@item{Instead of just an @scheme[_arg-id], an form argument can be
@scheme[[_arg-id _default-expr]], which means that the argument
is optional. When the argument is not supplied,
@scheme[_default-expr] produces the default value. The
@scheme[_default-expr] can refer to any preceding
@scheme[_arg-id], and every following @scheme[_arg-id] must
have a default as well.
@examples[
((lambda (x [y 5]) (list x y))
1 2)
((lambda (x [y 5]) (list x y))
1)
((lambda (x [y (+ x 1)]) (list x y))
1)
(lambda ([x 5] y) (list x y))
]}
@item{Instead of just an @scheme[_arg-id], an form argument can be
@scheme[(code:line _keyword _arg-id)], which indicates a
by-keyword argument instead of a by-position argument. The
position of the keyword--identifier pair in the argument list
does not matter for matching with arguments in an application,
because it will be matched to an argument value by keyword
insteda of by position.
@examples[
((lambda (x #:second y) (list x y))
1 #:second 2)
((lambda (x #:second y) (list x y))
#:second 2 1)
((lambda (#:second y x) (list x y))
1 #:second 2)
((lambda (x #:second y) (list x y))
1 2)
((lambda (x #:second y) (list x y))
#:second 2)
]}
@item{The previous two possibilities can be combined to specify a
by-keyword argument with a default value.
@examples[
((lambda (x #:second [y 5]) (list x y))
1 #:second 2)
((lambda (x #:second [y 5]) (list x y))
1)
]}
}
The @scheme[case-lambda] form creates a procedure that can have
completely different behaviors depending on the number of arguments
that are supplied. A case-lambda expression has the form
@specform[
(case-lambda
[formals body-expr ...+]
...)
]
where each @scheme[_formals _body-expr ...+] is anlogous to
@scheme[(lambda _formals _body-expr ...+)]. That is, a
@scheme[_formals] can be @scheme[(_arg-id ...)], @scheme[_rest-id], or
@scheme[(_arg-id ... . _rest-id)].
Applying a procedure produced by @scheme[case-lambda] is like applying
a @scheme[lambda] for the first case that matches the number of given
arguments.
@examples[
((case-lambda [() 10][(x y) (+ x y)])
1 2)
((case-lambda [() 10][(x y) (+ x y)]))
((case-lambda [() 10][(x y) (+ x y)])
1)
]
A @scheme[case-lambda] procedure cannot directly support optional or
keyword arguments.
@refdetails["mz:lambda"]{procedure expressions}

View File

@ -189,7 +189,7 @@ simpler (just a procedure call).
We have ignored several other variants of the interation
form---including plain @scheme[for], which is used when the iteration
body is to be run only for its effect. For more complete information,
see @secref["for"].
see @secref["guide:for"].
@;------------------------------------------------------------------------
@section{List Iteration from Scratch}

View File

@ -3,4 +3,51 @@
@require[(lib "eval.ss" "scribble")]
@require["guide-utils.ss"]
@title{Module Basics}
@title{Modules}
Scheme definitions and expressions are normally written inside of a
module. Although a REPL evaluates definitions and expressions outide
of a module, and although @scheme[load] can evaluate definitions and
expressions from a file as if they appeared in a REPL interaction,
code that is meant to last for more than a few seconds belongs in a
module.
The space of modules is distinct from the space of normal Scheme
definitions. Since modules typically reside in files, the space of
module names is explicitly tied to the filesystem at run time. For
example, if the file @file{/home/molly/cake.ss} contains
@schememod[
big
(provide print-cake)
(code:comment #, @t{draws a cake with @scheme[n] candles})
(define (print-cake n)
(printf " ~a \n" (make-string n #\.))
(printf " .-~a-.\n" (make-string n #\|))
(printf " | ~a |\n" (make-string n #\space))
(printf "---~a---\n" (make-string n #\-)))
]
then it can be used as the source of a module whose full name is based
on the path @file{/home/molly/cake.ss}. Instead of using the full
path, however, the module is likely to be referenced by a releative
path. For example, a file @file{/home/molly/random-cake.ss} could use
the module like this:
@schememod[
big
(require "cake.ss")
(print-cake (random 30))
]
The relative reference @scheme[(require "cake.ss")] works because the
@file{cake.ss} module source is in the same directory as the
@file{random-cake.ss} file.
As you see in the above examples, @scheme[provide] and
@scheme[require] are module-level declarations that export and import
bindings between modules.

View File

@ -3,7 +3,7 @@
@require[(lib "eval.ss" "scribble")]
@require["guide-utils.ss"]
@title{Symbols}
@title[#:tag "symbols"]{Symbols}
A @defterm{symbol} is an atomic value that prints like an identifier.
An expression that starts with @litchar{'} and continues with an

View File

@ -12,6 +12,6 @@ skip to @secref["datatypes"].
@local-table-of-contents[]
@include-section["simple-data.scrbl"]
@include-section["syntax.scrbl"]
@include-section["simple-syntax.scrbl"]
@include-section["lists.scrbl"]
@include-section["truth.scrbl"]

View File

@ -29,8 +29,8 @@ initialized. Such early references are not possible for bindings that
corerspond to procedure arguments, @scheme[let] bindings, or
@scheme[let*] bindings; early reference requires a recursive binding
context, such as @scheme[letrec] or local @scheme[define]s in a
procedure body. Also, early references to top-level and module
top-level bindings raise an exception, instead of producing
procedure body. Also, early references to top-level and module-level
bindings raise an exception, instead of producing
@|undefined-const|. For these reasons, @undefined-const rarely
appears.

View File

@ -3,7 +3,9 @@
@title[#:tag "mz:derived-syntax"]{Derived Syntactic Forms}
@section{Iterations and Comprehensions: @scheme[for], @scheme[for/list], ...}
@section[#:tag "mz:for"]{Iterations and Comprehensions: @scheme[for], @scheme[for/list], ...}
@guideintro["guide:for"]{iterations and comprehensions}
@defform[(for (for-clause ...) . body)]{

View File

@ -137,7 +137,7 @@ each of its sub-expression. In addtion, some procedures (notably
a certain number of values.
@;------------------------------------------------------------------------
@section{Top-level and Module Bindings}
@section{Top-Level and Module-Level Bindings}
Given
@ -187,7 +187,7 @@ right-hand expression must be reduced to a value.
]
Most definitions in PLT Scheme are in modules. In terms of evaluation,
a module is simply a prefix on a defined name, so that different
a module is essentially a prefix on a defined name, so that different
modules can define the name.
Using @scheme[set!], a program can change the value associated with an
@ -476,7 +476,13 @@ location.
An @defterm{identifier} is source-program entity. Parsing a Scheme
program reveals that some identifiers correspond to variables, some
refer to syntactic forms, and some are quoted to produce a symbol or a
syntax object.
syntax object. An identifier @scheme[binds] another when the former is
parsed as a variable and the latter is parsed as a reference to the
former. An identifier is @scheme[bound] in a sub-expression if it
binds any uses of the identifier in the sub-expression that are not
otherwise bound within the sub-expression; conversely, a binding for a
sub-expression @defterm{shadows} any bindings in its context, so that
uses of an identifier refer to the shaodowing binding.
Throughout the documentation, identifiers are typeset to suggest the
way that they are parsed. A black, boldface identifier like

View File

@ -1,7 +1,9 @@
(module mz mzscheme
(require (lib "struct.ss" "scribble")
(lib "manual.ss" "scribble")
(lib "eval.ss" "scribble"))
(lib "eval.ss" "scribble")
(lib "decode.ss" "scribble")
(lib "kw.ss"))
(provide (all-from (lib "manual.ss" "scribble"))
(all-from (lib "eval.ss" "scribble")))
@ -14,4 +16,19 @@
(define-syntax Exn
(syntax-rules ()
[(_ s) (scheme s)]))
(provide exnraise Exn))
(provide exnraise Exn)
(provide Guide guideintro)
(define Guide
(italic (link "../guide/index.html" "A Guide to PLT Scheme")))
(define/kw (guideintro tag #:body s)
(apply margin-note
(decode-content (append (list "For an introduction to ")
s
(list ", see "
(secref tag)
" in "
Guide
"."))))))

View File

@ -63,7 +63,7 @@ the reference evaluates to the value in the location associated with
the binding.
When the expander encounters an @scheme[id] that is not bound by a
module or local binding, it converts the expression to @scheme[(#,
module-level or local binding, it converts the expression to @scheme[(#,
@schemeidfont{#%top} . id)] giving @schemeidfont{#%top} the lexical
context of the @scheme[id]; typically, that context refers to
@scheme[#%top].
@ -87,7 +87,9 @@ references are disallowed anywhere within a @scheme[module] form.
]}
@;------------------------------------------------------------------------
@section{Procedure Applications and @scheme[#%app]}
@section[#:tag "mz:application"]{Procedure Applications and @scheme[#%app]}
@guideintro["guide:application"]{procedure applications}
@defform/none[(proc-expr arg ...)]{
@ -146,7 +148,9 @@ according to their order in the application form.
@;------------------------------------------------------------------------
@section{Procedure Expressions: @scheme[lambda] and @scheme[case-lambda]}
@section[#:tag "mz:lambda"]{Procedure Expressions: @scheme[lambda] and @scheme[case-lambda]}
@guideintro["guide:lambda"]{procedure expressions}
@defform[(lambda formals* . body)]{
@ -314,8 +318,9 @@ within @scheme[body] to the procedure itself.}
Similar to @scheme[let], but evaluates the @scheme[val-expr]s one by
one, creating a location for each @scheme[id] as soon as the value is
available, and binding @scheme[id] in the remaining @scheme[val-expr]s
as well as the @scheme[body]. The @scheme[id]s need not be distinct.
availablek. The @scheme[id]s are bound in the remaining @scheme[val-expr]s
as well as the @scheme[body], and the @scheme[id]s need not be
distinct.
@examples[
(let ([x 1]