reorganize guide to have the Scheme background in one section

svn: r6284
This commit is contained in:
Matthew Flatt 2007-05-25 01:30:00 +00:00
parent b82a2f7f8c
commit 75632a9cc3
11 changed files with 213 additions and 337 deletions

View File

@ -252,36 +252,40 @@
;; ----------------------------------------
(define/public (table-of-contents part ht)
(make-table #f (cdr (render-toc part))))
(make-table #f (render-toc part #t)))
(define/private (render-toc part)
(define/private (render-toc part skip?)
(let ([number (collected-info-number (part-collected-info part))])
(let ([l (cons
(list (make-flow
(list
(make-paragraph
(list
(make-element 'hspace (list (make-string (* 2 (length number)) #\space)))
(make-link-element (if (= 1 (length number))
"toptoclink"
"toclink")
(append
(format-number number
(list
(make-element 'hspace '(" "))))
(part-title-content part))
`(part ,(part-tag part))))))))
(apply
append
(map (lambda (p) (render-toc p)) (part-parts part))))])
(if (and (= 1 (length number))
(or (not (car number))
((car number) . > . 1)))
(cons (list (make-flow (list (make-paragraph (list
(make-element 'hspace (list "")))))))
l)
l))))
(let ([subs
(apply
append
(map (lambda (p) (render-toc p #f)) (part-parts part)))])
(if skip?
subs
(let ([l (cons
(list (make-flow
(list
(make-paragraph
(list
(make-element 'hspace (list (make-string (* 2 (length number)) #\space)))
(make-link-element (if (= 1 (length number))
"toptoclink"
"toclink")
(append
(format-number number
(list
(make-element 'hspace '(" "))))
(part-title-content part))
`(part ,(part-tag part))))))))
subs)])
(if (and (= 1 (length number))
(or (not (car number))
((car number) . > . 1)))
(cons (list (make-flow (list (make-paragraph (list
(make-element 'hspace (list "")))))))
l)
l))))))
;; ----------------------------------------
(super-new))))

View File

@ -19,9 +19,9 @@
(content->string content)
"_"))
(define/kw (title #:key [tag #f] #:body str)
(define/kw (title #:key [tag #f] [style #f] #:body str)
(let ([content (decode-content str)])
(make-title-decl (or tag (gen-tag content)) content)))
(make-title-decl (or tag (gen-tag content)) style content)))
(define/kw (section #:key [tag #f] #:body str)
(let ([content (decode-content str)])

View File

@ -14,6 +14,7 @@
(provide-structs
[title-decl ([tag any/c]
[style any/c]
[content list?])]
[part-start ([depth integer?]
[tag (or/c false/c string?)]
@ -48,14 +49,15 @@
null
(list (decode-paragraph (reverse (skip-whitespace accum))))))
(define (decode-flow* l tag title part-depth)
(let loop ([l l][next? #f][accum null][title title][tag tag])
(define (decode-flow* l tag style title part-depth)
(let loop ([l l][next? #f][accum null][title title][tag tag][style style])
(cond
[(null? l) (make-part tag
title
#f
(make-flow (decode-accum-para accum))
null)]
[(null? l) (make-styled-part tag
title
#f
(make-flow (decode-accum-para accum))
null
style)]
[(title-decl? (car l))
(unless part-depth
(error 'decode
@ -65,30 +67,35 @@
(error 'decode
"found extra title: ~v"
(car l)))
(loop (cdr l) next? accum (title-decl-content (car l)) (title-decl-tag (car l)))]
(loop (cdr l) next? accum
(title-decl-content (car l))
(title-decl-tag (car l))
(title-decl-style (car l)))]
[(or (paragraph? (car l))
(table? (car l))
(itemization? (car l))
(delayed-flow-element? (car l)))
(let ([para (decode-accum-para accum)]
[part (decode-flow* (cdr l) tag title part-depth)])
(make-part (part-tag part)
(part-title-content part)
(part-collected-info part)
(make-flow (append para
(list (car l))
(flow-paragraphs (part-flow part))))
(part-parts part)))]
[part (decode-flow* (cdr l) tag style title part-depth)])
(make-styled-part (part-tag part)
(part-title-content part)
(part-collected-info part)
(make-flow (append para
(list (car l))
(flow-paragraphs (part-flow part))))
(part-parts part)
(styled-part-style part)))]
[(part? (car l))
(let ([para (decode-accum-para accum)]
[part (decode-part (cdr l) tag title part-depth)])
(make-part (part-tag part)
(part-title-content part)
(part-collected-info part)
(make-flow (append para
(flow-paragraphs
(part-flow part))))
(cons (car l) (part-parts part))))]
[part (decode-flow* (cdr l) tag style title part-depth)])
(make-styled-part (part-tag part)
(part-title-content part)
(part-collected-info part)
(make-flow (append para
(flow-paragraphs
(part-flow part))))
(cons (car l) (part-parts part))
(styled-part-style part)))]
[(and (part-start? (car l))
(or (not part-depth)
((part-start-depth (car l)) . <= . part-depth)))
@ -109,38 +116,40 @@
(part-start-title s)
(add1 part-depth))]
[part (decode-part l tag title part-depth)])
(make-part (part-tag part)
(part-title-content part)
(part-collected-info part)
(make-flow para)
(cons s (part-parts part))))
(make-styled-part (part-tag part)
(part-title-content part)
(part-collected-info part)
(make-flow para)
(cons s (part-parts part))
(styled-part-style part)))
(loop (cdr l) (cons (car l) s-accum)))))]
[(splice? (car l))
(loop (append (splice-run (car l)) (cdr l)) next? accum title tag)]
[(null? (cdr l)) (loop null #f (cons (car l) accum) title tag)]
(loop (append (splice-run (car l)) (cdr l)) next? accum title tag style)]
[(null? (cdr l)) (loop null #f (cons (car l) accum) title tag style)]
[(and (pair? (cdr l))
(splice? (cadr l)))
(loop (cons (car l) (append (splice-run (cadr l)) (cddr l))) next? accum title tag)]
(loop (cons (car l) (append (splice-run (cadr l)) (cddr l))) next? accum title tag style)]
[(line-break? (car l))
(if next?
(loop (cdr l) #t accum title tag)
(loop (cdr l) #t accum title tag style)
(let ([m (match-newline-whitespace (cdr l))])
(if m
(let ([part (loop m #t null title tag)])
(make-part (part-tag part)
(part-title-content part)
(part-collected-info part)
(make-flow (append (decode-accum-para accum)
(flow-paragraphs (part-flow part))))
(part-parts part)))
(loop (cdr l) #f (cons (car l) accum) title tag))))]
[else (loop (cdr l) #f (cons (car l) accum) title tag)])))
(let ([part (loop m #t null title tag style)])
(make-styled-part (part-tag part)
(part-title-content part)
(part-collected-info part)
(make-flow (append (decode-accum-para accum)
(flow-paragraphs (part-flow part))))
(part-parts part)
(styled-part-style part)))
(loop (cdr l) #f (cons (car l) accum) title tag style))))]
[else (loop (cdr l) #f (cons (car l) accum) title tag style)])))
(define (decode-part l tag title depth)
(decode-flow* l tag title depth))
(decode-flow* l tag #f title depth))
(define (decode-flow l)
(part-flow (decode-flow* l #f #f #f)))
(part-flow (decode-flow* l #f #f #f #f)))
(define (match-newline-whitespace l)
(cond

View File

@ -3,6 +3,7 @@
(require "struct.ss"
(lib "class.ss")
(lib "file.ss")
(lib "list.ss")
(lib "runtime-path.ss")
(prefix xml: (lib "xml.ss" "xml")))
(provide render-mixin
@ -14,7 +15,8 @@
(define current-subdirectory (make-parameter #f))
(define current-output-file (make-parameter #f))
(define on-separate-page (make-parameter #f))
(define on-separate-page (make-parameter #t))
(define next-separate-page (make-parameter #f))
(define collecting-sub (make-parameter 0))
;; ----------------------------------------
@ -243,9 +245,15 @@
(define/override (part-whole-page? d)
(= 2 (collecting-sub)))
(define/private (toc-part? d)
(and (styled-part? d)
(eq? 'toc (styled-part-style d))))
(define/override (collect-part d parent ht number)
(let ([prev-sub (collecting-sub)])
(parameterize ([collecting-sub (add1 prev-sub)])
(parameterize ([collecting-sub (if (toc-part? d)
1
(add1 prev-sub))])
(if (= 1 prev-sub)
(let ([filename (derive-filename d)])
(parameterize ([current-output-file (build-path (path-only (current-output-file))
@ -275,19 +283,43 @@
(inherit render-table)
(define/private (find-siblings d)
(let ([parent (collected-info-parent (part-collected-info d))])
(let loop ([l (if parent
(part-parts parent)
(if (null? (part-parts d))
(list d)
(list d (car (part-parts d)))))]
[prev #f])
(cond
[(eq? (car l) d) (values prev
(and (pair? (cdr l))
(cadr l)))]
[else (loop (cdr l) (car l))]))))
(define/private (navigation d ht)
(let ([parent (collected-info-parent (part-collected-info d))])
(let-values ([(prev next)
(let loop ([l (if parent
(part-parts parent)
(if (null? (part-parts d))
(list d)
(list d (car (part-parts d)))))]
[prev #f])
(cond
[(eq? (car l) d) (values prev (and (pair? (cdr l))
(cadr l)))]
[else (loop (cdr l) (car l))]))])
(let*-values ([(prev next) (find-siblings d)]
[(prev) (if prev
(let loop ([prev prev])
(if (and (toc-part? prev)
(pair? (part-parts prev)))
(loop (car (last-pair (part-parts prev))))
prev))
(and parent
(toc-part? parent)
parent))]
[(next) (cond
[(and (toc-part? d)
(pair? (part-parts d)))
(car (part-parts d))]
[(and (not next)
parent
(toc-part? parent))
(let-values ([(prev next)
(find-siblings parent)])
next)]
[else next])])
(render-table (make-table
'at-right
(list
@ -306,13 +338,17 @@
sep-element
(if parent
(make-element
(make-target-url "index.html")
(make-target-url
(if (toc-part? parent)
(derive-filename parent)
"index.html"))
up-content)
"")
sep-element
(make-element
(and next
(make-target-url (derive-filename next)))
(if next
(make-target-url (derive-filename next))
"nonavigation")
next-content))))))))
d
ht))))
@ -321,7 +357,8 @@
(let ([number (collected-info-number (part-collected-info d))])
(cond
[(and (not (on-separate-page))
(= 1 (length number)))
(or (= 1 (length number))
(next-separate-page)))
;; Render as just a link, and put the actual
;; content in a new file:
(let* ([filename (derive-filename d)]
@ -334,16 +371,19 @@
'truncate/replace)
null))]
[else
(if ((length number) . <= . 1)
;; Navigation bars;
`(,@(navigation d ht)
(p nbsp)
,@(super render-part d ht)
(p nbsp)
,@(navigation d ht)
(p nbsp))
;; Normal section render
(super render-part d ht))])))
(let ([sep? (on-separate-page)])
(parameterize ([next-separate-page (toc-part? d)]
[on-separate-page #f])
(if sep?
;; Navigation bars;
`(,@(navigation d ht)
(p nbsp)
,@(super render-part d ht)
(p nbsp)
,@(navigation d ht)
(p nbsp))
;; Normal section render
(super render-part d ht))))])))
(super-new)))

View File

@ -202,11 +202,8 @@
font-family: monospace;
}
.navigation {
color: red;
text-align: right;
font-size: medium;
font-style: italic;
.nonavigation {
color: gray;
}
.disable {

View File

@ -56,6 +56,7 @@
[collected-info (or/c false/c collected-info?)]
[flow flow?]
[parts (listof part?)])]
[(styled-part part) ([style any/c])]
[(unnumbered-part part) ()]
[flow ([paragraphs (listof flow-element?)])]
[paragraph ([content list?])]

View File

@ -5,26 +5,23 @@
@title{A Guide to PLT Scheme}
This guide is intended for programmers who are new to Scheme, new to
PLT Scheme, or new to some part of PLT Scheme.
This guide is intended for programmers who are new to Scheme, new to PLT
Scheme, or new to some part of PLT Scheme. It definitely assumes some
programming experience. If you are new to programming, consider
instead reading @|HtDP|. If you want a quick and pretty overview of PLT
Scheme, start with @|Quick|.
If you are new to programming, consider instead reading @|HtDP|.
If you want a quicker, prettier, higher-level overview of PLT Scheme,
start with @|Quick|.
For everyone else, this guide assumes some programming experience.
After a somewhat gentle introduction to Scheme (chapters 1 through 4),
we dive into the details of putting Scheme to work. This guide covers
much of the PLT Scheme toolbox, but it leaves the precise details
to @|MzScheme| and other reference manuals.
@seclink["to-scheme"]{Chapter 2} provides a somewhat gentle
introduction to Scheme. After that, this guide dives into the details
of putting Scheme to work. Even though this guide covers much of the
PLT Scheme toolbox, it leaves precise details to @|MzScheme| and other
reference manuals.
@table-of-contents[]
@include-section["welcome.scrbl"]
@include-section["syntax.scrbl"]
@include-section["lists.scrbl"]
@include-section["truth.scrbl"]
@include-section["to-scheme.scrbl"]
@; ----------------------------------------------------------------------
@section[#:tag "datatypes"]{Built-In and Programmer-Defined Datatypes}

View File

@ -118,7 +118,7 @@ the @scheme[fold-for] syntax as follows:
@interaction[
(fold-for ([sum 0])
([elem (list 1 2 3)])
(+ sum elem))
(+ sum (* elem elem)))
]
Compare to analogous Java code, where @scheme[(list 1 2 3)] is
@ -128,7 +128,7 @@ replaced by a collection @scheme[lst]:
#<<EOS
int sum = 0;
for (Object elem : lst) {
sum = sum + elem;
sum = sum + elem * elem;
}
return sum;
EOS
@ -187,7 +187,7 @@ Scheme programmers tend to use them, partly because the syntax is
simpler (just a procedure call).
We have ignored several other variants of the interation
form---including plain @scheme[for], which is use when the iteration
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["iterations+comprehensions"].

View File

@ -4,29 +4,29 @@
@require[(lib "bnf.ss" "scribble")]
@require["guide-utils.ss"]
@title[#:tag "syntax-overview"]{Basic Scheme Syntax}
@title[#:tag "syntax-overview"]{Simple Definitions and Expressions}
The syntax of a Scheme program is specified in an unusual way compared
to most programming languages. In particular, importing a module can
introduce new definition and expression forms, so the syntax of a
Scheme module cannot be written as a context-free grammar. Even more
radically, the language name after @schemefont{#module} determines the
token-level syntax of the code that follows it.
A program module is written as
As a starting point, however, we can pretend that Scheme's syntax
follows a context-free grammar. We'll start with this approximation,
and work from there to build up a more complete picture of the
language.
@schemeblock[
#, @BNF-seq[@litchar{#module} @nonterm{langname} @kleenestar{@nonterm{topform}}]
]
The following BNF grammar sketches a simplified syntax for Scheme.
Text with a gray background, such as @litchar{#module}, represents
literal text. Whitespace must appear between separate such literals
and nonterminals like @nonterm{id}, except that whitespace is
not required before or after @litchar{(}, @litchar{)}, @litchar{[}, or
@litchar{]}. Following the usual conventions, @kleenestar{} means
zero or more repetitions of the preceding element, @kleeneplus{} means
one or more repetitions of the preceding element, and @BNF-group{}
groups a sequence as an element for repetition.
where a @nonterm{topform} is either a @nonterm{definition} or an
@nonterm{expr}. The REPL also evaluates @nonterm{topform}s.
In syntax specifications, text with a gray background, such as
@litchar{#module}, represents literal text. Whitespace must appear
between separate such literals and nonterminals like @nonterm{id},
except that whitespace is not required before or after @litchar{(},
@litchar{)}, @litchar{[}, or @litchar{]}. A comment, which starts
with @litchar{;} and runs until the end of the line, is treated the
same as whitespace.
Following the usual conventions, @kleenestar{} in a grammar means zero
or more repetitions of the preceding element, @kleeneplus{} means one
or more repetitions of the preceding element, and @BNF-group{} groups
a sequence as an element for repetition.
@define[val-defn-stx @BNF-seq[@litchar{(}@litchar{define} @nonterm{id} @nonterm{expr} @litchar{)}]]
@define[fun-defn-stx
@ -57,29 +57,6 @@ groups a sequence as an element for repetition.
@define[let-expr-stx (make-let-expr-stx @litchar{let})]
@define[let*-expr-stx (make-let-expr-stx @litchar{let*})]
@BNF[(list @nonterm{module} @BNF-seq[@litchar{#module} @nonterm{langname} @kleenestar{@nonterm{topform}}])
(list @nonterm{topform} @nonterm{definition}
@nonterm{expr}
@BNF-etc)
(list @nonterm{definition} val-defn-stx
fun-defn-stx
@BNF-etc)
(list @nonterm{expr} @nonterm{id}
@nonterm{constant}
app-expr-stx
if-expr-stx
lambda-expr-stx
let-expr-stx
let*-expr-stx
@BNF-etc)]
The syntax for comments, which are are treated the same as whitespace,
is not shown in the grammar above. A comment starts with @litchar{;}
and runs until the end of the line.
The REPL evaluates @nonterm{topform}s, just like the body of a module.
@;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@section{Definitions}
@ -116,18 +93,6 @@ piece
substring
]
Within a module, each definition must bind a distinct
@nonterm{id}, and only identifiers without an imported binding
can be defined. A definition in the REPL, in contrast, overwrites any
previous definition for the same @nonterm{id}.
@examples[
(define five 5)
(substring "hello world" 0 five)
(define five 8)
(substring "hello world" 0 five)
]
A procedure definition can include multiple expressions for the
procedure's body. In that case, only the value of the last expression
is returned when the procedure is called. The other expressions are
@ -140,12 +105,10 @@ evaluated only for some side-effect, such as printing.
(greet "universe")
]
You should generally avoid side-effects in Scheme; printing is a
reasonable effect to use in some programs, but it's no substitute for
simply returning a value. In any case, you should understand that
multiple expressions are allowed in a definition body, because it
explains why the following @scheme[nogreet] procedure simply returns
its argument:
Scheme programmers prefer to avoid assignment statements; it's
important, though, to understand that multiple expressions are allowed
in a definition body, because it explains why the following
@scheme[nogreet] procedure simply returns its argument:
@def+int[
(define (nogreet name)
@ -187,66 +150,6 @@ more examples:
#, @schemeid[call/cc]
#, @schemeid[call-with-composable-continuation]
#, @schemeid[x-1+3i]
#, @schemeid[define]
]
Since @schemeid[define] is itself an identifier, you could
re-define @schemeid[define] in the REPL. That's rarely a good idea,
of course, and it's not allowed in any module where
@scheme[define] already has a meaning.
@;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@section{Constants}
Scheme constants include numbers, booleans, strings, and byte
strings. In documentation examples and in DrScheme, constant
expressions are shown in green.
@defterm{Numbers} are written in the usual way, including fractions
and imagnary numbers. Numbers that use decimal points or exponent
markers are implemented as double-precision floating-point numbers,
and they are called @defterm{inexact} numbers in Scheme
terminology. Other numbers are implemented as @defterm{exact} with
arbitrary precision. In the example number constants below, the ones
on the left are exact, and the ones on the right are inexact
approximations:
@schemeblock[
1 1.0
1/2 0.5
1+2i 1.0+2i
9999999999999999999999 1e+22
]
@defterm{Booleans} are @scheme[#t] for true and @scheme[#f] for
false. In conditionals, however, all non-@scheme[#f] values are
treated as true.
@defterm{Strings} are written between double quotes. Within a string,
backslash is an escaping character; for example, a backslash followed
by a double-quote includes a little double-quote in the string. Except
for an unescaped double-quote or backslash, any Unicode character can
appear in a string constant.
@schemeblock[
"hello world"
"A \"fancy\" string"
"\u03BBx:(\u03BC\u03B1.\u03B1\u2192\u03B1).xx"
]
When a constant is evaluated in the REPL, it typically prints the same
as its input syntax. In some cases, the printed form is a normalized
version of the input syntax. In other cases, the printed result of an
expression does not correspond to input syntax at all, such as when an
expression proceduces a procedure (instead of applying the
procedure). In documentation and in DrScheme's REPL, results are
printed in blue instead of green to highlight the difference between
an input expression and a printed result.
@examples[
(eval-example-string "1.0000")
(eval-example-string "\"A \\u0022fancy\\u0022 string\"")
string-append
]
@;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -426,10 +329,9 @@ few key places makes Scheme code even more readable.
@;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@section{Procedure Applications, Again}
In our pretend grammar of Scheme, we oversimplified in the description
of procedure applications. The actual syntax of a procedure
application allows an arbitrary expression for the procedure, instead
of just an @nonterm{id}:
In our earlier grammar procedure applications, we oversimplified. The
actual syntax of a procedure application allows an arbitrary
expression for the procedure, instead of just an @nonterm{id}:
@schemeblock[
#, app2-expr-stx
@ -557,14 +459,15 @@ louder
]
Note that the expression for @scheme[louder] in the second case is an
``anonymous'' procedure written with @scheme[lambda], but the compiler
infers a name, anyway, for the purpose of printing the procedure.
``anonymous'' procedure written with @scheme[lambda], but, if
possible, the compiler infers a name, anyway, to make printing and
error reporting as informative as possible.
@;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@section[#:tag "local-binding-intro"]{Local Binding with with
@scheme[define], @scheme[let], and @scheme[let*]}
@section[#:tag "local-binding-intro"]{Local Binding with
@scheme[define], @scheme[let], and @scheme[let*]}
It's time to retract another simplification in our pretend grammar of
It's time to retract another simplification in our grammar of
Scheme. In the body of a procedure, definitions can appear before the
body expressions:
@ -623,36 +526,3 @@ use earlier bindings:
[z (+ x y)])
(format "adding ~s and ~s produces ~s" x y z))
]
@;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@section{The Language So Far}
As you saw, the little grammar that we showed at the
@seclink["syntax-overview"]{beginning} of the chapter turned out to be
too simple even for this chapter. Here's the grammar that we have now:
@BNF[(list @nonterm{module} @BNF-seq[@litchar{#module} @nonterm{langname} @kleenestar{@nonterm{topform}}])
(list @nonterm{topform} @nonterm{definition}
@nonterm{expr}
@BNF-etc)
(list @nonterm{definition} val-defn-stx
fun-defn2-stx
@BNF-etc)
(list @nonterm{expr} @nonterm{id}
@nonterm{constant}
app2-expr-stx
if-expr-stx
or-expr-stx
and-expr-stx
cond-expr-stx
lambda2-expr-stx
let-expr-stx
let*-expr-stx
@BNF-etc)]
For an expanded grammar, it's still a pretty small language! This
language is enough, however, to write lots of interesting programs.
Depending on your programming background, you may be struck by the
apparent absence of an iteration form. We'll add one in the next
chapter, but also explain why it isn't really necessary.

View File

@ -49,8 +49,8 @@ mistake, such as accidentally reversing the arguments to
Non-list pairs are used intentionally, sometimes. For example, the
@scheme[make-immutable-hash-table] procedure takes a list of pairs,
where the @scheme[car] of each pair is a key and the @scheme[cdr] is a
value.
where the @scheme[car] of each pair is a key and the @scheme[cdr] is an
arbitrary value.
The only thing more confusing to new Schemers than non-list pairs is
the printing convention for pairs where the second element @italic{is}
@ -182,11 +182,6 @@ Beware, however, that the REPL's printer recognizes the symbol
(eval:alts '(#, @schemevalfont{quote} #, @schemevalfont{road}) ''road)
]
There's a method to this madness; it has to do with the true nature of
Scheme syntax (which we discuss in the next section) and the
traditional Lisp approach to meta-programming (which we discuss in the
@seclink["quote-eval"]{section afterward}).
@;------------------------------------------------------------------------
@section{Lists and Scheme Syntax}
@ -225,35 +220,6 @@ way of writing @scheme[(+ 1 2)]. It is practically never a good idea
to write application expressions using this dot notation; it's just a
consequence of the way Scheme's syntax is defined.
The rule for converting @litchar{'} to a use of @scheme[quote] is also
defined at the read level. If you (accidentally) use
@schemeidfont{quote} as an identifier, the result makes sense only
when you understand the reader's conversion:
@def+int[
(define (shakespeare quot)
(list 'shakespeare 'says quot))
(shakespeare "to be or not to be")]
@schemeblock[
(define (shakey #, @schemeidfont{quote})
(list '#, @schemeidfont{shakey} '#, @schemeidfont{says} #, @schemeidfont{quote}))
]
@interaction[
(eval:alts (shakey "to be or not to be") (let ([shakey (lambda (x) x)]) ("to be or not to be" shakey)))
]
The second example fails because @scheme['#, @schemeidfont{shakey}] is
really @scheme[(#, @schemeidfont{quote} #, @schemeidfont{shakey})],
which means the application of @scheme[shakey]'s argument (which turns
out to be a string, not a procedure).
A few other character combinations trigger @litchar{'}-like
conversions, including @litchar{`}, @litchar{,}, @litchar["@,"], and
@litchar{#`}. Also, @litchar{#module big} triggers a read-time
conversion that bundles file content into a single
@scheme[module] declaration (see @secref["module"]).
Normally, @litchar{.} is allowed by the reader only with a
parenthesized sequence, and only before the last element of the
sequence. However, a pair of @litchar{.}s can also appear around a
@ -271,11 +237,3 @@ This two-dot convension is non-traditional, and it has essentially
nothing to do with the dot notation for non-list pairs. PLT Scheme
programmers use the infix convension sparingly---mostly for asymmetric
binary operators such as @scheme[<] and @scheme[is-a?].
@;------------------------------------------------------------------------
@section[#:tag "eval-quote"]{Traditional Metaprogramming}
[The whole quote and printer thing has to do with manipulating
programs as represented by pairs, symbols, etc. Not usually a good
idea anymore...]

View File

@ -9,7 +9,7 @@ Depending on how you look at it, @bold{PLT Scheme} is
@itemize{
@item{a @defterm{programming language}---a dialect of Scheme, which
@item{a @defterm{programming language}---a descendant of Scheme, which
is a dialect of Lisp;}
@item{a @defterm{family} of programming languages---variants of
@ -37,12 +37,12 @@ Most likely, you'll want to explore PLT Scheme using DrScheme,
especially at the beginning. If you prefer, you can also work with the
command-line @exec{mzscheme} interpreter and your favorite text
editor. The rest of this guide presents the language mostly
independent of the tool that you use.
independent of your choice of editor.
If you're using DrScheme, you'll need to set it in the right mode,
because DrScheme is less biased to a particular Scheme variant than
@exec{mzscheme}. Assuming that you've never used DrScheme before,
start it up, type the line
If you're using DrScheme, you'll need to choose the proper language,
because DrScheme accommodates many different variants of
Scheme. Assuming that you've never used DrScheme before, start it up,
type the line
@schememod[big]