finish first draft of HtDP language docs

svn: r8179
This commit is contained in:
Matthew Flatt 2008-01-02 03:33:00 +00:00
parent e7b5653dd6
commit d4482c90ca
19 changed files with 1364 additions and 119 deletions

View File

@ -60,64 +60,4 @@
(all-from-except intermediate: lang/htdp-intermediate-lambda procedures
cons list* append)
("Reading and Printing"
(print (any -> void)
"to print the argument as a value to stdout")
(display (any -> void)
"to print the argument to stdout (without quotes on symbols and strings, etc.)")
(write (any -> void)
"to print the argument to stdout (in a traditional style that is somewhere between print and display)")
(pretty-print (any -> void)
"like write, but with standard newlines and indentation")
(printf (string any ... -> void)
"to format the rest of the arguments according to the first argument and print it to stdout")
(newline (-> void)
"to print a newline to stdout")
(read (-> sexp) "to read input from the user"))
("Lists"
(list? (any -> boolean)
"to determine whether some value is a list")
((advanced-cons cons) (X (listof X) -> (listof X))
"to construct a list")
((advanced-append append) ((listof any) ... -> (listof any))
"to create a single list from several"))
("Misc"
(force (delay -> any) "to find the delayed value; see also delay")
(promise? (any -> boolean) "to determine if a value is delayed")
(void (-> void) "produces a void value")
(void? (any -> boolean) "to determine if a value is void"))
("Posns"
(set-posn-x! (posn number -> void) "to update the x component of a posn")
(set-posn-y! (posn number -> void) "to update the x component of a posn"))
("Vectors"
(vector (X ... -> (vector X ...))
"to construct a vector")
(make-vector (number X -> (vectorof X))
"to construct a vector")
(build-vector (nat (nat -> X) -> (vectorof X))
"to construct a vector")
(vector-ref ((vector X) nat -> X)
"to extract an element from a vector")
(vector-length ((vector X) -> nat)
"to determine the length of a vector")
(vector-set! ((vectorof X) nat X -> void)
"to update a vector")
(vector? (any -> boolean)
"to determine if a value is a vector"))
("Boxes"
(box (any -> box)
"to construct a box")
(unbox (box -> any)
"to extract the boxed value")
(set-box! (box any -> void)
"to update a box")
(box? (any -> boolean)
"to determine if a value is a box"))))
(all-from advanced: lang/private/advanced-funs procedures)))

View File

@ -8,7 +8,7 @@
;; syntax:
(provide (rename-out
[intermediate-define define]
[intermediate-lambda-define define]
[intermediate-define-struct define-struct]
[intermediate-lambda lambda]
[advanced-app #%app]

View File

@ -11,7 +11,7 @@
(provide (rename-out
[intermediate-define define]
[intermediate-define-struct define-struct]
[beginner-lambda lambda]
[intermediate-pre-lambda lambda]
[intermediate-app #%app]
[beginner-top #%top]
[intermediate-local local]
@ -46,35 +46,4 @@
;; procedures:
(provide-and-document
procedures
(all-from beginner: lang/private/beginner-funs procedures)
("Higher-Order Functions"
(map ((X ... -> Z) (listof X) ... -> (listof Z))
"to construct a new list by applying a function to each item on one or more existing lists")
(for-each ((any ... -> any) (listof any) ... -> void)
"to apply a function to each item on one or more lists for effect only")
(filter ((X -> boolean) (listof X) -> (listof X))
"to construct a list from all those items on a list for which the predicate holds")
((intermediate-foldr foldr) ((X Y -> Y) Y (listof X) -> Y)
"(foldr f base (list x-1 ... x-n)) = (f x-1 ... (f x-n base))")
((intermediate-foldl foldl) ((X Y -> Y) Y (listof X) -> Y)
"(foldl f base (list x-1 ... x-n)) = (f x-n ... (f x-1 base))")
(build-list (nat (nat -> X) -> (listof X))
"(build-list n f) = (list (f 0) ... (f (- n 1)))")
((intermediate-build-string build-string) (nat (nat -> char) -> string)
"(build-string n f) = (string (f 0) ... (f (- n 1)))")
((intermediate-quicksort quicksort) ((listof X) (X X -> boolean) -> (listof X))
"to construct a list from all items on a list in an order according to a predicate")
(andmap ((X -> boolean) (listof X) -> boolean)
"(andmap p (list x-1 ... x-n)) = (and (p x-1) (and ... (p x-n)))")
(ormap ((X -> boolean) (listof X) -> boolean)
"(ormap p (list x-1 ... x-n)) = (or (p x-1) (or ... (p x-n)))")
(memf ((X -> boolean) (listof X) -> (union false (listof X)))
"to determine whether the first argument produces true for some value in the second argument")
(apply ((X-1 ... X-N -> Y) X-1 ... X-i (list X-i+1 ... X-N) -> Y)
"to apply a function using items from a list as the arguments")
(compose ((Y-1 -> Z) ... (Y-N -> Y-N-1) (X-1 ... X-N -> Y-N) -> (X-1 ... X-N -> Z))
"to compose a sequence of procedures into a single procedure")
(procedure? (any -> boolean)
"to determine if a value is a procedure"))))
(all-from beginner: lang/private/intermediate-funs procedures)))

View File

@ -0,0 +1,79 @@
(module advanced-funs scheme/base
(require "teachprims.ss"
mzlib/etc
mzlib/list
mzlib/pretty
syntax/docprovide
scheme/promise
"../posn.ss"
(for-syntax scheme/base))
(define-syntax (freshen-export stx)
(syntax-case stx ()
[(_ new-name orig-name)
#'(define-syntax new-name (make-rename-transformer #'orig-name))]))
(provide-and-document/wrap
procedures
freshen-export
("Reading and Printing"
(print (any -> void)
"to print the argument as a value to stdout")
(display (any -> void)
"to print the argument to stdout (without quotes on symbols and strings, etc.)")
(write (any -> void)
"to print the argument to stdout (in a traditional style that is somewhere between print and display)")
(pretty-print (any -> void)
"like write, but with standard newlines and indentation")
(printf (string any ... -> void)
"to format the rest of the arguments according to the first argument and print it to stdout")
(newline (-> void)
"to print a newline to stdout")
(read (-> sexp) "to read input from the user"))
("Lists"
(list? (any -> boolean)
"to determine whether some value is a list")
((advanced-cons cons) (X (listof X) -> (listof X))
"to construct a list")
((advanced-append append) ((listof any) ... -> (listof any))
"to create a single list from several"))
("Misc"
(force (delay -> any) "to find the delayed value; see also delay")
(promise? (any -> boolean) "to determine if a value is delayed")
(void (-> void) "produces a void value")
(void? (any -> boolean) "to determine if a value is void"))
("Posns"
(set-posn-x! (posn number -> void) "to update the x component of a posn")
(set-posn-y! (posn number -> void) "to update the x component of a posn"))
("Vectors"
(vector (X ... -> (vector X ...))
"to construct a vector")
(make-vector (number X -> (vectorof X))
"to construct a vector")
(build-vector (nat (nat -> X) -> (vectorof X))
"to construct a vector")
(vector-ref ((vector X) nat -> X)
"to extract an element from a vector")
(vector-length ((vector X) -> nat)
"to determine the length of a vector")
(vector-set! ((vectorof X) nat X -> void)
"to update a vector")
(vector? (any -> boolean)
"to determine if a value is a vector"))
("Boxes"
(box (any -> box)
"to construct a box")
(unbox (box -> any)
"to extract the boxed value")
(set-box! (box any -> void)
"to update a box")
(box? (any -> boolean)
"to determine if a value is a box"))))

View File

@ -273,9 +273,6 @@
(list (any ... -> (listof any)) "to construct a list of its arguments")
(list (any ... (listof any) -> (listof any))
"to construct a list of its arguments, building on the last argument")
((beginner-list* list*) (any ... (listof any) -> (listof any))
"to construct a list by adding multiple items to a list")

View File

@ -0,0 +1,47 @@
(module intermediate-funs scheme/base
(require "teachprims.ss"
mzlib/etc
mzlib/list
syntax/docprovide
(for-syntax scheme/base))
(define-syntax (freshen-export stx)
(syntax-case stx ()
[(_ new-name orig-name)
#'(define-syntax new-name (make-rename-transformer #'orig-name))]))
(provide-and-document/wrap
procedures
freshen-export
(all-from beginner: lang/private/beginner-funs procedures)
("Higher-Order Functions"
(map ((X ... -> Z) (listof X) ... -> (listof Z))
"to construct a new list by applying a function to each item on one or more existing lists")
(for-each ((any ... -> any) (listof any) ... -> void)
"to apply a function to each item on one or more lists for effect only")
(filter ((X -> boolean) (listof X) -> (listof X))
"to construct a list from all those items on a list for which the predicate holds")
((intermediate-foldr foldr) ((X Y -> Y) Y (listof X) -> Y)
"(foldr f base (list x-1 ... x-n)) = (f x-1 ... (f x-n base))")
((intermediate-foldl foldl) ((X Y -> Y) Y (listof X) -> Y)
"(foldl f base (list x-1 ... x-n)) = (f x-n ... (f x-1 base))")
(build-list (nat (nat -> X) -> (listof X))
"(build-list n f) = (list (f 0) ... (f (- n 1)))")
((intermediate-build-string build-string) (nat (nat -> char) -> string)
"(build-string n f) = (string (f 0) ... (f (- n 1)))")
((intermediate-quicksort quicksort) ((listof X) (X X -> boolean) -> (listof X))
"to construct a list from all items on a list in an order according to a predicate")
(andmap ((X -> boolean) (listof X) -> boolean)
"(andmap p (list x-1 ... x-n)) = (and (p x-1) (and ... (p x-n)))")
(ormap ((X -> boolean) (listof X) -> boolean)
"(ormap p (list x-1 ... x-n)) = (or (p x-1) (or ... (p x-n)))")
(memf ((X -> boolean) (listof X) -> (union false (listof X)))
"to determine whether the first argument produces true for some value in the second argument")
(apply ((X-1 ... X-N -> Y) X-1 ... X-i (list X-i+1 ... X-N) -> Y)
"to apply a function using items from a list as the arguments")
(compose ((Y-1 -> Z) ... (Y-N -> Y-N-1) (X-1 ... X-N -> Y-N) -> (X-1 ... X-N -> Z))
"to compose a sequence of procedures into a single procedure")
(procedure? (any -> boolean)
"to determine if a value is a procedure"))))

View File

@ -143,12 +143,12 @@
intermediate-define
intermediate-define-struct
intermediate-pre-lambda
intermediate-local
intermediate-letrec
intermediate-let
intermediate-let*
intermediate-recur
intermediate-lambda
intermediate-app
intermediate-quote
intermediate-quasiquote
@ -156,6 +156,9 @@
intermediate-unquote-splicing
intermediate-time
intermediate-lambda-define
intermediate-lambda
advanced-define
advanced-lambda
advanced-app
@ -408,7 +411,7 @@
;; define (beginner)
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define (define/proc first-order? assign? stx)
(define (define/proc first-order? assign? stx lambda-stx)
(define (wrap-func-definition name argc k)
(wrap-func-definitions first-order?
@ -440,7 +443,8 @@
(identifier/non-kw? (syntax name))
(let ([lam (syntax expr)])
(check-defined-lambda lam)
(syntax-case (syntax expr) (beginner-lambda)
(syntax-case* (syntax expr) (beginner-lambda) (lambda (a b)
(module-identifier=? a lambda-stx))
;; Well-formed lambda def:
[(beginner-lambda arg-seq lexpr ...)
(begin
@ -573,10 +577,14 @@
(bad-use-error 'define stx)]))
(define (beginner-define/proc stx)
(define/proc #t #f stx))
(define/proc #t #f stx #'beginner-lambda))
(define (intermediate-define/proc stx)
(define/proc #f #f stx))
(define/proc #f #f stx #'intermediate-pre-lambda))
(define (intermediate-lambda-define/proc stx)
;; no special treatment of intermediate-lambda:
(define/proc #f #f stx #'beginner-lambda))
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; lambda (beginner; only works with define)
@ -593,10 +601,12 @@
[_else
(bad-use-error 'lambda stx)]))
(define (intermediate-pre-lambda/proc stx)
(beginner-lambda/proc stx))
(define (check-defined-lambda lam)
(syntax-case lam (beginner-lambda)
[(beginner-lambda arg-seq lexpr ...)
(syntax-case lam (intermediate-pre-lambda)
[(intermediate-pre-lambda arg-seq lexpr ...)
(syntax-case (syntax arg-seq) () [(arg ...) #t][_else #f])
(let ([args (syntax->list (syntax arg-seq))])
(for-each (lambda (arg)
@ -628,7 +638,7 @@
args)
'ok)]
;; Bad lambda because bad args:
[(beginner-lambda args . _)
[(intermediate-pre-lambda args . _)
(teach-syntax-error
'lambda
lam
@ -636,7 +646,7 @@
"expected a sequence of function arguments after `lambda', but found ~a"
(something-else (syntax args)))]
;; Bad lambda, no args:
[(beginner-lambda)
[(intermediate-pre-lambda)
(teach-syntax-error
'lambda
lam
@ -1507,20 +1517,20 @@
'comes-from-let*))]
[_else (bad-let-form 'let* stx stx)]))))
;; Helper function: allows `beginner-lambda' instead
;; Helper function: allows `intermediate-pre-lambda' instead
;; of rejecting it:
(define (allow-local-lambda stx)
(syntax-case stx (beginner-lambda)
[(beginner-lambda . rest)
(syntax-case stx (intermediate-pre-lambda)
[(intermediate-pre-lambda . rest)
(begin
(check-defined-lambda stx)
;; pattern-match again to pull out the formals:
(syntax-case stx ()
[(_ formals . rest)
(quasisyntax/loc stx (lambda formals #,(stepper-syntax-property
#`make-lambda-generative
'stepper-skip-completely
#t)
#`make-lambda-generative
'stepper-skip-completely
#t)
. rest))]))]
[_else stx]))

View File

@ -222,6 +222,7 @@
(provide schemeblock SCHEMEBLOCK schemeblock/form
schemeblock0 SCHEMEBLOCK0 schemeblock0/form
schemeblockelem
schemeinput
schememod
scheme SCHEME scheme/form schemeresult schemeid schememodname
@ -442,7 +443,9 @@
(provide declare-exporting
deftogether
defproc defproc* defstruct defthing defthing* defparam defparam* defboolparam
defproc defproc* defstruct
defthing defthing* defthing/proc
defparam defparam* defboolparam
defform defform* defform/subs defform*/subs defform/none
defidform
specform specform/subs
@ -762,6 +765,10 @@
(syntax-rules ()
[(_ id) (*var 'id)]))
(define (defthing/proc id contract descs)
(*defthing (list id) (list (syntax-e id)) #f (list contract)
(lambda () descs)))
(define (into-blockquote s)
(cond
[(splice? s)

View File

@ -0,0 +1,263 @@
#lang scribble/doc
@(require "common.ss"
"std-grammar.ss"
"prim-ops.ss"
(for-label lang/htdp-advanced))
@(define-syntax-rule (bd intm-define intm-define-struct intm-lambda intm-let)
(begin
(require (for-label lang/htdp-intermediate-lambda))
(define intm-define (scheme define))
(define intm-define-struct (scheme define-struct))
(define intm-lambda (scheme lambda))
(define intm-let (scheme let))))
@(bd intm-define intm-define-struct intm-lambda intm-let)
@title[#:style 'toc]{Advanced Student}
@schemegrammar*+qq[
#:literals (define define-struct lambda cond else if and or empty true false require lib planet
local let let* letrec time begin begin0 set! delay shared recur when case unless)
[program def-or-expr]
[def-or-expr definition
expr
library-require]
[definition (define (id id id ...) expr)
(define id expr)
(define-struct id (id ...))]
[expr (begin expr expr ...)
(begin0 expr expr ...)
(set! id expr)
(delay expr)
(lambda (id id ...) expr)
(local [definition ...] expr)
(letrec ([id expr] ...) expr)
(shared ([id expr] ...) expr)
(let ([id expr] ...) expr)
(let id ([id expr] ...) expr)
(let* ([id expr] ...) expr)
(recur id ([id expr] ...) expr)
(code:line (expr expr expr ...) (code:comment #, @seclink["intermediate-lambda-call"]{function call}))
(cond [expr expr] ... [expr expr])
(cond [expr expr] ... [else expr])
(case expr [(choice choice ...) expr] ...
[(choice choice ...) expr])
(case expr [(choice choice ...) expr] ...
[else expr])
(if expr expr expr)
(when expr expr)
(unless expr expr)
(and expr expr expr ...)
(or expr expr expr ...)
(time expr)
empty
(code:line id (code:comment #, @seclink["intermediate-id"]{identifier}))
(code:line prim-op (code:comment #, @seclink["intermediate-lambda-prim-op"]{primitive operation}))
'id
(code:line #, @elem{@schemevalfont{'}@scheme[quoted]} (code:comment #, @seclink["beginner-abbr-quote"]{quoted value}))
(code:line #, @elem{@schemevalfont{`}@scheme[quasiquoted]} (code:comment #, @seclink["beginner-abbr-quasiquote"]{quasiquote}))
number
true
false
string
character]
[choice (code:line id (code:comment #, @t{treated as a symbol}))
number]
]
@|prim-nonterms|
@prim-ops['(lib "htdp-advanced.ss" "lang") #'here]
@; ----------------------------------------------------------------------
@section[#:tag "advanced-define"]{@scheme[define]}
@deftogether[(
@defform[(define (id id ...) expr)]
@defform/none[#:literals (define)
(define id expr)]
)]{
The same as Intermediate with Lambda's @|intm-define|, except that a
function is allowed to accept zero arguments.}
@; ----------------------------------------------------------------------
@section[#:tag "advanced-define-struct"]{@scheme[define-struct]}
@defform[(define-struct structid (fieldid ...))]{
The same as Intermediate's @|intm-define-struct|, but defines an
additional set of operations:
@itemize{
@item{@schemeidfont{make-}@scheme[structid] : takes a number of
arguments equal to the number of fields in the structure type,
and creates a new instance of the structure type.}
@item{@schemeidfont{set-}@scheme[structid]@schemeidfont{-}@scheme[fieldid]@schemeidfont{!}
: takes an instance of the structure and a value, and changes
the instance's field to the given value.}
}}
@; ----------------------------------------------------------------------
@section[#:tag "advanced-lambda"]{@scheme[lambda]}
@defform[(lambda (id ...) expr)]{
The same as Intermediate with Lambda's @|intm-lambda|, except that a
function is allowed to accept zero arguments.}
@; ----------------------------------------------------------------------
@section{@scheme[begin]}
@defform[(begin expr expr ...)]{
Evaluates the @scheme[expr]s in order from left to right. The value of
the @scheme[begin] expression is the value of the last @scheme[expr].}
@; ----------------------------------------------------------------------
@section{@scheme[begin0]}
@defform[(begin0 expr expr ...)]{
Evaluates the @scheme[expr]s in order from left to right. The value of
the @scheme[begin] expression is the value of the first @scheme[expr].}
@; ----------------------------------------------------------------------
@section{@scheme[set!]}
@defform[(set! id expr)]{
Evaluates @scheme[expr], and then changes the definition @scheme[id]
to have @scheme[expr]'s value. The @scheme[id] must be defined or
bound by @scheme[letrec], @scheme[let], or @scheme[let*].}
@; ----------------------------------------------------------------------
@section{@scheme[delay]}
@defform[(delay expr)]{
Produces a ``promise'' to evaluate @scheme[expr]. The @scheme[expr] is
not evaluated until the promise is forced through the @scheme[force]
operator; when the promise is forced, the result is recorded, so that
any further @scheme[force] of the promise always produces the
remembered value.}
@; ----------------------------------------------------------------------
@section{@scheme[shared]}
@defform[(shared ([id expr] ...) expr)]{
Like @scheme[letrec], but when an @scheme[expr] next to an @scheme[id]
is a @scheme[cons], @scheme[list], @scheme[vector], quasiquoted
expression, or @schemeidfont{make-}@scheme[_structid] from a
@scheme[define-struct], the @scheme[expr] can refer directly to any
@scheme[id], not just @scheme[id]s defined earlier. Thus,
@scheme[shared] can be used to create cyclic data structures.}
@; ----------------------------------------------------------------------
@section[#:tag "advanced-let"]{@scheme[let]}
@defform*[[(let ([id expr] ...) expr)
(let id ([id expr] ...) expr)]]{
The first form of @scheme[let] is the same as Intermediate's
@|intm-let|.
The second form is equivalent to a @scheme[recur] form.}
@; ----------------------------------------------------------------------
@section{@scheme[recur]}
@defform[(recur id ([id expr] ...) expr)]{
A short-hand recursion construct. The first @scheme[id] corresponds to
the name of the recursive function. The parenthesized @scheme[id]s are
the function's arguments, and each corresponding @scheme[expr] is a
value supplied for that argument in an initial starting call of the
function. The last @scheme[expr] is the body of the function.
More precisely, a @scheme[recur] form
@schemeblock[
(recur func-id ([arg-id arg-expr] (unsyntax @schemeidfont{...}))
body-expr)
]
is equivalent to
@schemeblock[
((local [(define (func-id arg-id (unsyntax @schemeidfont{...}))
body-expr)]
func-id)
arg-expr (unsyntax @schemeidfont{...}))
]}
@; ----------------------------------------------------------------------
@section{@scheme[case]}
@defform[(case expr [(choice ...) expr] ... [(choice ...) expr])]{
A @scheme[case] form contains one or more ``lines'' that are
surrounded by parentheses or square brackets. Each line contains a
sequence of choices---numbers and names for symbols---and an answer
@scheme[expr]. The initial @scheme[expr] is evaluated, and the
resulting value is compared to the choices in each line, where the
lines are considered in order. The first line that contains a matching
choice provides an answer @scheme[expr] whose value is the result of
the whole @scheme[case] expression. If none of the lines contains a
matching choice, it is an error.}
@defform/none[#:literals (cond else)
(cond expr [(choice ...) expr] ... [else expr])]{
This form of @scheme[case] is similar to the prior one, except that
the final @scheme[else] clause is always taken if no prior line
contains a choice matching the value of the initial @scheme[expr]. In
other words, so there is no possibility to ``fall off them end'' of
the @scheme[case] form.}
@; ----------------------------------------------------------------------
@section{@scheme[when] and @scheme[unless]}
@defform[(when expr expr)]{
The first @scheme[expr] (known as the ``test'' expression) is
evaluated. If it evaluates to @scheme[true], the result of the
@scheme[when] expression is the result of evaluating the second
@scheme[expr], otherwise the result is @scheme[(void)] and the second
@scheme[expr] is not evaluated. If the result of evaluating the test
@scheme[expr] is neither @scheme[true] nor @scheme[false], it is an
error.}
@defform[(unless expr expr)]{
Like @scheme[when], but the second @scheme[expr] is evaluated when the
first @scheme[expr] produces @scheme[false] instead of @scheme[true].}
@; ----------------------------------------
@section[#:tag "advanced-prim-ops"]{Primitive Operations}
The following primitives extend the set available though
@seclink["intermediate-prim-op"]{Intermediate}.
@prim-op-defns['(lib "htdp-advanced.ss" "lang")
#'here
'((lib "htdp-beginner.ss" "lang") (lib "htdp-intermediate.ss" "lang"))]

View File

@ -0,0 +1,104 @@
#lang scribble/doc
@(require "common.ss"
"std-grammar.ss"
"prim-ops.ss"
(for-label lang/htdp-beginner-abbr))
@title[#:style 'toc]{Beginner Student with List Abbreviations}
@schemegrammar*+qq[
#:literals (define define-struct lambda cond else if and or empty true false require lib planet)
[program def-or-expr]
[def-or-expr definition
expr
library-require]
[definition (define (id id id ...) expr)
(define id expr)
(define id (lambda (id id ...) expr))
(define-struct id (id ...))]
[expr (code:line (id expr expr ...) (code:comment #, @seclink["beginner-call"]{function call}))
(code:line (prim-op expr ...) (code:comment #, @seclink["beginner-prim-call"]{primitive operation call}))
(cond [expr expr] ... [expr expr])
(cond [expr expr] ... [else expr])
(if expr expr expr)
(and expr expr expr ...)
(or expr expr expr ...)
empty
id
(code:line #, @elem{@schemevalfont{'}@scheme[quoted]} (code:comment #, @seclink["beginner-abbr-quote"]{quoted value}))
(code:line #, @elem{@schemevalfont{`}@scheme[quasiquoted]} (code:comment #, @seclink["beginner-abbr-quasiquote"]{quasiquote}))
number
true
false
string
character]
]
@|prim-nonterms|
@prim-ops['(lib "htdp-beginner-abbr.ss" "lang") #'here]
@; ----------------------------------------
@section[#:tag "beginner-abbr-quote"]{Quote}
@deftogether[(
@defform/none[(unsyntax @elem{@schemevalfont{'}@scheme[quoted]})]
@defform[(quote quoted)]
)]{
Creates symbols and abbreviates nested lists.
Normally, this form is written with a @litchar{'}, like
@scheme['(apple banana)], but it can also be written with @scheme[quote], like
@scheme[((unsyntax @scheme[quote]) (apple banana))].}
@; ----------------------------------------
@section[#:tag "beginner-abbr-quasiquote"]{Quasiquote}
@deftogether[(
@defform/none[(unsyntax @elem{@schemevalfont{`}@scheme[quasiquoted]})]
@defform[(quasiquote quasiquoted)]
)]{
Creates symbols and abbreviates nested lists, but also allows escaping
to expression ``unquotes.''
Normally, this form is written with a backquote, @litchar{`}, like
@scheme[`(apple ,(+ 1 2))], but it can also be written with
@scheme[quasiquote], like @scheme[((unsyntax @scheme[quasiquote])
(apple ,(+ 1 2)))].}
@deftogether[(
@defform/none[(unsyntax @elem{@schemevalfont{,}@scheme[quasiquoted]})]
@defform[(unquote expr)]
)]{
Under a single quasiquote, @schemefont{,}@scheme[expr] escapes from
the quote to include an evaluated expression whose result is inserted
into the abbreviated list.
Under multiple quasiquotes, @schemefont{,}@scheme[expr] is really
@schemefont{,}@scheme[quasiquoted], decrementing the quasiquote count
by one for @scheme[quasiquoted].
Normally, an unquote is written with @litchar{,}, but it can also be
written with @scheme[unquote].}
@deftogether[(
@defform/none[(unsyntax @elem{@schemevalfont[",@"]@scheme[quasiquoted]})]
@defform[(unquote-splicing expr)]
)]{
Under a single quasiquote, @schemefont[",@"]@scheme[expr] escapes from
the quote to include an evaluated expression whose result is a list to
splice into the abbreviated list.
Under multiple quasiquotes, a splicing unquote is like an unquote;
that is, it decrements the quasiquote count by one.
Normally, a splicing unquote is written with @litchar{,}, but it can
also be written with @scheme[unquote-splicing].}

View File

@ -0,0 +1,324 @@
#lang scribble/doc
@(require "common.ss"
"std-grammar.ss"
"prim-ops.ss"
(for-label lang/htdp-beginner))
@(define-syntax-rule (bd intm-case)
(begin
(require (for-label lang/htdp-advanced))
(define intm-case (scheme case))))
@(bd adv-case)
@title[#:style 'toc]{Beginner Student}
@schemegrammar*+library[
#:literals (define define-struct lambda cond else if and or empty true false require lib planet)
[program def-or-expr]
[def-or-expr definition
expr
library-require]
[definition (define (id id id ...) expr)
(define id expr)
(define id (lambda (id id ...) expr))
(define-struct id (id ...))]
[expr (code:line (id expr expr ...) (code:comment #, @seclink["beginner-call"]{function call}))
(code:line (prim-op expr ...) (code:comment #, @seclink["beginner-prim-call"]{primitive operation call}))
(cond [expr expr] ... [expr expr])
(cond [expr expr] ... [else expr])
(if expr expr expr)
(and expr expr expr ...)
(or expr expr expr ...)
empty
id
(code:line id (code:comment #, @seclink["beginner-id"]{identifier}))
(code:line #, @elem{@schemevalfont{'}@scheme[id]} (code:comment #, @seclink["beginner-quote"]{symbol}))
number
true
false
string
character]
]
@|prim-nonterms|
@prim-ops['(lib "htdp-beginner.ss" "lang") #'here]
@; ----------------------------------------------------------------------
@section{@scheme[define]}
@defform[(define (id id id ...) expr)]{
Defines a function. The first @scheme[id] inside the parentheses is
the name of the function. All remaining @scheme[id]s are the names of
the function's arguments. The @scheme[expr] is the body of the
function, evaluated whenever the function is called. The name of the
function cannot be that of a primitive or another definition.}
@defform/none[#:literals (define)
(define id expr)]{
Defines a constant @scheme[id] as a synonym for the value produced by
@scheme[expr]. The defined name cannot be that of a primitive or
another definition, and @scheme[id] itself must not appear in
@scheme[expr].}
@defform/none[#:literals (define lambda)
(define id (lambda (id id ...) expr))]{
An alternate form for defining functions. The first @scheme[id] is the
name of the function. The @scheme[id]s in parentheses are the names of
the function's arguments, and the @scheme[expr] is the body of the
function, which evaluated whenever the function is called. The name
of the function cannot be that of a primitive or another definition.}
@defidform[lambda]{
The @scheme[lambda] keyword can only be used with @scheme[define] in
the alternative function-definition syntax.}
@; ----------------------------------------------------------------------
@section{@scheme[define-struct]}
@defform[(define-struct structid (fieldid ...))]{
Define a new type of structure. The structure's fields are named by
the @scheme[fieldid]s in parentheses. After evaluation of a
define-struct form, a set of new primitives is available for creation,
extraction, and type-like queries:
@itemize{
@item{@schemeidfont{make-}@scheme[structid] : takes a number of
arguments equal to the number of fields in the structure type,
and creates a new instance of the structure type.}
@item{@scheme[structid]@schemeidfont{-}@scheme[fieldid] : takes an
instance of the structure and returns the field named by
@scheme[structid].}
@item{@scheme[structid]@schemeidfont{?} : takes any value, and returns
@scheme[true] if the value is an instance of the structure type.}
@item{@scheme[structid] : an identifier representing the structure
type, but never used directly.}
}
The created names must not be the same as a primitive or another defined name.}
@; ----------------------------------------------------------------------
@section[#:tag "beginner-call"]{Function Calls}
@defform/none[(id expr expr ...)]{
Calls a function. The @scheme[id] must refer to a defined function,
and the @scheme[expr]s are evaluated from left to right to produce the
values that are passed as arguments to the function. The result of the
function call is the result of evaluating the function's body with
every instance of an argument name replaced by the value passed for
that argument. The number of argument @scheme[expr]s must be the same
as the number of arguments expected by the function.}
@defform[(#%app id expr expr ...)]{
A function call can be written with @scheme[#%app], though it's
practically never written that way.}
@; ----------------------------------------------------------------------
@section[#:tag "beginner-prim-call"]{Primitive Calls}
@defform/none[(prim-op expr ...)]{
Like a @seclink["beginner-call"]{function call}, but for a primitive
operation. The @scheme[expr]s are evaluated from left to right, and
passed as arguments to the primitive operation named by
@scheme[prim-op]. A @scheme[define-struct] form creates new
primitives.}
@; ----------------------------------------------------------------------
@section{@scheme[cond]}
@defform[(cond [expr expr] ... [expr expr])]{
A @scheme[cond] form contains one or more ``lines'' that are
surrounded by parentheses or square brackets. Each line contains two
@scheme[expr]s: a question @scheme[expr] and an answer
@scheme[expr].
The lines are considered in order. To evaluate a line, first evaluate
the question @scheme[expr]. If the result is @scheme[true], then the
result of the whole @scheme[cond] expression is the result of
evaluating the answer @scheme[expr] of the same line. If the result of
evaluating the question @scheme[expr] is @scheme[false], the line is
discarded and evaluation proceeds with the next line.
If the result of a question @scheme[expr] is neither @scheme[true] nor
@scheme[false], it is an error. If none of the question @scheme[expr]s
evaluates to @scheme[true], it is also an error.}
@defform/none[#:literals (cond else)
(cond [expr expr] ... [else expr])]{
This form of @scheme[cond] is similar to the prior one, except that
the final @scheme[else] clause is always taken if no prior line's test
expression evaluates to @scheme[true]. In other words, @scheme[else]
acts like @scheme[true], so there is no possibility to ``fall off them
end'' of the @scheme[cond] form.}
@defidform[else]{
The @scheme[else] keyword can be used only with @scheme[cond], or in
Advanced language, with @|adv-case|.}
@; ----------------------------------------------------------------------
@section{@scheme[if]}
@defform[(if expr expr expr)]{
The first @scheme[expr] (known as the ``test'' @scheme[expr]) is
evaluated. If it evaluates to @scheme[true], the result of the
@scheme[if] expression is the result of evaluating the second
@scheme[expr] (often called the ``then'' @scheme[expr]). If the text
@scheme[expr] evaluates to @scheme[false], the result of the
@scheme[if] expression is the result of evaluating the third
@scheme[expr]expression (known as the ``else'' @scheme[expr]). If the
result of evaluating the test @scheme[expr] is neither @scheme[true]
nor @scheme[false], it is an error.}
@; ----------------------------------------------------------------------
@section{@scheme[and]}
@defform[(and expr expr expr ...)]{
The @scheme[expr]s are evaluated from left to right. If the first
@scheme[expr] evaluates to @scheme[false], the @scheme[and] expression
immediately evaluates to @scheme[false]. If the first @scheme[expr]
evaluates to @scheme[true], the next expression is considered. If all
@scheme[expr]s evaluate to @scheme[true], the @scheme[and] expression
evaluates to @scheme[true]. If any of the expressions evaluate to a
value other than @scheme[true] or @scheme[false], it is an error.}
@; ----------------------------------------------------------------------
@section{@scheme[or]}
@defform[(or expr expr expr ...)]{
The @scheme[expr]s are evaluated from left to right. If the first
@scheme[expr] evaluates to @scheme[true], the @scheme[or] expression
immediately evaluates to @scheme[true]. If the first @scheme[expr]
evaluates to @scheme[false], the next expression is considered. If all
@scheme[expr]s evaluate to @scheme[false], the @scheme[or] expression
evaluates to @scheme[false]. If any of the expressions evaluate to a
value other than @scheme[true] or @scheme[false], it is an error.}
@; ----------------------------------------------------------------------
@section{@scheme[empty]}
@defthing[empty empty?]{
The empty list.}
@; ----------------------------------------------------------------------
@section[#:tag "beginner-id"]{Identifiers}
@defform/none[id]{
An @scheme[id] refers to a defined constant or argument within a
function body. If no definition or argument matches the @scheme[id]
name, an error is reported. Similarly, if @scheme[id] matches the name
of a defined function or primitive operation, an error is reported.}
@; ----------------------------------------------------------------------
@section[#:tag "beginner-quote"]{Symbols}
@deftogether[(
@defform/none[(unsyntax @elem{@schemevalfont{'}@scheme[id]})]
@defform[(quote id)]
)]{
A quoted @scheme[id] is a symbol. A symbol is a constant, like
@scheme[0] and @scheme[empty].
Normally, a symbol is written with a @litchar{'}, like
@scheme['apple], but it can also be written with @scheme[quote], like
@scheme[((unsyntax @scheme[quote]) apple)].
The @scheme[id] for a symbol is a sequence of characters not including
a space or one of the following:}
@t{@hspace[2] @litchar{"} @litchar{,} @litchar{'} @litchar{`}
@litchar{(} @litchar{)} @litchar{[} @litchar{]}
@litchar["{"] @litchar["}"] @litchar{|} @litchar{;}
@litchar{#}}
@; ----------------------------------------------------------------------
@section{@scheme[true] and @scheme[false]}
@defthing[true boolean?]{
The true value.}
@defthing[false boolean?]{
The false value.}
@; ----------------------------------------------------------------------
@section{@scheme[require]}
@defform[(require string)]{
Makes the definitions of the module specified by @scheme[string]
available in the current module (i.e., current file), where @scheme[string]
refers to a file relative to the enclosing file.
The @scheme[string] is constrained in several ways to avoid problems
with different path conventions on different platforms: a @litchar{/}
is a directory separator, @litchar{.} always means the current
directory, @litchar{..} always means the parent directory, path
elements can use only @litchar{a} through @litchar{z} (uppercase or
lowercase), @litchar{0} through @litchar{9}, @litchar{-}, @litchar{_},
and @litchar{.}, and the string cannot be empty or contain a leading
or trailing @litchar{/}.}
@defform/none[#:literals (require lib)
(require (lib string string ...))]{
Accesses a file in an installed library, making its definitions
available in the current module (i.e., current file). The first
@scheme[string] names the library file, and the remaining
@scheme[string]s name the collection (and sub-collection, and so on)
where the file is installed. Each string is constrained in the same
way as for the @scheme[(require string)] form.}
@defform/none[#:literals (require planet)
(require (planet string (string string number number)))]{
Accesses a library that is distributed on the internet via the PLaneT
server, making it definitions available in the current module (i.e.,
current file).}
@; ----------------------------------------
@section[#:tag "beginner-prim-ops"]{Primitive Operations}
@prim-op-defns['(lib "htdp-beginner.ss" "lang") #'here '()]

View File

@ -0,0 +1,5 @@
#lang scheme/base
(require scribble/manual)
(provide (all-from-out scribble/manual))

View File

@ -0,0 +1,18 @@
#lang scribble/doc
@(require "common.ss")
@title{Languages for @italic{How to Design Programs}}
@table-of-contents[]
@;------------------------------------------------------------------------
@include-section["beginner.scrbl"]
@include-section["beginner-abbr.scrbl"]
@include-section["intermediate.scrbl"]
@include-section["intermediate-lambda.scrbl"]
@include-section["advanced.scrbl"]
@;------------------------------------------------------------------------
@index-section[]

View File

@ -0,0 +1,4 @@
(module info setup/infotab
(define name "Scribblings: HtDP Languages")
(define scribblings '(("htdp-langs.scrbl" (multi-page main-doc)))))

View File

@ -0,0 +1,99 @@
#lang scribble/doc
@(require "common.ss"
"std-grammar.ss"
"prim-ops.ss"
(for-label lang/htdp-intermediate-lambda))
@(define-syntax-rule (bd intm-define)
(begin
(require (for-label lang/htdp-intermediate))
(define intm-define (scheme define))))
@(bd intm-define)
@title[#:style 'toc]{Intermediate Student with Lambda}
@schemegrammar*+qq[
#:literals (define define-struct lambda cond else if and or empty true false require lib planet
local let let* letrec time)
[program def-or-expr]
[def-or-expr definition
expr
library-require]
[definition (define (id id id ...) expr)
(define id expr)
(define-struct id (id ...))]
[expr (lambda (id id ...) expr)
(local [definition ...] expr)
(letrec ([id expr] ...) expr)
(let ([id expr] ...) expr)
(let* ([id expr] ...) expr)
(code:line (expr expr expr ...) (code:comment #, @seclink["intermediate-lambda-call"]{function call}))
(cond [expr expr] ... [expr expr])
(cond [expr expr] ... [else expr])
(if expr expr expr)
(and expr expr expr ...)
(or expr expr expr ...)
(time expr)
empty
(code:line id (code:comment #, @seclink["intermediate-id"]{identifier}))
(code:line prim-op (code:comment #, @seclink["intermediate-lambda-prim-op"]{primitive operation}))
'id
(code:line #, @elem{@schemevalfont{'}@scheme[quoted]} (code:comment #, @seclink["beginner-abbr-quote"]{quoted value}))
(code:line #, @elem{@schemevalfont{`}@scheme[quasiquoted]} (code:comment #, @seclink["beginner-abbr-quasiquote"]{quasiquote}))
number
true
false
string
character]
]
@|prim-nonterms|
@prim-ops['(lib "htdp-intermediate-lambda.ss" "lang") #'here]
@; ----------------------------------------------------------------------
@section[#:tag "intermediate-lambda-define"]{@scheme[define]}
@deftogether[(
@defform[(define (id id id ...) expr)]
@defform/none[#:literals (define)
(define id expr)]
)]{
The same as Intermediate's @|intm-define|. No special case is needed
for @scheme[lambda], since a @scheme[lambda] form is an expression.}
@; ----------------------------------------------------------------------
@section[#:tag "intermediate-lambda"]{@scheme[lambda]}
@defform[(lambda (id id ...) expr)]{
Creates a function that takes as many arguments as given @scheme[id]s,
and whose body is @scheme[expr].}
@; ----------------------------------------------------------------------
@section[#:tag "intermediate-lambda-call"]{Function Calls}
@defform/none[(expr expr expr ...)]{
Like a Beginner @seclink["beginner-call"]{function call}, except that
the function position can be an arbitrary expression---perhaps a
@scheme[lambda] expression or a @scheme[_prim-op].}
@defform[(#%app id expr expr ...)]{
A function call can be written with @scheme[#%app], though it's
practically never written that way.}
@; ----------------------------------------------------------------------
@section[#:tag "intermediate-lambda-prim-op"]{Primitive Operation Names}
@defform/none[prim-op]{
The name of a primitive operation can be used as an expression. It
produces a function version of the operation.}

View File

@ -0,0 +1,184 @@
#lang scribble/doc
@(require "common.ss"
"std-grammar.ss"
"prim-ops.ss"
(for-label lang/htdp-intermediate))
@(define-syntax-rule (bd beg-define beg-define-struct)
(begin
(require (for-label lang/htdp-beginner))
(define beg-define (scheme define))
(define beg-define-struct (scheme define-struct))))
@(bd beg-define beg-define-struct)
@title[#:style 'toc]{Intermediate Student}
@schemegrammar*+qq[
#:literals (define define-struct lambda cond else if and or empty true false require lib planet
local let let* letrec time)
[program def-or-expr]
[def-or-expr definition
expr
library-require]
[definition (define (id id id ...) expr)
(define id expr)
(define id (lambda (id id ...) expr))
(define-struct id (id ...))]
[expr (local [definition ...] expr)
(letrec ([id expr-for-let] ...) expr)
(let ([id expr-for-let] ...) expr)
(let* ([id expr-for-let] ...) expr)
(code:line (id expr expr ...) (code:comment #, @seclink["intermediate-call"]{function call}))
(code:line (prim-op expr ...) (code:comment #, @seclink["beginner-prim-call"]{primitive operation call}))
(cond [expr expr] ... [expr expr])
(cond [expr expr] ... [else expr])
(if expr expr expr)
(and expr expr expr ...)
(or expr expr expr ...)
(time expr)
empty
(code:line id (code:comment #, @seclink["intermediate-id"]{identifier}))
(code:line prim-op (code:comment #, @seclink["intermediate-prim-op"]{primitive operation}))
'id
(code:line #, @elem{@schemevalfont{'}@scheme[quoted]} (code:comment #, @seclink["beginner-abbr-quote"]{quoted value}))
(code:line #, @elem{@schemevalfont{`}@scheme[quasiquoted]} (code:comment #, @seclink["beginner-abbr-quasiquote"]{quasiquote}))
number
true
false
string
character]
[expr-for-let (lambda (id id ...) expr)
expr]
]
@|prim-nonterms|
@prim-ops['(lib "htdp-intermediate.ss" "lang") #'here]
@; ----------------------------------------------------------------------
@section[#:tag "intermediate-define"]{@scheme[define]}
@deftogether[(
@defform[(define (id id id ...) expr)]
@defform/none[#:literals (define)
(define id expr)]
@defform/none[#:literals (define lambda)
(define id (lambda (id id ...) expr))]
)]{
Besides working in @scheme[local], definition forms are
the same as Beginner's @|beg-define|.}
@defidform[lambda]{
As in Beginner, @scheme[lambda] keyword can only be used with
@scheme[define] in the alternative function-definition syntax.}
@; ----------------------------------------------------------------------
@section[#:tag "intermediate-define-struct"]{@scheme[define-struct]}
@defform[(define-struct structid (fieldid ...))]{
Besides working in @scheme[local], this form is the same as Beginner's
@|beg-define-struct|.}
@; ----------------------------------------------------------------------
@section{@scheme[local]}
@defform[(local [definition ...] expr)]{
Groups related definitions for use in @scheme[expr]. Each
@scheme[definition] is evaluated in order, and finally the body
@scheme[expr] is evaluated. Only the expressions within the
@scheme[local] form (including the right-hand-sides of the
@scheme[definition]s and the @scheme[expr]) may refer to the names
defined by the @scheme[definition]s. If a name defined in the
@scheme[local] form is the same as a top-level binding, the inner one
``shadows'' the outer one. That is, inside the @scheme[local] form,
any references to that name refer to the inner one.
Since @scheme[local] is an expression and may occur anywhere an
expression may occur, it introduces the notion of lexical
scope. Expressions within the local may ``escape'' the scope of the
local, but these expressions may still refer to the bindings
established by the local.}
@; ----------------------------------------------------------------------
@section{@scheme[letrec], @scheme[let], and @scheme[let*]}
@defform[(letrec ([id expr-for-let] ...) expr)]{
Similar to @scheme[local], but essentially omitting the
@scheme[define] for each definition.
A @scheme[expr-for-let] can be either an expression for a constant
definition or a @scheme[lambda] form for a function definition.}
@defform[(let ([id expr-for-let] ...) expr)]{
Like @scheme[letrec], but the defined @scheme[id]s can be used only in
the last @scheme[expr], not the @scheme[expr-for-let]s next to the
@scheme[id]s.}
@defform[(let* ([id expr-for-let] ...) expr)]{
Like @scheme[let], but each @scheme[id] can be used in any subsequent
@scheme[expr-for-let], in addition to @scheme[expr].}
@; ----------------------------------------------------------------------
@section[#:tag "intermediate-call"]{Function Calls}
@defform/none[(id expr expr ...)]{
A function call in Intermediate is the same as a Beginner
@seclink["beginner-call"]{function call}, except that it can also call
@scheme[local]ly defined functions or functions passed as
arguments. That is, @scheme[id] can be a function defined in
@scheme[local] or an argument name while in a function.}
@defform[(#%app id expr expr ...)]{
A function call can be written with @scheme[#%app], though it's
practically never written that way.}
@; ----------------------------------------------------------------------
@section{@scheme[time]}
@defform[(time expr)]{
This form is used to measure the time taken to evaluate
@scheme[expr]. After evaluating @scheme[expr], Scheme prints out the
time taken by the evaluation (including real time, time taken by the
cpu, and the time spent collecting free memory) and returns the result
of the expression.}
@; ----------------------------------------------------------------------
@section[#:tag "intermediate-id"]{Identifiers}
@defform/none[id]{
An @scheme[id] refers to a defined constant (possibly local), defined
function (possibly local), or argument within a function body. If no
definition or argument matches the @scheme[id] name, an error is
reported.}
@; ----------------------------------------------------------------------
@section[#:tag "intermediate-prim-op"]{Primitive Operations}
@defform/none[prim-op]{
The name of a primitive operation can be used as an expression. If it
is passed to a function, then it can be used in a function call within
the function's body.}
@prim-op-defns['(lib "htdp-intermediate.ss" "lang")
#'here
'((lib "htdp-beginner.ss" "lang"))]

View File

@ -0,0 +1,113 @@
#reader(lib "scribble/reader.ss")
#lang scheme/base
(require "common.ss"
scribble/decode
scribble/struct
scribble/scheme
scheme/list
scheme/pretty
syntax/docprovide)
(provide prim-ops
prim-op-defns)
(define (maybe-make-table l t)
(if (paragraph? t)
(make-paragraph
(append l (cons " "
(paragraph-content t))))
(make-table
"prototype"
(list (list (make-flow (list (make-paragraph l)))
(make-flow (list t)))))))
(define (typeset-type type)
(let-values ([(in out) (make-pipe)])
(parameterize ([pretty-print-columns 50])
(pretty-print type out))
(port-count-lines! in)
(read-syntax #f in)))
(define (sort-category category)
(sort
(cadr category)
(lambda (x y)
(string<=? (symbol->string (car x))
(symbol->string (car y))))))
(define (make-proto func ctx-stx)
(maybe-make-table
(list
(hspace 2)
(to-element (datum->syntax ctx-stx (car func)))
(hspace 1)
":"
(hspace 1))
(to-paragraph
(typeset-type (cadr func)))))
(define (prim-ops lib ctx-stx)
(let ([ops (map (lambda (cat)
(cons (car cat)
(list (cdr cat))))
(lookup-documentation lib 'procedures))])
(make-table
#f
(cons
(list
(make-flow
(list
(make-paragraph
(list "A " (scheme _prim-op) " is one of:")))))
(apply
append
(map (lambda (category)
(cons
(list (make-flow
(list
(make-paragraph (list (hspace 1)
(bold (car category)))))))
(map (lambda (func)
(list
(make-flow
(list
(make-proto func ctx-stx)))))
(sort-category category))))
ops))))))
(define (prim-op-defns lib ctx-stx not-in)
(make-splice
(let ([ops (map (lambda (cat)
(cons (car cat)
(list (cdr cat))))
(lookup-documentation lib 'procedures))]
[not-in-ns (map (lambda (not-in-mod)
(let ([ns (make-base-namespace)])
(parameterize ([current-namespace ns])
(namespace-require `(for-label ,not-in-mod)))
ns))
not-in)])
(apply
append
(map (lambda (category)
(filter values
(map
(lambda (func)
(let ([id (datum->syntax ctx-stx (car func))])
(and (not (ormap
(lambda (ns)
(free-label-identifier=?
id
(parameterize ([current-namespace ns])
(namespace-syntax-introduce (datum->syntax #f (car func))))))
not-in-ns))
(let ([desc-strs (cddr func)])
(defthing/proc
id
(to-paragraph (typeset-type (cadr func)))
(cons "Purpose: " desc-strs))))))
(sort-category category))))
ops)))))

View File

@ -0,0 +1,71 @@
#reader(lib "scribble/reader.ss")
#lang scheme/base
(require "common.ss"
scribble/decode
(for-label lang/htdp-beginner-abbr))
(provide prim-nonterms
schemegrammar*+library
schemegrammar*+qq)
(define ex-str "This is a string with \" inside")
(define-syntax-rule (schemegrammar*+library form ...)
(schemegrammar*
form ...
(...
[libray-require #, @scheme[(require string)]
#, @scheme[(require (lib string string ...))]
#, @scheme[(require (planet string package))]])
(...
[package #, @scheme[(string string number number)]])))
(define-syntax-rule (schemegrammar*+qq form ...)
(schemegrammar*+library
form ...
(...
[quoted id
number
string
character
#, @scheme[(quoted ...)]
#, @elem{@schemevalfont{'}@scheme[quoted]}
#, @elem{@schemevalfont{`}@scheme[quoted]}
#, @elem{@schemefont{,}@scheme[quoted]}
#, @elem{@schemefont[",@"]@scheme[quoted]}])
(...
[quasiquoted id
number
string
character
#, @scheme[(quasiquoted ...)]
#, @elem{@schemevalfont{'}@scheme[quasiquoted]}
#, @elem{@schemevalfont{`}@scheme[quasiquoted]}
#, @elem{@schemefont{,}@scheme[expr]}
#, @elem{@schemefont[",@"]@scheme[expr]}])))
(define prim-nonterms
(make-splice
(list
@t{An @scheme[_id] is a sequence of characters not including a
space or one of the following:}
@t{@hspace[2] @litchar{"} @litchar{,} @litchar{'} @litchar{`}
@litchar{(} @litchar{)} @litchar{[} @litchar{]}
@litchar["{"] @litchar["}"] @litchar{|} @litchar{;}
@litchar{#}}
@t{A @scheme[_number] is a number such as @scheme[123], @scheme[3/2], or
@scheme[5.5].}
@t{A @scheme[_string] is enclosed by a pair of @litchar{"}. Unlike
symbols, strings may be split into characters and manipulated by a
variety of primitive functions. For example, @scheme["abcdef"],
@scheme["This is a string"], and @scheme[#,ex-str] are all strings.}
@t{A @scheme[_character] begins with @litchar{#\} and has the
name of the character. For example, @scheme[#\a], @scheme[#\b],
and @scheme[#\space] are characters.}
)))

View File

@ -19,6 +19,14 @@ typeset a library or language name is called @scheme[schememodname]).
Do not call an identifier (i.e., a syntactic element) a ``variable''
or a ``symbol.''
Avoid cut-and-paste for descriptive text. If two functions are
similar, consider documenting them together with
@scheme[deftogether]. To abstract a description, consider using
explicit prose abstraction, such as ``@scheme[x] is like @scheme[@y],
except that ...,'' instead of abstracting the source and instantiating
it multiple times; often, a prose abstraction is clearer to the reader
than a hidden abstraction in the document implementation.
Use @schemeidfont{id} or a name that ends @schemeidfont{-id} in
@scheme[defform] to mean an identifier, not @schemeidfont{identifier},
@schemeidfont{variable}, @schemeidfont{name}, or
@ -69,10 +77,13 @@ specific sequence of characters.
Refrain from referring to documentation ``above'' or ``below,'' and
instead have a hyperlink point to the right place.
Use American style for quotation marks and punctuation at the end of
quotation marks (i.e., a sentence-terminating period goes inside the
quotation marks). Of course, this rule does not apply for quotation
marks that are part of code.
In prose, use @litchar{``} and @litchar{''} quotation marks instead of
@litchar{"}. Use @litchar{---} for an em-dash, and do not include
spaces on either side, though it will typeset as an en-dash and spaces
in HTML output. Use American style for quotation marks and punctuation
at the end of quotation marks (i.e., a sentence-terminating period
goes inside the quotation marks). Of course, this rule does not apply
for quotation marks that are part of code.
Do not use a citation reference (as created by @scheme[cite]) as a
noun. Use it as an annotation.
noun; use it as an annotation.