Lots of documentation formatting.

Started as fixing misindented definitions, then more indentations, then
a bunch of similar things (square brackets, huge spaces at end-of-lines,
etc).
This commit is contained in:
Eli Barzilay 2011-08-15 07:50:04 -04:00
parent d3d9514b1c
commit d61eb53686
113 changed files with 1081 additions and 923 deletions

View File

@ -16,8 +16,8 @@
@(define-syntax-rule (def-ext id)
(begin
(require (for-label net/sendurl))
(define id (racket send-url))))
(require (for-label net/sendurl))
(define id (racket send-url))))
@(def-ext net-send-url)

View File

@ -47,7 +47,7 @@ Zum Beispiel:
(define pos (make-vec3 5 5 3))
(define lookat (make-vec3 0 0 0))
(define camera
(create-camera-matrix pos lookat 70.0 screenWidth screenHeight))
(create-camera-matrix pos lookat 70.0 screenWidth screenHeight))
(code:comment @#,t{render image})
(render-scene screenWidth screenHeight box camera)
]

View File

@ -19,16 +19,16 @@
@(define-syntax-rule (defprocthing* mod id ...)
(begin
(deflazy mod defprocthing id)
...))
(deflazy mod defprocthing id)
...))
@(define-syntax-rule (defprocthing id . rest)
(defthing id procedure? . rest))
@(define-syntax-rule (defidform* mod id ...)
(begin
(deflazy mod defidform id)
...))
(deflazy mod defidform id)
...))
@; ----------------------------------------

View File

@ -4,8 +4,8 @@
@(define-syntax-rule (intro id)
(begin
(require (for-label racket/cmdline))
(define id (racket command-line))))
(require (for-label racket/cmdline))
(define id (racket command-line))))
@(intro racket-command-line)
@mzlib[#:mode title cmdline]

View File

@ -13,12 +13,12 @@
@interaction-eval[#:eval etc-eval (require mzlib/etc)]
@(begin
(define-syntax-rule (bind id else-id)
(begin
(require (for-label scheme/base))
(define id (racket lambda))
(define else-id (racket else))))
(bind base-lambda base-else))
(define-syntax-rule (bind id else-id)
(begin
(require (for-label scheme/base))
(define id (racket lambda))
(define else-id (racket else))))
(bind base-lambda base-else))
@mzlib[#:mode title etc]
@ -77,11 +77,11 @@ syntax transformers that share helper functions, though
(define-syntax-set (let-current-continuation
let-current-escape-continuation)
(define (mk call-id)
(lambda (stx)
(syntax-case stx ()
[(_ id body1 body ...)
(with-syntax ([call call-id])
(syntax (call (lambda (id) body1 body ...))))])))
(lambda (stx)
(syntax-case stx ()
[(_ id body1 body ...)
(with-syntax ([call call-id])
(syntax (call (lambda (id) body1 body ...))))])))
(define let-current-continuation/proc
(mk (quote-syntax call/cc)))
(define let-current-escape-continuation/proc
@ -156,12 +156,12 @@ corresponding expression are bound to the multiple variables.
@examples[
#:eval etc-eval
(let+ ([val (values x y) (values 1 2)])
(list x y))
(list x y))
(let ([x 1])
(let+ ([val x 3]
[val y x])
y))
(let+ ([val x 3]
[val y x])
y))
]}

View File

@ -10,11 +10,11 @@
@interaction-eval[#:eval kw-eval (require mzlib/kw)]
@(begin
(define-syntax-rule (bind id)
(begin
(require (for-label scheme/base))
(define id (racket lambda))))
(bind base-lambda))
(define-syntax-rule (bind id)
(begin
(require (for-label scheme/base))
(define id (racket lambda))))
(bind base-lambda))
@mzlib[#:mode title kw]

View File

@ -6,8 +6,8 @@
@(begin
(define-syntax-rule (bind id)
(begin
(require racket/match)
(define id (racket match))))
(require racket/match)
(define id (racket match))))
(bind racket-match))
@mzlib[#:mode title match]

View File

@ -4,11 +4,11 @@
(only-in racket/sandbox make-module-evaluator)))
@(begin
(define-syntax-rule (bind id)
(begin
(require (for-label racket/sandbox))
(define id (racket make-evaluator))))
(bind racket-make-evaluator))
(define-syntax-rule (bind id)
(begin
(require (for-label racket/sandbox))
(define id (racket make-evaluator))))
(bind racket-make-evaluator))
@mzlib[#:mode title sandbox]

View File

@ -3,11 +3,11 @@
(for-label mzlib/sendevent))
@(begin
(define-syntax-rule (bind id)
(begin
(require (for-label scheme/gui/base))
(define id (racket send-event))))
(bind mred-send-event))
(define-syntax-rule (bind id)
(begin
(require (for-label scheme/gui/base))
(define id (racket send-event))))
(bind mred-send-event))
@mzlib[#:mode title sendevent]

View File

@ -3,12 +3,13 @@
(for-label mzlib/serialize))
@(begin
(define-syntax-rule (bind id id2)
(begin
(require (for-label racket/serialize))
(define id (racket define-serializable-struct))
(define id2 (racket define-serializable-struct/versions))))
(bind racket-define-serializable-struct racket-define-serializable-struct/versions))
(define-syntax-rule (bind id id2)
(begin
(require (for-label racket/serialize))
(define id (racket define-serializable-struct))
(define id2 (racket define-serializable-struct/versions))))
(bind racket-define-serializable-struct
racket-define-serializable-struct/versions))
@mzlib[#:mode title serialize]

View File

@ -52,10 +52,10 @@ property.
@examples[
#:eval struct-eval
(define-struct/properties point (x y)
([prop:custom-write (lambda (p port write?)
(fprintf port "(~a, ~a)"
(point-x p)
(point-y p)))]))
([prop:custom-write (lambda (p port write?)
(fprintf port "(~a, ~a)"
(point-x p)
(point-y p)))]))
(display (make-point 1 2))
]}

View File

@ -10,13 +10,13 @@ library provides working versions of @racket[transcript-on] and
@racket[transcript-off].
@(define-syntax-rule (go)
(begin
(require (for-label mzlib/transcr))
(begin
(require (for-label mzlib/transcr))
@deftogether[(
@defproc[(transcript-on [filename any/c]) any]
@defproc[(transcript-off) any]
)]{
@deftogether[(
@defproc[(transcript-on [filename any/c]) any]
@defproc[(transcript-off) any]
)]{
Starts/stops recording a transcript at @racket[filename].}))
@(go)

View File

@ -3,16 +3,16 @@
(for-label mzlib/unit))
@(begin
(define-syntax-rule (bind id)
(begin
(require (for-label racket/unit))
(define id (racket struct))))
(bind racket-struct)
(define-syntax-rule (bindc id)
(begin
(require (for-label racket/unit))
(define id (racket struct/ctc))))
(bindc racket-struct/ctc))
(define-syntax-rule (bind id)
(begin
(require (for-label racket/unit))
(define id (racket struct))))
(bind racket-struct)
(define-syntax-rule (bindc id)
(begin
(require (for-label racket/unit))
(define id (racket struct/ctc))))
(bindc racket-struct/ctc))
@mzlib[#:mode title unit]

View File

@ -22,22 +22,22 @@
base-free-identifier=? base-free-template-identifier=?
base-free-transformer-identifier=? base-free-label-identifier=?)
(begin
(require (for-label scheme/base))
(define base-define (racket define))
(define base-define-syntax (racket define-syntax))
(define base-define-for-syntax (racket define-for-syntax))
(define base-define-struct (racket define-struct))
(define base-if (racket if))
(define base-cond (racket cond))
(define base-case (racket case))
(define base-top-interaction (racket #%top-interaction))
(define base-open-input-file (racket open-input-file))
(define base-apply (racket apply))
(define base-prop:procedure (racket prop:procedure))
(define base-free-identifier=? (racket free-identifier=?))
(define base-free-template-identifier=? (racket free-template-identifier=?))
(define base-free-transformer-identifier=? (racket free-transformer-identifier=?))
(define base-free-label-identifier=? (racket free-label-identifier=?))))
(require (for-label scheme/base))
(define base-define (racket define))
(define base-define-syntax (racket define-syntax))
(define base-define-for-syntax (racket define-for-syntax))
(define base-define-struct (racket define-struct))
(define base-if (racket if))
(define base-cond (racket cond))
(define base-case (racket case))
(define base-top-interaction (racket #%top-interaction))
(define base-open-input-file (racket open-input-file))
(define base-apply (racket apply))
(define base-prop:procedure (racket prop:procedure))
(define base-free-identifier=? (racket free-identifier=?))
(define base-free-template-identifier=? (racket free-template-identifier=?))
(define base-free-transformer-identifier=? (racket free-transformer-identifier=?))
(define base-free-label-identifier=? (racket free-label-identifier=?))))
@(def-base base-define base-define-syntax base-define-for-syntax base-define-struct
base-if base-cond base-case base-top-interaction
base-open-input-file base-apply base-prop:procedure

View File

@ -110,11 +110,11 @@ Raised for errors when handling cookies.}
@subsection{Creating a cookie}
@racketblock[
(let ((c (cookie:add-max-age
(let ([c (cookie:add-max-age
(cookie:add-path
(set-cookie "foo" "bar")
"/servlets")
3600)))
3600)])
(print-cookie c))
]

View File

@ -343,7 +343,7 @@ characters, @racket[char-lower-case?] characters, etc.}
@(define-syntax-rule (lex-sre-doc)
(...
(begin
(require (for-label parser-tools/lex-sre))
(require (for-label parser-tools/lex-sre))
@defform[(* re ...)]{
@ -417,7 +417,7 @@ characters.}
@(define-syntax-rule (lex-v200-doc)
(...
(begin
(require (for-label parser-tools/lex-plt-v200))
(require (for-label parser-tools/lex-plt-v200))
@t{The @racketmodname[parser-tools/lex-plt-v200] module re-exports
@racket[*], @racket[+], @racket[?], and @racket[&] from

View File

@ -199,19 +199,19 @@ the bounds of the image, returns a transparent color.}
[f (-> natural-number/c natural-number/c color?)])
image?]{
Builds an image of the specified size and shape by calling the specified function
on the coordinates of each pixel. For example,
Builds an image of the specified size and shape by calling the specified
function on the coordinates of each pixel. For example,
@codeblock|{
; fuzz : image -> image
(define (fuzz pic)
(local [; near-pixel : num(x) num(y) -> color
(define (near-pixel x y)
(get-pixel-color (+ x -3 (random 7))
(+ y -3 (random 7))
pic))]
(build-image (image-width pic)
(image-height pic)
near-pixel)))
(local [; near-pixel : num(x) num(y) -> color
(define (near-pixel x y)
(get-pixel-color (+ x -3 (random 7))
(+ y -3 (random 7))
pic))]
(build-image (image-width pic)
(image-height pic)
near-pixel)))
}|
produces a fuzzy version of the given picture by replacing each pixel with a
randomly chosen pixel near it.}
@ -268,7 +268,7 @@ size and shape. For example,
@codeblock|{
; lose-red : num(x) num(y) color -> color
(define (lose-red x y old-color)
(make-color 0 (color-green old-color) (color-blue old-color)))
(make-color 0 (color-green old-color) (color-blue old-color)))
(map-image lose-red my-picture)}|
produces a copy of @racket[my-picture] with all the red leached out,
@ -286,9 +286,9 @@ Another example:
@codeblock|{
; apply-gradient : num(x) num(y) color -> color
(define (apply-gradient x y old-color)
(make-color (min (* 3 x) 255)
0
(min (* 3 y) 255)))
(make-color (min (* 3 x) 255)
0
(min (* 3 y) 255)))
(map-image apply-gradient my-picture)}|
produces a picture the size of @racket[my-picture]'s bounding rectangle,
@ -402,12 +402,12 @@ For example,
@codeblock|{
; bad-gradient : num(x) num(y) -> color
(define (bad-gradient x y)
(make-color (* 2.5 x) (* 1.6 y) 0))
(make-color (* 2.5 x) (* 1.6 y) 0))
(build-image 50 30 bad-gradient)
; good-gradient : num(x) num(y) -> color
(define (good-gradient x y)
(make-color (real->int (* 2.5 x)) (real->int (* 1.6 y)) 0))
(make-color (real->int (* 2.5 x)) (real->int (* 1.6 y)) 0))
(build-image 50 30 good-gradient)
}|
The version using @racket[bad-gradient] crashes because color components must be exact integers.
@ -462,15 +462,15 @@ its output into a string, which is returned. Especially useful for testing:
@codeblock|{
; ask : string -> prints output, waits for text input, returns it
(define (ask question)
(begin (display question)
(read)))
(begin (display question)
(read)))
; greet : nothing -> prints output, waits for text input, prints output
(define (greet)
(local [(define name (ask "What is your name?"))]
(printf "Hello, ~a!" name)))
(local [(define name (ask "What is your name?"))]
(printf "Hello, ~a!" name)))
(check-expect
(with-io-strings "Steve" greet)
"What is your name?Hello, Steve!")}|
(with-io-strings "Steve" greet)
"What is your name?Hello, Steve!")}|
}
@; @include-section{worlds.scrbl}

View File

@ -229,7 +229,6 @@ The @racket[pkg] argument must end with @racket[".plt"].
}
@defproc[(get-package-spec [owner string?]
[pkg (and/c string? #rx"[.]plt$")]
[maj (or/c #f natural-number/c) #f]
@ -284,7 +283,8 @@ See also @racket[build-scribble-docs?] and @racket[force-package-building?]
}
@defparam[force-package-building? b boolean?]{
Determines if @racket[make-planet-archive] is more strict and thus aborts more often.
Determines if @racket[make-planet-archive] is more strict and thus
aborts more often.
}
@defproc[(download-package [pkg-spec pkg-spec?])
@ -418,7 +418,8 @@ produces a list corresponding to its name and version, exactly like
}
@defproc[(pkg? [v any/c]) boolean?]{
Determines if its argument is a pkg, the representation of an installed package.
Determines if its argument is a pkg, the representation of an
installed package.
}
@section[#:tag "version.rkt"]{Package Version}

View File

@ -181,15 +181,15 @@ function, we could do the following:
#:segments [segments 20]
#:color [color 'red]
#:width [width 1])
(let* ((dash-size (/ (- x-max x-min) segments))
(x-lists (build-list
(let* ([dash-size (/ (- x-max x-min) segments)]
[x-lists (build-list
(/ segments 2)
(lambda (index)
(x-values
(/ samples segments)
(+ x-min (* 2 index dash-size))
(+ x-min (* (add1 (* 2 index))
dash-size)))))))
dash-size)))))])
(lambda (2dview)
(send 2dview set-line-color color)
(send 2dview set-line-width width)

View File

@ -399,7 +399,7 @@ Dispatching-related bindings:
@racketblock[
(define (ttref)
(let ((url (get-arg)) (text (get-arg)))
(let ([url (get-arg)] [text (get-arg)])
(list "<a href=\"" url "\">@tt{" text "}</a>")))
]

View File

@ -247,8 +247,8 @@ Here's the implementation of @racket[fold-test-results] in terms of
kid-seed)
(lambda (case name action seed)
(case-fn
(run-test-case name action)
seed))
(run-test-case name action)
seed))
seed
test))
]

View File

@ -76,7 +76,7 @@ cases. Here's a simple test case written using the
@racketblock[
(test-begin
(let ((lst (list 2 4 6 9)))
(let ([lst (list 2 4 6 9)])
(check = (length lst) 4)
(for-each
(lambda (elt)
@ -111,7 +111,7 @@ we're testing. We can give a test case a name with the
@racketblock[
(test-case
"List has length 4 and all elements even"
(let ((lst (list 2 4 6 9)))
(let ([lst (list 2 4 6 9)])
(check = (length lst) 4)
(for-each
(lambda (elt)
@ -133,7 +133,7 @@ group them into a test suite:
(test-case
"List has length 4 and all elements even"
(let ((lst (list 2 4 6 9)))
(let ([lst (list 2 4 6 9)])
(check = (length lst) 4)
(for-each
(lambda (elt)

View File

@ -9,9 +9,9 @@
(apply item @index[(map (lambda (x) (format "~a keybinding" x)) keys) key-str] " : " desc)))
@(define-syntax-rule (def-mod-beg id)
(begin
(require (for-label racket/base))
(define id @racket[#%module-begin])))
(begin
(require (for-label racket/base))
(define id @racket[#%module-begin])))
@(def-mod-beg mz-mod-begin)
@title{Keyboard Shortcuts}

View File

@ -36,15 +36,15 @@
@racketblock[
(class ...
...
(define status-panel #f)
(define/override (make-root-area-container cls parent)
(set! status-panel
(super make-root-area-container vertical-panel% parent))
(let ([root (make-object cls status-panel)])
(define status-panel #f)
(define/override (make-root-area-container cls parent)
(set! status-panel
(super make-root-area-container vertical-panel% parent))
(let ([root (make-object cls status-panel)])
(code:comment "... add other children to status-panel ...")
(code:comment "... add other children to status-panel ...")
root))
root))
...)]
In this example, status-panel will contain a root panel for the other

View File

@ -9,11 +9,11 @@
(except-in wxme/cache-image reader)))
@(define-syntax-rule (in mod . content)
(begin
(define-syntax-rule (intro)
(begin (require (for-label mod))
. content))
(intro)))
(begin
(define-syntax-rule (intro)
(begin (require (for-label mod))
. content))
(intro)))
@title{WXME Decoding}

View File

@ -94,8 +94,8 @@ apply a function like @racket[+] to all of the items in the list:
@def+int[
(define (avg lst) (code:comment @#,elem{doesn't always work...})
(/ (+ (list-ref lst 0) (list-ref lst 1) (list-ref lst 2))
(length lst)))
(/ (+ (list-ref lst 0) (list-ref lst 1) (list-ref lst 2))
(length lst)))
(avg '(1 2 3))
(avg '(1 2))
]

View File

@ -28,9 +28,9 @@ tail position with respect to the @racket[begin] form.
(if (zero? height)
(void)
(begin
(display (make-string height #\*))
(newline)
(print-triangle (sub1 height)))))
(display (make-string height #\*))
(newline)
(print-triangle (sub1 height)))))
(print-triangle 4)
]
@ -55,10 +55,10 @@ positions, instead of forming an expression, the content of
@defexamples[
(let ([curly 0])
(begin
(define moe (+ 1 curly))
(define larry (+ 1 moe)))
(list larry curly moe))
(begin
(define moe (+ 1 curly))
(define larry (+ 1 moe)))
(list larry curly moe))
]
This splicing behavior is mainly useful for macros, as we discuss
@ -114,13 +114,13 @@ result is @racket[#f].
@defexamples[
(define (enumerate lst)
(if (null? (cdr lst))
(printf "~a.\n" (car lst))
(begin
(printf "~a, " (car lst))
(when (null? (cdr (cdr lst)))
(printf "and "))
(enumerate (cdr lst)))))
(if (null? (cdr lst))
(printf "~a.\n" (car lst))
(begin
(printf "~a, " (car lst))
(when (null? (cdr (cdr lst)))
(printf "and "))
(enumerate (cdr lst)))))
(enumerate '("Larry" "Curly" "Moe"))
]

View File

@ -742,8 +742,8 @@ applied first. Then the method-implementing mixins can use
(class % ....
(define/public (get-color) (void))))
(lambda (get-color get-price %) ....
(class % ....
(define/override (get-color) 'black))))
(class % ....
(define/override (get-color) 'black))))
(list (local-member-name-key get-price)
(lambda (get-price get-color %) ....
(class % ....
@ -752,7 +752,7 @@ applied first. Then the method-implementing mixins can use
(class % ....
(inherit get-color)
(define/override (get-price)
.... (get-color) ....))))))
.... (get-color) ....))))))
]
With this trait encoding, @racket[trait-alias] adds a new method with

View File

@ -60,9 +60,9 @@ racket
[argmax
(->i ([f (-> any/c real?)] [lov (and/c pair? list?)]) ()
(r (f lov)
(lambda (r)
(define f@r (f r))
(for/and ((v lov)) (>= f@r (f v))))))])
(lambda (r)
(define f@r (f r))
(for/and ([v lov]) (>= f@r (f v))))))])
]
It is a @emph{dependent} contract that names the two arguments and uses
the names to impose a predicate on the result. This predicate computes
@ -84,9 +84,8 @@ racket
(r (f lov)
(lambda (r)
(define f@r (f r))
(and
(memq r lov)
(for/and ((v lov)) (>= f@r (f v)))))))])
(and (memq r lov)
(for/and ([v lov]) (>= f@r (f v)))))))])
]
The @racket[memq] function ensures that @racket[r] is @emph{intensionally equal}
@margin-note*{That is, "pointer equality" for those who prefer to think at
@ -113,7 +112,7 @@ racket
(r (f lov)
(lambda (r)
(define f@r (f r))
(and (for/and ((v lov)) (>= f@r (f v)))
(and (for/and ([v lov]) (>= f@r (f v)))
(eq? (first (memf (lambda (v) (= (f v) f@r)) lov))
r)))))])
]
@ -157,7 +156,7 @@ racket
@code:comment{@#,dominates1}
(define (dominates-all f@r f lov)
(for/and ((v lov)) (>= (f v) f@r)))
(for/and ([v lov]) (>= (f v) f@r)))
@code:comment{@#,first?1}
(define (is-first-max? r f@r f lov)
@ -199,7 +198,7 @@ racket
@code:comment{@#,dominates2}
(define (dominates-all f@r flov)
(for/and ((f@v flov)) (>= f@r f@v)))
(for/and ([f@v flov]) (>= f@r f@v)))
@code:comment{@#,first?2}
(define (is-first-max? r f@r lov+flov)

View File

@ -81,10 +81,9 @@ streams like this:
@interaction[
#:eval e
(define stream/c
(promise/c
(or/c
null?
(cons/c number? stream/c))))
(promise/c
(or/c null?
(cons/c number? stream/c))))
]
@close-eval[e]
@ -96,11 +95,10 @@ values that they accept do not.
Instead, use
@racketblock[
(define stream/c
(promise/c
(or/c
null?
(cons/c 1
(recursive-contract stream/c)))))
(promise/c
(or/c
null?
(cons/c 1 (recursive-contract stream/c)))))
]
The use of @racket[recursive-contract] delays the evaluation of the

View File

@ -95,14 +95,14 @@ the requiring module, just to give an idea:
(module m racket
(require mzlib/contract)
(provide/contract [x x-ctc]))
(provide/contract [x x-ctc]))
(module n racket (require m) (define (f) ... x ...))
==>
(module n racket
(require (rename m x x-real))
(define x (apply-contract x-real x-ctc ...))
(define (f) ... x ...))
(require (rename m x x-real))
(define x (apply-contract x-real x-ctc ...))
(define (f) ... x ...))
The intention is to only do the work of applying the
contract once (per variable reference to a

View File

@ -261,7 +261,7 @@ resulting iteration can be performed more efficiently than plain
@racket[for/vector] or @racket[for*/vector]:
@interaction[
(let ((chapters '("Intro" "Details" "Conclusion")))
(let ([chapters '("Intro" "Details" "Conclusion")])
(for/vector #:length (length chapters) ([i (in-naturals 1)]
[chapter chapters])
(string-append (number->string i) ". " chapter)))

View File

@ -64,18 +64,18 @@ Consider the following core of a Mandelbrot-set computation:
@racketblock[
(define (mandelbrot iterations x y n)
(let ((ci (- (/ (* 2.0 y) n) 1.0))
(cr (- (/ (* 2.0 x) n) 1.5)))
(let loop ((i 0) (zr 0.0) (zi 0.0))
(let ([ci (- (/ (* 2.0 y) n) 1.0)]
[cr (- (/ (* 2.0 x) n) 1.5)])
(let loop ([i 0] [zr 0.0] [zi 0.0])
(if (> i iterations)
i
(let ((zrq (* zr zr))
(ziq (* zi zi)))
(let ([zrq (* zr zr)]
[ziq (* zi zi)])
(cond
((> (+ zrq ziq) 4.0) i)
(else (loop (add1 i)
(+ (- zrq ziq) cr)
(+ (* 2.0 zr zi) ci)))))))))
[(> (+ zrq ziq) 4.0) i]
[else (loop (add1 i)
(+ (- zrq ziq) cr)
(+ (* 2.0 zr zi) ci))]))))))
]
The expressions @racket[(mandelbrot 10000000 62 500 1000)] and
@ -110,8 +110,8 @@ first the problem:
@racketblock[
(define (mandelbrot iterations x y n)
(let ((ci (- (/ (* 2.0 (->fl y)) (->fl n)) 1.0))
(cr (- (/ (* 2.0 (->fl x)) (->fl n)) 1.5)))
(let ([ci (- (/ (* 2.0 (->fl y)) (->fl n)) 1.0)]
[cr (- (/ (* 2.0 (->fl x)) (->fl n)) 1.5)])
....))
]
@ -128,18 +128,18 @@ much less allocation:
@racketblock[
(define (mandelbrot iterations x y n)
(let ((ci (fl- (fl/ (* 2.0 (->fl y)) (->fl n)) 1.0))
(cr (fl- (fl/ (* 2.0 (->fl x)) (->fl n)) 1.5)))
(let loop ((i 0) (zr 0.0) (zi 0.0))
(let ([ci (fl- (fl/ (* 2.0 (->fl y)) (->fl n)) 1.0)]
[cr (fl- (fl/ (* 2.0 (->fl x)) (->fl n)) 1.5)])
(let loop ([i 0] [zr 0.0] [zi 0.0])
(if (> i iterations)
i
(let ((zrq (fl* zr zr))
(ziq (fl* zi zi)))
(let ([zrq (fl* zr zr)]
[ziq (fl* zi zi)])
(cond
((fl> (fl+ zrq ziq) 4.0) i)
(else (loop (add1 i)
(fl+ (fl- zrq ziq) cr)
(fl+ (fl* 2.0 (fl* zr zi)) ci)))))))))
[(fl> (fl+ zrq ziq) 4.0) i]
[else (loop (add1 i)
(fl+ (fl- zrq ziq) cr)
(fl+ (fl* 2.0 (fl* zr zi)) ci))]))))))
]
This conversion can speed @racket[mandelbrot] by a factor of 8, even

View File

@ -315,8 +315,8 @@ the source form are identifiers. We could use a
(syntax-case stx ()
[(rotate a c ...)
(begin
(check-ids stx #'(a c ...))
#'(shift-to (c ... a) (a c ...)))]))
(check-ids stx #'(a c ...))
#'(shift-to (c ... a) (a c ...)))]))
]
The @racket[check-ids] function can use the @racket[syntax->list]

View File

@ -217,13 +217,13 @@ racket
(+ n 17))
(define-syntax (def-go stx)
(syntax-case stx ()
[(_ go)
(protect-syntax
#'(define-syntax (go stx)
(syntax-case stx ()
[(_ x)
(protect-syntax #'(unchecked-go 8 x))])))]))
(syntax-case stx ()
[(_ go)
(protect-syntax
#'(define-syntax (go stx)
(syntax-case stx ()
[(_ x)
(protect-syntax #'(unchecked-go 8 x))])))]))
]
When @racket[def-go] is used inside another module to defined
@ -247,13 +247,13 @@ racket
(lambda (stx) (syntax-arm stx insp))))
(define-syntax (def-go stx)
(syntax-case stx ()
[(_ go)
(protect-syntax
#'(define-syntax (go stx)
(syntax-case stx ()
[(_ x)
(go-syntax-protect #'(unchecked-go 8 x))])))]))
(syntax-case stx ()
[(_ go)
(protect-syntax
#'(define-syntax (go stx)
(syntax-case stx ()
[(_ x)
(go-syntax-protect #'(unchecked-go 8 x))])))]))
]
@;------------------------------------------------------------------------

View File

@ -313,28 +313,28 @@ racket
(define toy-store@-maker
(lambda (the-color)
(unit
(import toy-factory^)
(export toy-store^)
(unit
(import toy-factory^)
(export toy-store^)
(define inventory null)
(define inventory null)
(define (store-color) the-color)
(define (store-color) the-color)
(code:comment @#,t{the rest is the same as before})
(code:comment @#,t{the rest is the same as before})
(define (maybe-repaint t)
(if (eq? (toy-color t) (store-color))
t
(repaint t (store-color))))
(define (maybe-repaint t)
(if (eq? (toy-color t) (store-color))
t
(repaint t (store-color))))
(define (stock! n)
(set! inventory
(append inventory
(map maybe-repaint
(build-toys n)))))
(define (stock! n)
(set! inventory
(append inventory
(map maybe-repaint
(build-toys n)))))
(define (get-inventory) inventory))))
(define (get-inventory) inventory))))
(provide toy-store@-maker)
]

View File

@ -6,11 +6,11 @@
(only-in setup/infotab require)))
@(begin
(define-syntax-rule (define-racket-require id)
(begin
(require (for-label (only-in racket require)))
(define id @racket[require])))
(define-racket-require racket:require))
(define-syntax-rule (define-racket-require id)
(begin
(require (for-label (only-in racket require)))
(define id @racket[require])))
(define-racket-require racket:require))
@title[#:tag "info.rkt"]{@filepath{info.rkt} File Format}

View File

@ -384,8 +384,8 @@ result will not call @racket[proc] with @racket['unlock].)
(when ok-to-compile?
(printf "Do compile here ...\n")))
(lambda ()
(when locked?
(lc 'unlock zo-name)))))
(when locked?
(lc 'unlock zo-name)))))
]
}

View File

@ -27,12 +27,12 @@
racket/future))
@(define-syntax-rule (local-module mod . body)
(begin
(define-syntax-rule (go)
(begin
(require (for-label mod))
. body))
(go)))
(begin
(define-syntax-rule (go)
(begin
(require (for-label mod))
. body))
(go)))
@(define ref-src
'(lib "scribblings/reference/reference.scrbl"))

View File

@ -280,7 +280,8 @@ For communication among @tech{places}, the new byte string is allocated in the
the other operations.
@examples[
(define b
(bytes->string/utf-8 (bytes #xc3 #xa7 #xc3 #xb0 #xc3 #xb6 #xc2 #xa3)))
(bytes->string/utf-8
(bytes #xc3 #xa7 #xc3 #xb0 #xc3 #xb6 #xc2 #xa3)))
(string->bytes/utf-8 b)
(bytes->string/utf-8 (string->bytes/utf-8 b))
@ -316,7 +317,7 @@ For communication among @tech{places}, the new byte string is allocated in the
@examples[
(define b
(bytes->string/latin-1 (bytes #xfe #xd3 #xd1 #xa5)))
(bytes->string/latin-1 (bytes #xfe #xd3 #xd1 #xa5)))
(string->bytes/latin-1 b)
(bytes->string/latin-1 (string->bytes/latin-1 b))

View File

@ -12,15 +12,15 @@
[(_ s ... s0) (elem (elem ", " (secref s)) ... ", and " (secref s0))]))
(define-syntax (defclassforms stx)
(syntax-case stx (*)
[(_ [* (form ...) (also ...)])
#'(defform* (form ...)
"See " @racket[class*] (sees also ...) "; use"
" outside the body of a " @racket[class*] " form is a syntax error.")]
[(_ [form (also ...)])
#'(defclassforms [* (form) (also ...)])]
[(_ form ...)
#'(begin (defclassforms form) ...)]))
(syntax-case stx (*)
[(_ [* (form ...) (also ...)])
#'(defform* (form ...)
"See " @racket[class*] (sees also ...) "; use"
" outside the body of a " @racket[class*] " form is a syntax error.")]
[(_ [form (also ...)])
#'(defclassforms [* (form) (also ...)])]
[(_ form ...)
#'(begin (defclassforms form) ...)]))
(define-syntax (defstarshorthands stx)
(syntax-case stx ()
@ -292,13 +292,13 @@ interface @racket[(class->interface object%)], and is transparent
(lambda kw-formals expr ...+)
(case-lambda (formals expr ...+) ...)
(#%plain-lambda formals expr ...+)
(let-values (((id) method-procedure) ...)
(let-values ([(id) method-procedure] ...)
method-procedure)
(letrec-values (((id) method-procedure) ...)
(letrec-values ([(id) method-procedure] ...)
method-procedure)
(let-values (((id) method-procedure) ...+)
(let-values ([(id) method-procedure] ...+)
id)
(letrec-values (((id) method-procedure) ...+)
(letrec-values ([(id) method-procedure] ...+)
id)])]{
Produces a class value.
@ -1366,11 +1366,11 @@ Produces a @tech{trait} that combines all of the methods of the given
@racketblock[
(define t1
(trait
(define/public (m1) 1)))
(trait
(define/public (m1) 1)))
(define t2
(trait
(define/public (m2) 2)))
(trait
(define/public (m2) 2)))
(define t3 (trait-sum t1 t2))
]
@ -1378,8 +1378,8 @@ creates a trait @racket[t3] that is equivalent to
@racketblock[
(trait
(define/public (m1) 1)
(define/public (m2) 2))
(define/public (m1) 1)
(define/public (m2) 2))
]
but @racket[t1] and @racket[t2] can still be used individually or

View File

@ -173,9 +173,9 @@ default error display handler (see
@examples[
(define (extract-current-continuation-marks key)
(continuation-mark-set->list
(current-continuation-marks)
key))
(continuation-mark-set->list
(current-continuation-marks)
key))
(with-continuation-mark 'key 'mark
(extract-current-continuation-marks 'key))

View File

@ -9,27 +9,27 @@
;; hacky?
(define file-eval
(lambda ()
(let ([the-eval (make-base-eval)])
(the-eval '(require (for-syntax racket/base)
racket/file))
(the-eval '(define some-file (make-temporary-file)))
(the-eval '(define some-other-file (make-temporary-file)))
the-eval)))
(lambda ()
(let ([the-eval (make-base-eval)])
(the-eval '(require (for-syntax racket/base)
racket/file))
(the-eval '(define some-file (make-temporary-file)))
(the-eval '(define some-other-file (make-temporary-file)))
the-eval)))
(define-syntax file-examples
(syntax-rules ()
[(_ expr ...)
(let [(my-eval (file-eval))]
(define (clean)
(my-eval '(for [(i (list some-file some-other-file))]
(when (file-exists? i)
(delete-file i)))))
(clean)
(begin0
(defexamples #:eval my-eval
expr ...)
(clean)))]))
(define (clean)
(my-eval '(for [(i (list some-file some-other-file))]
(when (file-exists? i)
(delete-file i)))))
(clean)
(begin0
(defexamples #:eval my-eval
expr ...)
(clean)))]))
"")

View File

@ -196,4 +196,3 @@ For communication among @tech{places}, the new @tech{fxvector} is
allocated in the @tech{shared memory space}.
@mz-examples[#:eval flfx-eval (make-shared-fxvector 4 3)]}

View File

@ -144,8 +144,8 @@ is equivalent to
@racketblock[
(let ([l (current-logger)])
(when (log-level? l '@#,racket[_level])
(log-message l '@#,racket[_level] string-expr
(current-continuation-marks))))
(log-message l '@#,racket[_level] string-expr
(current-continuation-marks))))
]}
@; ----------------------------------------

View File

@ -481,7 +481,8 @@ instead of @racket[match].}
type named @racket[struct-id], where the field @racket[field] in the
instance matches the corresponding @racket[pat].
Any field of @racket[struct-id] may be omitted, and such fields can occur in any order.
Any field of @racket[struct-id] may be omitted, and such fields can
occur in any order.
@defexamples[
#:eval match-eval

View File

@ -44,7 +44,7 @@ new parameter value. A guard procedure can raise an exception to
reject a change to the parameter's value. The @racket[guard] is not
applied to the initial @racket[v].}
@defform[(parameterize ((parameter-expr value-expr) ...)
@defform[(parameterize ([parameter-expr value-expr] ...)
body ...+)
#:contracts
([parameter-expr parameter?])]{

View File

@ -739,8 +739,8 @@ values from the generator.
(if (null? x)
0
(begin
(yield (car x))
(loop (cdr x)))))))
(yield (car x))
(loop (cdr x)))))))
(g)
(g)
(g)
@ -812,8 +812,8 @@ Produces a @tech{sequence} that encapsulates the @tech{generator} formed by
(if (null? x)
my-stop-value
(begin
(yield (car x))
(loop (cdr x)))))))
(yield (car x))
(loop (cdr x)))))))
(for/list ([i (in-producer my-generator my-stop-value)])
i)]}

View File

@ -24,7 +24,7 @@ used as a macro that expands to a use of the target identifier, but
@racket[syntax-local-value] of @racket[id] does not produce
the target's value.}
@defform[(syntax-parameterize ((id expr) ...) body-expr ...+)]{
@defform[(syntax-parameterize ([id expr] ...) body-expr ...+)]{
@margin-note/ref{See also @racket[splicing-syntax-parameterize].}

View File

@ -139,7 +139,7 @@ For example, the expression
expands to
@racketblock[
(let ((or-part x)) (if or-part or-part (or y)))
(let ([or-part x]) (if or-part or-part (or y)))
]
which, in turn, expands to

View File

@ -210,9 +210,9 @@ the binding (according to @racket[free-identifier=?]) matters.}
(if expr expr expr)
(begin expr ...+)
(begin0 expr expr ...)
(let-values (((id ...) expr) ...)
(let-values ([(id ...) expr] ...)
expr ...+)
(letrec-values (((id ...) expr) ...)
(letrec-values ([(id ...) expr] ...)
expr ...+)
(set! id expr)
(@#,racket[quote] datum)
@ -756,21 +756,21 @@ bucket-2
(syntax-rules ()
[(def-and-use)
(begin
(code:comment @#,t{Initial reference to @racket[even] precedes definition:})
(define (odd x) (if (zero? x) #f (even (sub1 x))))
(define (even x) (if (zero? x) #t (odd (sub1 x))))
(odd 17))]))
(code:comment @#,t{Initial reference to @racket[even] precedes definition:})
(define (odd x) (if (zero? x) #f (even (sub1 x))))
(define (even x) (if (zero? x) #t (odd (sub1 x))))
(odd 17))]))
(defs-and-uses/fail)
(define-syntax defs-and-uses
(syntax-rules ()
[(def-and-use)
(begin
(code:comment @#,t{Declare before definition via no-values @racket[define-syntaxes]:})
(define-syntaxes (odd even) (values))
(define (odd x) (if (zero? x) #f (even (sub1 x))))
(define (even x) (if (zero? x) #t (odd (sub1 x))))
(odd 17))]))
(code:comment @#,t{Declare before definition via no-values @racket[define-syntaxes]:})
(define-syntaxes (odd even) (values))
(define (odd x) (if (zero? x) #f (even (sub1 x))))
(define (even x) (if (zero? x) #t (odd (sub1 x))))
(odd 17))]))
(defs-and-uses)
]

View File

@ -109,7 +109,7 @@ is prefixed with the special form name as described under
@examples[#:eval the-eval
(wrong-syntax #'here "expected ~s" 'there)
(parameterize ((current-syntax-context #'(look over here)))
(parameterize ([current-syntax-context #'(look over here)])
(wrong-syntax #'here "expected ~s" 'there))
]
@ -117,7 +117,7 @@ A macro using @racket[wrong-syntax] might set the syntax context at the very
beginning of its transformation as follows:
@RACKETBLOCK[
(define-syntax (my-macro stx)
(parameterize ((current-syntax-context stx))
(parameterize ([current-syntax-context stx])
(syntax-case stx ()
___)))
]

View File

@ -905,18 +905,18 @@ follows.
chickens))
(module nest2 racket
(define-for-syntax eggs 2)
(provide (for-syntax eggs)))
(define-for-syntax eggs 2)
(provide (for-syntax eggs)))
(require (for-meta 2 racket/base)
(for-syntax 'nest2))
(define-syntax (test stx)
(define-syntax (show-eggs stx)
(printf "Eggs are ~a\n" eggs)
#'0)
(begin
(show-eggs)
#'0))
(test)
(define-syntax (show-eggs stx)
(printf "Eggs are ~a\n" eggs)
#'0)
(begin
(show-eggs)
#'0))
(test)
]}
@specsubform[#:literals (for-syntax)
@ -2144,8 +2144,8 @@ be defined by the same @racket[define-for-syntax] form.
@defexamples[#:eval (syntax-eval)
(define-for-syntax helper 2)
(define-syntax (make-two syntax-object)
(printf "helper is ~a\n" helper)
#'2)
(printf "helper is ~a\n" helper)
#'2)
(make-two)
(code:comment @#,t{`helper' is not bound in the runtime phase})
helper

View File

@ -3,8 +3,8 @@
@(define-syntax-rule (def base-author)
(begin
(require (for-label scribble/base))
(define base-author @racket[author])))
(require (for-label scribble/base))
(define base-author @racket[author])))
@(def base-author)
@title{JFP Paper Format}

View File

@ -4,8 +4,8 @@
@(define-syntax-rule (def base-author)
(begin
(require (for-label scribble/base))
(define base-author @racket[author])))
(require (for-label scribble/base))
(define base-author @racket[author])))
@(def base-author)
@title{LNCS Paper Format}

View File

@ -16,9 +16,9 @@
@(begin
(define-syntax-rule (def-render-mixin id)
(begin
(require (for-label scribble/html-render))
(define id @racket[render-mixin])))
(begin
(require (for-label scribble/html-render))
(define id @racket[render-mixin])))
(def-render-mixin html:render-mixin))
@title[#:tag "renderer"]{Renderers}

View File

@ -117,8 +117,8 @@ form.}
(->d (arg ...) () #:rest id rest [id result])])]{
Like @racket[proc-doc], but supporting contract forms that embed
argument names. Only a subset of @racket[->i] and @racket[->d] forms are currently
supported.}
argument names. Only a subset of @racket[->i] and @racket[->d] forms are
currently supported.}
@defform[(thing-doc id contract-expr dec-expr)]{

View File

@ -163,7 +163,6 @@ Transfers cross-reference information to @racket[ci], which is the
initially collected information from @racket[renderer].}
@defproc[(xref-index [xref xref?]) (listof entry?)]{
Converts indexing information @racket[xref] into a list of

View File

@ -83,12 +83,12 @@ language [*]:
"#<procedure:closure-storing-proc>"
(#%plain-lambda (x)
(begin
(let-values (((arg0-1643 arg1-1644 arg2-1645)
(let-values ([(arg0-1643 arg1-1644 arg2-1645)
(#%plain-app
values
"#<*unevaluated-struct*>"
"#<*unevaluated-struct*>"
"#<*unevaluated-struct*>")))
"#<*unevaluated-struct*>")])
(with-continuation-mark "#<debug-key-struct>"
(#%plain-lambda ()
(#%plain-app
@ -161,7 +161,7 @@ language [*]:
#f
(#%plain-lambda () (#%plain-app list f))))))))
(let-values (((done-already?) (quote #f)))
(let-values ([(done-already?) (quote #f)])
(#%app dynamic-wind void
(lambda () (#%app dynamic-require (quote (quote #%htdp)) (quote #f)))
(lambda () (if done-already?

View File

@ -2,9 +2,9 @@
@(require "common.rkt" (for-label syntax/kerncase))
@(define-syntax-rule (intro id)
(begin
(require (for-label mzscheme))
(define id (racket if))))
(begin
(require (for-label mzscheme))
(define id (racket if))))
@(intro mzscheme-if)
@; ----------------------------------------------------------------------

View File

@ -11,8 +11,8 @@
@(begin
(define the-eval
(parameterize ((sandbox-output 'string)
(sandbox-error-output 'string))
(parameterize ([sandbox-output 'string]
[sandbox-error-output 'string])
(make-evaluator 'racket/base #:requires '(syntax/keyword))))
;;(void (the-eval '(error-print-source-location #f)))
(define-syntax-rule (myexamples e ...)

View File

@ -6,11 +6,11 @@
read-syntax-inside read-inside)))
@(begin
(define-syntax-rule (define-mb name)
(begin
(require (for-label scheme/base))
(define name @racket[#%module-begin])))
(define-mb scheme-#%module-begin))
(define-syntax-rule (define-mb name)
(begin
(require (for-label scheme/base))
(define name @racket[#%module-begin])))
(define-mb scheme-#%module-begin))
@(define guide-doc '(lib "scribblings/guide/guide.scrbl"))

View File

@ -23,11 +23,11 @@ the parameter expressions.
[(_ ((p v:expr) ...) body:expr)
#:declare p (expr/c #'parameter?
#:name "parameter argument")
#'(parameterize ((p.c v) ...) body)]))
(myparameterize ((current-input-port
(open-input-string "(1 2 3)")))
#'(parameterize ([p.c v] ...) body)]))
(myparameterize ([current-input-port
(open-input-string "(1 2 3)")])
(read))
(myparameterize (('whoops 'something))
(myparameterize (['whoops 'something])
'whatever)
]

View File

@ -425,7 +425,6 @@ They all construct a triangle oriented as follows:
}
@defproc*[([(square [side-len (and/c real? (not/c negative?))]
[mode mode?]
[color image-color?])
@ -657,7 +656,6 @@ the @racket[point-count] argument determines how many points the star has.
(rectangle 40 40 "solid" "silver")
(rectangle 50 50 "solid" "seagreen"))]
}
@defproc[(overlay/offset [i1 image?] [x real?] [y real?] [i2 image?]) image?]{
@ -777,7 +775,6 @@ the @racket[point-count] argument determines how many points the star has.
(rectangle 30 30 50 "seagreen")
(rectangle 20 20 50 "seagreen"))]
}
@ -869,7 +866,6 @@ the @racket[point-count] argument determines how many points the star has.
(ellipse 20 30 "solid" "dimgray")
(ellipse 20 10 "solid" "black"))]
}
@defproc[(beside/align [y-place y-place?] [i1 image?] [i2 image?] [is image?] ...) image?]{
@ -894,7 +890,6 @@ the @racket[point-count] argument determines how many points the star has.
(text "ijy" 18 "black")
(text "ijy" 24 "black"))]
}
@ -907,7 +902,6 @@ the @racket[point-count] argument determines how many points the star has.
(ellipse 30 20 "solid" "dimgray")
(ellipse 10 20 "solid" "black"))]
}
@defproc[(above/align [x-place x-place?] [i1 image?] [i2 image?] [is image?] ...) image?]{
@ -928,7 +922,6 @@ the @racket[point-count] argument determines how many points the star has.
(ellipse 30 20 "solid" "darkolivegreen")
(ellipse 10 20 "solid" "darkgreen"))]
}
@section{Placing Images & Scenes}
@ -937,11 +930,11 @@ Placing images into scenes is particularly useful when building worlds
and universes using @racket[2htdp/universe].
@defproc*[([(empty-scene [width (and/c real? (not/c negative?))]
[height (and/c real? (not/c negative?))])
image?]
[height (and/c real? (not/c negative?))])
image?]
[(empty-scene [width (and/c real? (not/c negative?))]
[height (and/c real? (not/c negative?))]
[color image-color?])
[color image-color?])
image?])]{
Creates an empty scene, i.e., a white rectangle with a black outline.
@ -1201,9 +1194,10 @@ more expensive than with the other shapes.
([bitmap-spec rel-string
id])]{
Loads the bitmap specified by @racket[bitmap-spec]. If @racket[bitmap-spec] is a string, it is treated as a
relative path. If it is an identifier, it is treated like a require spec and used to refer to a file
in a collection.
Loads the bitmap specified by @racket[bitmap-spec]. If
@racket[bitmap-spec] is a string, it is treated as a relative path.
If it is an identifier, it is treated like a require spec and used to
refer to a file in a collection.
@image-examples[(bitmap icons/stop-16x16.png)
(bitmap icons/b-run.png)]

View File

@ -197,35 +197,35 @@ The other big change concerns key event handling and mouse event
@port[
@racketblock[
(define (change w a-key-event)
(cond
[(key=? a-key-event 'left)
(world-go w -DELTA)]
[(key=? a-key-event 'right)
(world-go w +DELTA)]
[(char? a-key-event)
w]
[(key=? a-key-event 'up)
(world-go w -DELTA)]
[(key=? a-key-event 'down)
(world-go w +DELTA)]
[else
w]))]
(cond
[(key=? a-key-event 'left)
(world-go w -DELTA)]
[(key=? a-key-event 'right)
(world-go w +DELTA)]
[(char? a-key-event)
w]
[(key=? a-key-event 'up)
(world-go w -DELTA)]
[(key=? a-key-event 'down)
(world-go w +DELTA)]
[else
w]))]
@; ---------------------------------
@racketblock[
(define (change w a-key-event)
(cond
[(key=? a-key-event "left")
(world-go w -DELTA)]
[(key=? a-key-event "right")
(world-go w +DELTA)]
[(= (string-length a-key-event) 1)
w]
[(key=? a-key-event "up")
(world-go w -DELTA)]
[(key=? a-key-event "down")
(world-go w +DELTA)]
[else
w]))
(cond
[(key=? a-key-event "left")
(world-go w -DELTA)]
[(key=? a-key-event "right")
(world-go w +DELTA)]
[(= (string-length a-key-event) 1)
w]
[(key=? a-key-event "up")
(world-go w -DELTA)]
[(key=? a-key-event "down")
(world-go w +DELTA)]
[else
w]))
]]
Note how the @racket[char?] clause changed. Since all chars are now
represented as strings containing one ``letter'', the program on the right

View File

@ -29,16 +29,15 @@ Example:
(racketblock
;; Advanced
(define (make-model dir)
(lambda (b e)
(begin
(view dir)
(printf "~a ~n" (control)))))
(lambda (b e)
(begin
(view dir)
(printf "~a ~n" (control)))))
(connect
(make-model "left")
(make-model "right")
(make-model "up")
(make-model "down"))
(connect (make-model "left")
(make-model "right")
(make-model "up")
(make-model "down"))
))
Now click on the four arrows. The message field contains the current
direction, the print-out the prior contents of the message field.

View File

@ -83,10 +83,10 @@ Example 2:
;; a text field, a message, and two buttons
;; fill in text and click OKAY
(define w
(create-window
(list
(list text1)
(list msg1)
(list (make-button "OKAY" respond)
(make-button "QUIT" (lambda (e) (hide-window w)))))))
(create-window
(list
(list text1)
(list msg1)
(list (make-button "OKAY" respond)
(make-button "QUIT" (lambda (e) (hide-window w)))))))
))

View File

@ -34,22 +34,27 @@ This module provides a macro for regular expression compilation.
pat])]{
Compiles a regular expression over match patterns to a @racket[machine].
The interpretation of the pattern language is mostly intuitive. The pattern language may be extended
with @racket[define-re-transformer]. @racket[dseq] allows bindings of the @racket[match] pattern to be
used in the rest of the regular expression. (Thus, they are not @emph{really} regular expressions.)
@racket[unquote] escapes to Racket to evaluate an expression that evaluates to a regular expression (this happens
once, at compile time.) @racket[rec] binds a Racket identifier to a delayed version of the inner expression; even
if the expression is initially accepting, this delayed version is never accepting.
The interpretation of the pattern language is mostly intuitive. The
pattern language may be extended with @racket[define-re-transformer].
@racket[dseq] allows bindings of the @racket[match] pattern to be used
in the rest of the regular expression. (Thus, they are not
@emph{really} regular expressions.) @racket[unquote] escapes to Racket
to evaluate an expression that evaluates to a regular expression (this
happens once, at compile time.) @racket[rec] binds a Racket identifier
to a delayed version of the inner expression; even if the expression is
initially accepting, this delayed version is never accepting.
The compiler will use an NFA, provided @racket[complement] and @racket[dseq] are not used. Otherwise,
many NFAs connected with the machine simulation functions from @racketmodname[unstable/automata/machine] are used.
The compiler will use an NFA, provided @racket[complement] and
@racket[dseq] are not used. Otherwise, many NFAs connected with the
machine simulation functions from
@racketmodname[unstable/automata/machine] are used.
}
@(define-syntax-rule (defidforms (id ...) . dat)
(deftogether ((defidform id) ...) . dat))
@defidforms[(complement seq union star epsilon nullset dseq rec)]{
Bindings for use in @racket[re].
Bindings for use in @racket[re].
}
@defform[(define-re-transformer id expr)]{
@ -127,9 +132,9 @@ This module provides a few transformers that extend the syntax of regular expres
[(list "B")])
(define-re-transformer my-opt
(syntax-rules ()
[(_ pat)
(union epsilon pat)]))
(syntax-rules ()
[(_ pat)
(union epsilon pat)]))
(test-re (my-opt "A")
[(list)

View File

@ -24,18 +24,26 @@
[name? identifier?]
[method identifier?])]{
Defines @racket[name] as a transformer binding for the static information about a new generic group.
Defines @racket[name] as a transformer binding for the static
information about a new generic group.
Defines @racket[prop:name] as a structure
type property. Structure types implementing this generic group should have this property where the value is a vector
with one element per @racket[method] where each value is
either @racket[#f] or a procedure with the same arity as specified by @racket[kw-formals*].
(@racket[kw-formals*] is similar to the @racket[kw-formals] used by @racket[lambda], except no expression is given for optional arguments.)
The arity of each method is checked by the guard on the structure type property.
Defines @racket[prop:name] as a structure type property. Structure
types implementing this generic group should have this property where
the value is a vector with one element per @racket[method] where each
value is either @racket[#f] or a procedure with the same arity as
specified by @racket[kw-formals*]. (@racket[kw-formals*] is similar to
the @racket[kw-formals] used by @racket[lambda], except no expression is
given for optional arguments.) The arity of each method is checked by
the guard on the structure type property.
Defines @racket[name?] as a predicate identifying instances of structure types that implement this generic group.
Defines @racket[name?] as a predicate identifying instances of structure
types that implement this generic group.
Defines each @racket[method] as a generic procedure that calls the corresponding method on values where @racket[name?] is true. Each method must have a required by-position argument that is @racket[free-identifier=?] to @racket[name]. This argument is used in the generic definition to locate the specialization.
Defines each @racket[method] as a generic procedure that calls the
corresponding method on values where @racket[name?] is true. Each method
must have a required by-position argument that is
@racket[free-identifier=?] to @racket[name]. This argument is used in
the generic definition to locate the specialization.
}
@ -61,13 +69,18 @@ context of @racket[name].
#:contracts
([name identifier?])]{
@racket[name] must be a transformer binding for the static information about a new generic group.
@racket[name] must be a transformer binding for the static information
about a new generic group.
Expands to a value usable as the property value for the structure type property of the @racket[name] generic group.
Expands to a value usable as the property value for the structure type
property of the @racket[name] generic group.
If the @racket[definition]s define the methods of @racket[name], then they are used in the property value.
If the @racket[definition]s define the methods of @racket[name], then
they are used in the property value.
If any method of @racket[name] is not defined, then @racket[#f] is used to signify that the structure type does not implement the particular method.
If any method of @racket[name] is not defined, then @racket[#f] is used
to signify that the structure type does not implement the particular
method.
Allows @racket[define/generic] to appear in @racket[definition ...].
@ -78,7 +91,9 @@ Allows @racket[define/generic] to appear in @racket[definition ...].
([local-name identifier?]
[method-name identifier?])]{
When used inside @racket[define-methods], binds @racket[local-name] to the generic for @racket[method-name]. This is useful for method specializations to use the generic methods on other values.
When used inside @racket[define-methods], binds @racket[local-name] to
the generic for @racket[method-name]. This is useful for method
specializations to use the generic methods on other values.
Syntactically an error when used outside @racket[define-methods].

View File

@ -29,9 +29,18 @@ This library provides a simplified version of parameters that are backed by cont
[none-v [any/c #f]]
[tag continuation-prompt-tag? default-continuation-prompt-tag])
(listof vector?)]{
Returns the values of the @racket[mps] up to @racket[tag]. The length of each vector in the result list is the same as the length of @racket[mps], and a value in a particular vector position is the value for the corresponding mark parameter in @racket[mps]. Values for multiple mark parameter appear in a single vector only when the mark parameters are for the same continuation frame in the current continuation. The @racket[none-v] argument is used for vector elements to indicate the lack of a value.
}
Returns the values of the @racket[mps] up to @racket[tag]. The length
of each vector in the result list is the same as the length of
@racket[mps], and a value in a particular vector position is the value
for the corresponding mark parameter in @racket[mps]. Values for
multiple mark parameter appear in a single vector only when the mark
parameters are for the same continuation frame in the current
continuation. The @racket[none-v] argument is used for vector elements
to indicate the lack of a value.
}
@defform[(mark-parameterize ([mp expr] ...) body-expr ...)]{
Parameterizes @racket[(begin body-expr ...)] by associating each @racket[mp] with the evaluation of @racket[expr] in the parameterization of the entire expression.
}
Parameterizes @racket[(begin body-expr ...)] by associating each
@racket[mp] with the evaluation of @racket[expr] in the
parameterization of the entire expression.
}

View File

@ -40,16 +40,16 @@ The other arguments have the same meaning as for @racket[expr/c].
@examples[#:eval the-eval
(define-syntax (myparameterize1 stx)
(syntax-case stx ()
[(_ ((p v)) body)
[(_ ([p v]) body)
(with-syntax ([cp (wrap-expr/c
#'parameter? #'p
#:name "the parameter argument"
#:context stx)])
#'(parameterize ((cp v)) body))]))
(myparameterize1 ((current-input-port
(open-input-string "(1 2 3)")))
#'(parameterize ([cp v]) body))]))
(myparameterize1 ([current-input-port
(open-input-string "(1 2 3)")])
(read))
(myparameterize1 (('whoops 'something))
(myparameterize1 (['whoops 'something])
'whatever)
(module mod racket

View File

@ -7,18 +7,19 @@
web-server/lang/serial-lambda
web-server/private/define-closure))
The defunctionalization process of the Web Language (see @secref["stateless" #:doc '(lib "web-server/scribblings/web-server.scrbl")])
The defunctionalization process of the Web Language (see
@secref["stateless" #:doc '(lib "web-server/scribblings/web-server.scrbl")])
requires an explicit representation of closures that is serializable.
@defmodule[web-server/lang/serial-lambda]{
@defform[(serial-lambda formals body ...)]{
Returns @racket[(lambda formals body ...)], except it is serializable.
Returns @racket[(lambda formals body ...)], except it is serializable.
}
@defform[(serial-case-lambda [formals body ...] ...)]{
Returns @racket[(case-lambda [formals body ...] ...)], except it is serializable.
Returns @racket[(case-lambda [formals body ...] ...)], except it is
serializable.
}
}

View File

@ -20,9 +20,10 @@
[path->serlvet path->servlet/c])
(values (-> void)
url->servlet/c)]{
The first return value flushes the cache.
The second is a procedure that uses @racket[url->path] to resolve the URL to a path, then uses @racket[path->servlet] to resolve
that path to a servlet, caching the results in an internal table.
The first return value flushes the cache. The second is a procedure
that uses @racket[url->path] to resolve the URL to a path, then uses
@racket[path->servlet] to resolve that path to a servlet, caching the
results in an internal table.
}
@defproc[(make [url->servlet url->servlet/c]
@ -35,9 +36,12 @@
(url? exn? . -> . can-be-response?)
servlet-error-responder])
dispatcher/c]{
This dispatcher runs racket servlets, using @racket[url->servlet] to resolve URLs to the underlying servlets.
If servlets have errors loading, then @racket[responders-servlet-loading] is used. Other errors are handled with
@racket[responders-servlet]. If a servlet raises calls @racket[next-dispatcher], then the signal is propagated by this dispatcher.
This dispatcher runs racket servlets, using @racket[url->servlet] to
resolve URLs to the underlying servlets. If servlets have errors
loading, then @racket[responders-servlet-loading] is used. Other errors
are handled with @racket[responders-servlet]. If a servlet raises calls
@racket[next-dispatcher], then the signal is propagated by this
dispatcher.
}
}
@ -49,17 +53,17 @@
@section{Internal Servlet Representation}
@defmodule[web-server/private/servlet]{
@defstruct[servlet ([custodian custodian?]
[namespace namespace?]
[manager manager?]
[directory path-string?]
[handler (request? . -> . can-be-response?)])
#:mutable]{
Instances of this structure hold the necessary parts of a servlet:
the @racket[custodian] responsible for the servlet's resources,
the @racket[namespace] the servlet is executed within,
the @racket[manager] responsible for the servlet's continuations,
the current @racket[directory] of the servlet,
and the @racket[handler] for all requests to the servlet.
}
@defstruct[servlet ([custodian custodian?]
[namespace namespace?]
[manager manager?]
[directory path-string?]
[handler (request? . -> . can-be-response?)])
#:mutable]{
Instances of this structure hold the necessary parts of a servlet:
the @racket[custodian] responsible for the servlet's resources,
the @racket[namespace] the servlet is executed within,
the @racket[manager] responsible for the servlet's continuations,
the current @racket[directory] of the servlet,
and the @racket[handler] for all requests to the servlet.
}
}

View File

@ -102,10 +102,12 @@ URLs to paths on the filesystem.
@defproc[(filter-url->path [regex regexp?]
[url->path url->path/c])
url->path/c]{
Runs the underlying @racket[url->path] but will only return if the path, when considered as a string,
matches the @racket[regex]. This is useful to disallow strange files, like GIFs, from being considered
servlets when using the servlet dispatchers. It will return a @racket[exn:fail:filesystem:exists?] exception if
the path does not match.
Runs the underlying @racket[url->path] but will only return if the
path, when considered as a string, matches the @racket[regex]. This is
useful to disallow strange files, like GIFs, from being considered
servlets when using the servlet dispatchers. It will return a
@racket[exn:fail:filesystem:exists?] exception if the path does not
match.
}
}
@ -249,9 +251,9 @@ a URL that refreshes the password file, servlet cache, etc.}
web-server/configuration/responders))
@defthing[denied?/c contract?]{
Equivalent to @racket[(request? . -> . (or/c false/c string?))].
The return is the authentication realm as a string if the request is not authorized and
@racket[#f] if the request @emph{is} authorized.
Equivalent to @racket[(request? . -> . (or/c false/c string?))]. The
return is the authentication realm as a string if the request is not
authorized and @racket[#f] if the request @emph{is} authorized.
}
@defproc[(make [denied? denied?/c]
@ -260,24 +262,26 @@ a URL that refreshes the password file, servlet cache, etc.}
(url? header? . -> . response?)
(gen-authentication-responder "forbidden.html")])
dispatcher/c]{
A dispatcher that checks if the request is denied based on @racket[denied?]. If so, then
@racket[authentication-responder] is called with a @racket[header] that
requests credentials. If not, then @racket[next-dispatcher] is
invoked.
A dispatcher that checks if the request is denied based on
@racket[denied?]. If so, then @racket[authentication-responder] is
called with a @racket[header] that requests credentials. If not, then
@racket[next-dispatcher] is invoked.
}
@defthing[authorized?/c contract?]{
Equivalent to @racket[(string? (or/c false/c bytes?) (or/c false/c bytes?) . -> . (or/c false/c string?))].
The input is the URI as a string and the username and passwords as bytes.
The return is the authentication realm as a string if the user is not authorized and
@racket[#f] if the request @emph{is} authorized.
Equivalent to
@racket[(string? (or/c false/c bytes?) (or/c false/c bytes?) . -> . (or/c false/c string?))].
The input is the URI as a string and the username and passwords as
bytes. The return is the authentication realm as a string if the user
is not authorized and @racket[#f] if the request @emph{is} authorized.
}
@defproc[(make-basic-denied?/path [password-file path-string?])
(values (-> void)
authorized?/c)]{
Creates an authorization procedure based on the given password file. The first returned value
is a procedure that refreshes the password cache used by the authorization procedure.
Creates an authorization procedure based on the given password
file. The first returned value is a procedure that refreshes the
password cache used by the authorization procedure.
@racket[password-file] is parsed as:
@racketblock[(list ([domain : string?]

View File

@ -23,9 +23,8 @@ Suppose we want to create an abstraction of entering a date in an HTML form. The
@racketblock[
(define date-formlet
(formlet
(div
"Month:" ,{input-int . => . month}
"Day:" ,{input-int . => . day})
(div "Month:" ,{input-int . => . month}
"Day:" ,{input-int . => . day})
(list month day)))
]
@ -233,36 +232,39 @@ types. Refer to @secref["input-formlets"] for example low-level formlets using t
@defproc[(xml-forest [r xexpr-forest/c])
(formlet/c procedure?)]{
Constructs a @tech{formlet} with the rendering @racket[r] and the identity procedure as the processing step.
Constructs a @tech{formlet} with the rendering @racket[r] and the
identity procedure as the processing step.
}
@defproc[(xml [r xexpr/c])
(formlet/c procedure?)]{
Equivalent to @racket[(xml-forest (list r))].
Equivalent to @racket[(xml-forest (list r))].
}
@defproc[(text [r string?])
(formlet/c procedure?)]{
Equivalent to @racket[(xml r)].
Equivalent to @racket[(xml r)].
}
@defproc[(tag-xexpr [tag symbol?]
[attrs (listof (list/c symbol? string?))]
[inner (formlet/c any/c)])
(formlet/c any/c)]{
Constructs a @tech{formlet} with the rendering @racket[(list (list* tag attrs inner-rendering))] where @racket[inner-rendering] is
the rendering of @racket[inner] and the processing stage identical to @racket[inner].
Constructs a @tech{formlet} with the rendering @racket[(list (list*
tag attrs inner-rendering))] where @racket[inner-rendering] is the
rendering of @racket[inner] and the processing stage identical to
@racket[inner].
}
@defproc[(formlet-display [f (formlet/c any/c)])
xexpr-forest/c]{
Renders @racket[f].
Renders @racket[f].
}
@defproc[(formlet-process [f (formlet/c any/c ...)]
[r request?])
(values any/c ...)]{
Runs the processing stage of @racket[f] on the bindings in @racket[r].
Runs the processing stage of @racket[f] on the bindings in @racket[r].
}
}
@ -276,14 +278,15 @@ These @tech{formlet}s are the main combinators for form input.
@defproc[(make-input [render (string? . -> . xexpr/c)])
(formlet/c (or/c false/c binding?))]{
This @tech{formlet} is rendered with @racket[render], which is passed the input name, and results in the
extracted @racket[binding].
This @tech{formlet} is rendered with @racket[render], which is passed
the input name, and results in the extracted @racket[binding].
}
@defproc[(make-input* [render (string? . -> . xexpr/c)])
(formlet/c (listof binding?))]{
This @tech{formlet} is rendered with @racket[render], which is passed the input name, and results in all the
@racket[binding]s that use the name.
This @tech{formlet} is rendered with @racket[render], which is passed
the input name, and results in all the @racket[binding]s that use the
name.
}
@defproc[(text-input [#:value value (or/c false/c bytes?) #f]
@ -292,7 +295,8 @@ These @tech{formlet}s are the main combinators for form input.
[#:read-only? read-only? boolean? #f]
[#:attributes attrs (listof (list/c symbol? string?)) empty])
(formlet/c (or/c false/c binding?))]{
This @tech{formlet} renders using an INPUT element with the TEXT type and the attributes given in the arguments.
This @tech{formlet} renders using an INPUT element with the TEXT type
and the attributes given in the arguments.
}
@defproc[(password-input [#:value value (or/c false/c bytes?) #f]
@ -301,7 +305,8 @@ These @tech{formlet}s are the main combinators for form input.
[#:read-only? read-only? boolean? #f]
[#:attributes attrs (listof (list/c symbol? string?)) empty])
(formlet/c (or/c false/c binding?))]{
This @tech{formlet} renders using an INPUT element with the PASSWORD type and the attributes given in the arguments.
This @tech{formlet} renders using an INPUT element with the PASSWORD
type and the attributes given in the arguments.
}
@defproc[(textarea-input [#:value value (or/c false/c bytes?) #f]
@ -309,14 +314,16 @@ These @tech{formlet}s are the main combinators for form input.
[#:cols cols (or/c false/c number?) #f]
[#:attributes attrs (listof (list/c symbol? string?)) empty])
(formlet/c (or/c false/c binding?))]{
This @tech{formlet} renders using an TEXTAREA element with attributes given in the arguments.
This @tech{formlet} renders using an TEXTAREA element with attributes
given in the arguments.
}
@defproc[(checkbox [value bytes?]
[checked? boolean?]
[#:attributes attrs (listof (list/c symbol? string?)) empty])
(formlet/c (or/c false/c binding?))]{
This @tech{formlet} renders using an INPUT element with the CHECKBOX type and the attributes given in the arguments.
This @tech{formlet} renders using an INPUT element with the CHECKBOX
type and the attributes given in the arguments.
}
@defproc[(radio [value bytes?]
@ -329,23 +336,27 @@ These @tech{formlet}s are the main combinators for form input.
@defproc[(submit [value bytes?]
[#:attributes attrs (listof (list/c symbol? string?)) empty])
(formlet/c (or/c false/c binding?))]{
This @tech{formlet} renders using an INPUT element with the SUBMIT type and the attributes given in the arguments.
This @tech{formlet} renders using an INPUT element with the SUBMIT
type and the attributes given in the arguments.
}
@defproc[(reset [value bytes?]
[#:attributes attrs (listof (list/c symbol? string?)) empty])
(formlet/c (or/c false/c binding?))]{
This @tech{formlet} renders using an INPUT element with the RESET type and the attributes given in the arguments.
This @tech{formlet} renders using an INPUT element with the RESET type
and the attributes given in the arguments.
}
@defproc[(file-upload [#:attributes attrs (listof (list/c symbol? string?)) empty])
(formlet/c (or/c false/c binding?))]{
This @tech{formlet} renders using an INPUT element with the FILE type and the attributes given in the arguments.
This @tech{formlet} renders using an INPUT element with the FILE type
and the attributes given in the arguments.
}
@defproc[(hidden [value bytes?] [#:attributes attrs (listof (list/c symbol? string?)) empty])
(formlet/c (or/c false/c binding?))]{
This @tech{formlet} renders using an INPUT element with HIDDEN type and the attributes given in the arguments.
This @tech{formlet} renders using an INPUT element with HIDDEN type
and the attributes given in the arguments.
}
@defproc[(img [alt bytes?]
@ -356,7 +367,8 @@ These @tech{formlet}s are the main combinators for form input.
[#:width width (or/c false/c exact-nonnegative-integer?) #f]
[#:attributes attrs (listof (list/c symbol? string?)) empty])
(formlet/c (or/c false/c binding?))]{
This @tech{formlet} renders using an IMG element with the attributes given in the arguments.
This @tech{formlet} renders using an IMG element with the attributes
given in the arguments.
}
@defproc[(button [type bytes?]
@ -365,7 +377,9 @@ These @tech{formlet}s are the main combinators for form input.
[#:value value (or/c false/c bytes?) #f]
[#:attributes attrs (listof (list/c symbol? string?)) empty])
(formlet/c (or/c false/c binding?))]{
This @tech{formlet} renders using a BUTTON element with the attributes given in the arguments. @racket[button-text] is the text that will appear on the button when rendered.
This @tech{formlet} renders using a BUTTON element with the attributes
given in the arguments. @racket[button-text] is the text that will
appear on the button when rendered.
}
@defproc[(multiselect-input [l sequence?]
@ -374,7 +388,11 @@ These @tech{formlet}s are the main combinators for form input.
[#:selected? selected? (any/c . -> . boolean?) (λ (x) #f)]
[#:display display (any/c . -> . xexpr/c) (λ (x) x)])
(formlet/c list?)]{
This @tech{formlet} renders using an SELECT element with the attributes given with an OPTION for each element of the sequence. If @racket[multiple?] is @racket[#t], then multiple options may be selected. An element is selected if @racket[selected?] returns @racket[#t]. Elements are displayed with @racket[display].
This @tech{formlet} renders using an SELECT element with the
attributes given with an OPTION for each element of the sequence. If
@racket[multiple?] is @racket[#t], then multiple options may be
selected. An element is selected if @racket[selected?] returns
@racket[#t]. Elements are displayed with @racket[display].
}
@defproc[(select-input [l sequence?]
@ -382,51 +400,62 @@ These @tech{formlet}s are the main combinators for form input.
[#:selected? selected? (any/c . -> . boolean?) (λ (x) #f)]
[#:display display (any/c . -> . xexpr/c) (λ (x) x)])
(formlet/c any/c)]{
This @tech{formlet} renders using an SELECT element with the attributes given with an OPTION for each element of the sequence. An element is selected if @racket[selected?] returns @racket[#t]. Elements are displayed with @racket[display].
This @tech{formlet} renders using an SELECT element with the
attributes given with an OPTION for each element of the sequence. An
element is selected if @racket[selected?] returns
@racket[#t]. Elements are displayed with @racket[display].
}
@defproc[(required [f (formlet/c (or/c false/c binding?))])
(formlet/c bytes?)]{
Constructs a @tech{formlet} that extracts the @racket[binding:form-value] from the binding produced by @racket[f], or errors.
Constructs a @tech{formlet} that extracts the
@racket[binding:form-value] from the binding produced by @racket[f],
or errors.
}
@defproc[(default
[def bytes?]
[f (formlet/c (or/c false/c binding?))])
(formlet/c bytes?)]{
Constructs a @tech{formlet} that extracts the @racket[binding:form-value] from the binding produced by @racket[f], or returns @racket[def].
Constructs a @tech{formlet} that extracts the
@racket[binding:form-value] from the binding produced by @racket[f],
or returns @racket[def].
}
@defproc[(to-string [f (formlet/c bytes?)])
(formlet/c string?)]{
Converts @racket[f]'s output to a string. Equivalent to @racket[(cross (pure bytes->string/utf-8) f)].
Converts @racket[f]'s output to a string. Equivalent to
@racket[(cross (pure bytes->string/utf-8) f)].
}
@defproc[(to-number [f (formlet/c string?)])
(formlet/c number?)]{
Converts @racket[f]'s output to a number. Equivalent to @racket[(cross (pure string->number) f)].
Converts @racket[f]'s output to a number. Equivalent to @racket[(cross
(pure string->number) f)].
}
@defproc[(to-symbol [f (formlet/c string?)])
(formlet/c symbol?)]{
Converts @racket[f]'s output to a symbol. Equivalent to @racket[(cross (pure string->symbol) f)].
Converts @racket[f]'s output to a symbol. Equivalent to
@racket[(cross (pure string->symbol) f)].
}
@defproc[(to-boolean [f (formlet/c bytes?)])
(formlet/c boolean?)]{
Converts @racket[f]'s output to a boolean, if it is equal to @racket[#"on"].
Converts @racket[f]'s output to a boolean, if it is equal to
@racket[#"on"].
}
@defthing[input-string (formlet/c string?)]{
Equivalent to @racket[(to-string (required (text-input)))].
Equivalent to @racket[(to-string (required (text-input)))].
}
@defthing[input-int (formlet/c integer?)]{
Equivalent to @racket[(to-number input-string)].
Equivalent to @racket[(to-number input-string)].
}
@defthing[input-symbol (formlet/c symbol?)]{
Equivalent to @racket[(to-symbol input-string)].
Equivalent to @racket[(to-symbol input-string)].
}
}
@ -446,16 +475,18 @@ A few utilities are provided for using @tech{formlet}s in Web applications.
`(html (head (title "Form Entry"))
(body ,form-xexpr)))])
(values any/c ...)]{
Uses @racket[send/suspend] and @racket[response/xexpr] to send @racket[f]'s rendering (wrapped in a FORM tag whose action is
the continuation URL (wrapped again by @racket[wrapper])) to the client.
When the form is submitted, the request is passed to the
processing stage of @racket[f].
Uses @racket[send/suspend] and @racket[response/xexpr] to send
@racket[f]'s rendering (wrapped in a FORM tag whose action is the
continuation URL (wrapped again by @racket[wrapper])) to the client.
When the form is submitted, the request is passed to the processing
stage of @racket[f].
}
@defproc[(embed-formlet [embed/url ((request? . -> . any) . -> . string?)]
[f (formlet/c any/c ...)])
xexpr/c]{
Like @racket[send/formlet], but for use with @racket[send/suspend/dispatch].
Like @racket[send/formlet], but for use with
@racket[send/suspend/dispatch].
}
}

View File

@ -278,8 +278,9 @@ transmission that the server @bold{will not catch}.}
[domain (or/c false/c valid-domain?)]
[path (or/c false/c string?)])]{
While server cookies are represented with @racket[cookie?]s, cookies that come from the client are represented
with a @racket[client-cookie] structure.
While server cookies are represented with @racket[cookie?]s, cookies
that come from the client are represented with a
@racket[client-cookie] structure.
}
@defproc[(request-cookies [req request?])
@ -423,15 +424,19 @@ An implementation of HTTP Digest Authentication.
@defproc[(password->digest-HA1 [lookup-password username*realm->password/c])
username*realm->digest-HA1/c]{
Uses @racket[lookup-password] to find the password, then computes the secret hash of it.
Uses @racket[lookup-password] to find the password, then computes the
secret hash of it.
}
@defproc[(make-check-digest-credentials [lookup-HA1 username*realm->digest-HA1/c])
(string? (listof (cons/c symbol? string?)) . -> . boolean?)]{
Constructs a function that checks whether particular Digest credentials (the second argument of the returned function)
are correct given the HTTP method provided as the first argument and the secret hash computed by @racket[lookup-HA1].
Constructs a function that checks whether particular Digest credentials
(the second argument of the returned function) are correct given the
HTTP method provided as the first argument and the secret hash computed
by @racket[lookup-HA1].
This is will result in an exception if the Digest credentials are missing portions.
This is will result in an exception if the Digest credentials are
missing portions.
}
Example:

View File

@ -45,9 +45,9 @@ An example @racket['stateless] servlet module:
(provide interface-version stuffer start)
(define interface-version 'stateless)
(define stuffer
(stuffer-chain
serialize-stuffer
(md5-stuffer (build-path (find-system-path 'home-dir) ".urls"))))
(stuffer-chain
serialize-stuffer
(md5-stuffer (build-path (find-system-path 'home-dir) ".urls"))))
(define (start req)
(response/xexpr
`(html (body (h2 "Look ma, no state!")))))

View File

@ -21,10 +21,11 @@ of @racketmodname[web-server/dispatchers/dispatch-servlets].
@defproc[(make-make-servlet-namespace (#:to-be-copied-module-specs to-be-copied-module-specs (listof module-path?)))
make-servlet-namespace/c]{
This function creates a function that when called will construct a new @racket[namespace] that
has all the modules from @racket[to-be-copied-module-specs] and @racket[additional-specs], as well
as @racket[racket] and @racket[mred], provided they are already attached
to the @racket[(current-namespace)] of the call-site.
This function creates a function that when called will construct a new
@racket[namespace] that has all the modules from
@racket[to-be-copied-module-specs] and @racket[additional-specs], as
well as @racket[racket] and @racket[mred], provided they are already
attached to the @racket[(current-namespace)] of the call-site.
Example:
@racketblock[
@ -37,14 +38,17 @@ Example:
@section{Why this is useful}
A different namespace is needed for each servlet, so that if servlet A and servlet B both use
a stateful module C, they will be isolated from one another. We see the @web-server as
an operating system for servlets, so we inherit the isolation requirement on operating systems.
A different namespace is needed for each servlet, so that if servlet A
and servlet B both use a stateful module C, they will be isolated from
one another. We see the @web-server as an operating system for servlets,
so we inherit the isolation requirement on operating systems.
However, there are some modules which must be shared. If they were not, then structures cannot
be passed from the @web-server to the servlets, because Racket's structures are generative.
However, there are some modules which must be shared. If they were not,
then structures cannot be passed from the @web-server to the servlets,
because Racket's structures are generative.
Since, on occasion, a user will actually wanted servlets A and B to interact through module C.
A custom @racket[make-servlet-namespace] can be created, through this procedure, that attaches
module C to all servlet namespaces. Through other means (see @secref["dispatchers"]) different sets
of servlets can share different sets of modules.
Since, on occasion, a user will actually wanted servlets A and B to
interact through module C. A custom @racket[make-servlet-namespace] can
be created, through this procedure, that attaches module C to all
servlet namespaces. Through other means (see @secref["dispatchers"])
different sets of servlets can share different sets of modules.

View File

@ -9,12 +9,17 @@
@defmodule[web-server/lang/native]{
It is sometimes inconvenient to use @racket[serial->native] and @racket[native->serial] throughout your program.
This module provides a macro for creating wrappers.
It is sometimes inconvenient to use @racket[serial->native] and
@racket[native->serial] throughout your program. This module provides a
macro for creating wrappers.
@defform[#:literals (ho) (define-native (native arg-spec ...) original) #:contracts ([arg-spec ho] [arg-spec _])]{
Builds an interface around @racket[original] named @racket[native] such that calls to @racket[native] are wrapped in @racket[serial->native]
and all arguments marked with @racket[ho] in @racket[arg-spec] are assumed to procedures and are wrapped in @racket[native->serial].
@defform[#:literals (ho)
(define-native (native arg-spec ...) original)
#:contracts ([arg-spec ho] [arg-spec _])]{
Builds an interface around @racket[original] named @racket[native] such
that calls to @racket[native] are wrapped in @racket[serial->native]
and all arguments marked with @racket[ho] in @racket[arg-spec] are
assumed to procedures and are wrapped in @racket[native->serial].
For example,
@racketblock[

View File

@ -39,33 +39,59 @@ A simple example:
"You clicked!"))])
"Click me")))))]
Similarly, many Web applications make use almost exclusively of functions that are arguments to @racket[embed/url] and immediately invoke @racket[send/suspend/dispatch].
Similarly, many Web applications make use almost exclusively of
functions that are arguments to @racket[embed/url] and immediately
invoke @racket[send/suspend/dispatch].
@deftogether[[@defform[(lambda/page formals e ...)]
@defform[(define/page (id . formals) e ...)]]]{
The @racket[lambda/page] and @racket[define/page] automate this by expanding to functions that accept a request as the first argument (followed by any arguments specified in @racket[formals]) and immediately wrap their body in @racket[page]. This functions also cooperate with @racket[get-binding] by binding the request to the @racket[current-request] parameter.
The @racket[lambda/page] and @racket[define/page] automate this by
expanding to functions that accept a request as the first argument
(followed by any arguments specified in @racket[formals]) and
immediately wrap their body in @racket[page]. This functions also
cooperate with @racket[get-binding] by binding the request to the
@racket[current-request] parameter.
}
The binding interface of @racketmodname[web-server/http] is powerful, but subtle to use conveniently due to its protection against hostile clients.
The binding interface of @racketmodname[web-server/http] is powerful,
but subtle to use conveniently due to its protection against hostile
clients.
@deftogether[[
@defparam[current-request req request?]
@defthing[binding-id/c contract?]
@defthing[binding-format/c contract?]
@defproc[(get-binding [id binding-id/c] [req request? (current-request)] [#:format format binding-format/c 'string])
@defproc[(get-binding [id binding-id/c]
[req request? (current-request)]
[#:format format binding-format/c 'string])
(or/c false/c string? bytes? binding?)]
@defproc[(get-bindings [id binding-id/c] [req request? (current-request)] [#:format format binding-format/c 'string])
@defproc[(get-bindings [id binding-id/c]
[req request? (current-request)]
[#:format format binding-format/c 'string])
(listof (or/c string? bytes? binding?))]
]]{
The @racket[get-binding](s) interface attempts to resolve this by providing a powerful interface with convenient defaults.
The @racket[get-binding](s) interface attempts to resolve this by
providing a powerful interface with convenient defaults.
@racket[get-binding] extracts the first binding of a form input from a request, while @racket[get-bindings] extracts them all.
@racket[get-binding] extracts the first binding of a form input from a
request, while @racket[get-bindings] extracts them all.
They accept a form identifier (@racket[id]) as either a byte string, a string, or a symbol. In each case, the user input is compared in a case-sensitive way with the form input.
They accept a form identifier (@racket[id]) as either a byte string, a
string, or a symbol. In each case, the user input is compared in a
case-sensitive way with the form input.
They accept an optional request argument (@racket[req]) that defaults to the value of the @racket[current-request] parameter used by @racket[lambda/page] and @racket[define/page].
They accept an optional request argument (@racket[req]) that defaults
to the value of the @racket[current-request] parameter used by
@racket[lambda/page] and @racket[define/page].
Finally, they accept an optional keyword argument (@racket[format]) that specifies the desired return format. The default, @racket['string], produces a UTF-8 string (or @racket[#f] if the byte string cannot be converted to UTF-8.) The @racket['bytes] format always produces the raw byte string. The @racket['file] format produces the file upload content (or @racket[#f] if the form input was not an uploaded file.) The @racket['binding] format produces the binding object.
Finally, they accept an optional keyword argument (@racket[format])
that specifies the desired return format. The default,
@racket['string], produces a UTF-8 string (or @racket[#f] if the byte
string cannot be converted to UTF-8.) The @racket['bytes] format
always produces the raw byte string. The @racket['file] format
produces the file upload content (or @racket[#f] if the form input was
not an uploaded file.) The @racket['binding] format produces the
binding object.
}

View File

@ -8,70 +8,88 @@
@defmodule[web-server/configuration/responders]{
This module provides some functions that help constructing HTTP responders.
These functions are used by the default dispatcher constructor (see @secref["web-server-unit"]) to
turn the paths given in the @racket[configuration-table] into responders for the associated circumstance.
This module provides some functions that help constructing HTTP
responders. These functions are used by the default dispatcher
constructor (see @secref["web-server-unit"]) to turn the paths given in
the @racket[configuration-table] into responders for the associated
circumstance.
@defproc[(file-response (http-code natural-number/c) (short-version string?) (text-file string?) (header header?) ...)
@defproc[(file-response [http-code natural-number/c]
[short-version string?]
[text-file string?]
[header header?] ...)
response?]{
Generates a @racket[response?] with the given @racket[http-code] and @racket[short-version]
as the corresponding fields; with the content of the @racket[text-file] as the body; and, with
the @racket[header]s as, you guessed it, headers.
Generates a @racket[response?] with the given @racket[http-code] and
@racket[short-version] as the corresponding fields; with the content of
the @racket[text-file] as the body; and, with the @racket[header]s as,
you guessed it, headers.
This does not cause redirects to a well-known URL, such as @filepath{conf/not-found.html}, but rather use the contents
of @filepath{not-found.html} (for example) as its contents. Therefore, any relative URLs in @racket[text-file] are relative
to whatever URL @racket[file-response] is used to respond @emph{to}. Thus, you should probably use absolute URLs in these files.
This does not cause redirects to a well-known URL, such as
@filepath{conf/not-found.html}, but rather use the contents of
@filepath{not-found.html} (for example) as its contents. Therefore, any
relative URLs in @racket[text-file] are relative to whatever URL
@racket[file-response] is used to respond @emph{to}. Thus, you should
probably use absolute URLs in these files.
}
@defproc[(servlet-loading-responder (url url?) (exn exn?))
@defproc[(servlet-loading-responder [url url?] [exn exn?])
response?]{
Gives @racket[exn] to the @racket[current-error-handler] and response with a stack trace and a "Servlet didn't load" message.
Gives @racket[exn] to the @racket[current-error-handler] and response
with a stack trace and a "Servlet didn't load" message.
}
@defproc[(gen-servlet-not-found (file path-string?))
@defproc[(gen-servlet-not-found [file path-string?])
((url url?) . -> . response?)]{
Returns a function that generates a standard "Servlet not found." error with content from @racket[file].
Returns a function that generates a standard "Servlet not found." error
with content from @racket[file].
}
@defproc[(servlet-error-responder (url url?) (exn exn?))
@defproc[(servlet-error-responder [url url?] [exn exn?])
response?]{
Gives @racket[exn] to the @racket[current-error-handler] and response with a stack trace and a "Servlet error" message.
Gives @racket[exn] to the @racket[current-error-handler] and response
with a stack trace and a "Servlet error" message.
}
@defproc[(gen-servlet-responder (file path-string?))
@defproc[(gen-servlet-responder [file path-string?])
((url url?) (exn any/c) . -> . response?)]{
Prints the @racket[exn] to standard output and responds with a "Servlet error." message with content from @racket[file].
Prints the @racket[exn] to standard output and responds with a "Servlet
error." message with content from @racket[file].
}
@defproc[(gen-servlets-refreshed (file path-string?))
@defproc[(gen-servlets-refreshed [file path-string?])
(-> response?)]{
Returns a function that generates a standard "Servlet cache refreshed." message with content from @racket[file].
Returns a function that generates a standard "Servlet cache refreshed."
message with content from @racket[file].
}
@defproc[(gen-passwords-refreshed (file path-string?))
@defproc[(gen-passwords-refreshed [file path-string?])
(-> response?)]{
Returns a function that generates a standard "Passwords refreshed." message with content from @racket[file].
Returns a function that generates a standard "Passwords refreshed."
message with content from @racket[file].
}
@defproc[(gen-authentication-responder (file path-string?))
@defproc[(gen-authentication-responder [file path-string?])
((url url?) (header header?) . -> . response?)]{
Returns a function that generates an authentication failure error with content from @racket[file] and
@racket[header] as the HTTP header.
Returns a function that generates an authentication failure error with
content from @racket[file] and @racket[header] as the HTTP header.
}
@defproc[(gen-protocol-responder (file path-string?))
@defproc[(gen-protocol-responder [file path-string?])
((url url?) . -> . response?)]{
Returns a function that generates a "Malformed request" error with content from @racket[file].
Returns a function that generates a "Malformed request" error with
content from @racket[file].
}
@defproc[(gen-file-not-found-responder (file path-string?))
@defproc[(gen-file-not-found-responder [file path-string?])
((req request?) . -> . response?)]{
Returns a function that generates a standard "File not found" error with content from @racket[file].
Returns a function that generates a standard "File not found" error
with content from @racket[file].
}
@defproc[(gen-collect-garbage-responder (file path-string?))
@defproc[(gen-collect-garbage-responder [file path-string?])
(-> response?)]{
Returns a function that generates a standard "Garbage collection run" message with content from @racket[file].
Returns a function that generates a standard "Garbage collection run"
message with content from @racket[file].
}
}

View File

@ -23,7 +23,10 @@ and increasing the size of the serialization. This module provides support for t
@defproc[(soft-state-ref [ss soft-state?])
any/c]{
Extracts the value associated with @racket[ss]. If the value is not available (perhaps because of garbage collection, deserialization in an uninitialized process, etc), then the thunk associated with @racket[ss] is invoked and the value is cached.
Extracts the value associated with @racket[ss]. If the value is not
available (perhaps because of garbage collection, deserialization in an
uninitialized process, etc), then the thunk associated with @racket[ss]
is invoked and the value is cached.
}
@defform[(soft-state expr ...)]{

View File

@ -6,10 +6,11 @@
@title[#:tag "considerations"]{Usage Considerations}
A stateless servlet has the following process performed on it automatically:
A stateless servlet has the following process performed on it
automatically:
@itemize[
@item{All uses of @racket[letrec] are removed and replaced with equivalent uses of
@racket[let] and imperative features.}
@item{All uses of @racket[letrec] are removed and replaced with
equivalent uses of @racket[let] and imperative features.}
@item{The program is converted into @link["http://en.wikipedia.org/wiki/Administrative_normal_form"]{ANF} (Administrative Normal Form),
making all continuations explicit.}
@item{All continuations and continuations marks are recorded in the
@ -22,41 +23,47 @@ A stateless servlet has the following process performed on it automatically:
@racket[lambda].}
]
This process allows the continuations captured by your servlet to be serialized.
This means they may be stored on the client's browser or the server's disk.
This process allows the continuations captured by your servlet to be
serialized. This means they may be stored on the client's browser or
the server's disk.
This means your servlet has no cost to the server other than execution. This is
very attractive if you've used Racket servlets and had memory problems.
This means your servlet has no cost to the server other than
execution. This is very attractive if you've used Racket servlets and
had memory problems.
This means your server can restart in the middle of a long running Web interaction
without the URLs that have been shared with the client expiring. This is
very attractive if you've used Racket servlets and had session timeout problems.
This means your server can restart in the middle of a long running Web
interaction without the URLs that have been shared with the client
expiring. This is very attractive if you've used Racket servlets and
had session timeout problems.
This process is defined on all of Racket and occurs after macro-expansion,
so you are free to use all interesting features of Racket. However, there
are some considerations you must make.
This process is defined on all of Racket and occurs after
macro-expansion, so you are free to use all interesting features of
Racket. However, there are some considerations you must make.
First, this process drastically changes the structure of your program. It
will create an immense number of lambdas and structures your program
did not normally contain. The performance implication of this has not been
studied with Racket.
First, this process drastically changes the structure of your program.
It will create an immense number of lambdas and structures your program
did not normally contain. The performance implication of this has not
been studied with Racket.
Second, the defunctionalization process is sensitive to the syntactic structure
of your program. Therefore, if you change your program in a trivial way, for example,
changing a constant, then all serialized continuations will be obsolete and will
error when deserialization is attempted. This is a feature, not a bug! It is a small
price to pay for protection from the sorts of errors that would occur if your program
Second, the defunctionalization process is sensitive to the syntactic
structure of your program. Therefore, if you change your program in a
trivial way, for example, changing a constant, then all serialized
continuations will be obsolete and will error when deserialization is
attempted. This is a feature, not a bug! It is a small price to pay for
protection from the sorts of errors that would occur if your program
were changed in a meaningful way.
Third, the values in the lexical scope of your continuations must be serializable
for the continuations itself to be serializable. This means that you must use
@racket[define-serializable-struct] rather than @racket[define-struct], and take
care to use modules that do the same. Similarly, you may not use @racket[parameterize],
because parameterizations are not serializable.
Third, the values in the lexical scope of your continuations must be
serializable for the continuations itself to be serializable. This means
that you must use @racket[define-serializable-struct] rather than
@racket[define-struct], and take care to use modules that do the same.
Similarly, you may not use @racket[parameterize], because
parameterizations are not serializable.
Fourth, and related, this process only runs on your code, not on the code you
@racket[require]. Thus, your continuations---to be serializable---must not
be in the context of another module. For example, the following will fail with an @as-index{"unsafe context"}
Fourth, and related, this process only runs on your code, not on the
code you @racket[require]. Thus, your continuations---to be
serializable---must not be in the context of another module. For
example, the following will fail with an @as-index{"unsafe context"}
exception:
@racketblock[

View File

@ -52,8 +52,9 @@ You can supply your own (built with these functions) when you write a stateless
@defproc[(stuffer-compose [g (stuffer/c any/c any/c)]
[f (stuffer/c any/c any/c)])
(stuffer/c any/c any/c)]{
Composes @racket[f] and @racket[g], i.e., applies @racket[f] then @racket[g] for @racket[in]
and @racket[g] then @racket[f] for @racket[out].
Composes @racket[f] and @racket[g], i.e., applies @racket[f] then
@racket[g] for @racket[in] and @racket[g] then @racket[f] for
@racket[out].
}
@defproc[(stuffer-sequence [f (stuffer/c any/c any/c)]
@ -65,9 +66,10 @@ You can supply your own (built with these functions) when you write a stateless
@defproc[(stuffer-if [c (bytes? . -> . boolean?)]
[f (stuffer/c bytes? bytes?)])
(stuffer/c bytes? bytes?)]{
Creates a @tech{stuffer} that stuffs with @racket[f] if @racket[c] is true on the input
to @racket[in]. Similarly, applies @racket[f] during @racket[out] if it was applied during
@racket[in] (which is recorded by prepending a byte.)
Creates a @tech{stuffer} that stuffs with @racket[f] if @racket[c] is
true on the input to @racket[in]. Similarly, applies @racket[f] during
@racket[out] if it was applied during @racket[in] (which is recorded by
prepending a byte.)
}
@defproc[(stuffer-chain [x (or/c stuffer? (bytes? . -> . boolean?))]
@ -85,7 +87,8 @@ You can supply your own (built with these functions) when you write a stateless
@defmodule[web-server/stuffers/serialize]{
@defthing[serialize-stuffer (stuffer/c serializable? bytes?)]{
A @tech{stuffer} that uses @racket[serialize] and @racket[write/bytes] and @racket[deserialize] and @racket[read/bytes].
A @tech{stuffer} that uses @racket[serialize] and @racket[write/bytes]
and @racket[deserialize] and @racket[read/bytes].
}
}
@ -111,14 +114,16 @@ You can supply your own (built with these functions) when you write a stateless
@defthing[gzip-stuffer (stuffer/c bytes? bytes?)]{
A @tech{stuffer} that uses @racket[gzip/bytes] and @racket[gunzip/bytes].
@warning{You should compose this with @racket[base64-stuffer] to get URL-safe bytes.}
@warning{You should compose this with @racket[base64-stuffer] to get
URL-safe bytes.}
}
}
@section{Key/Value Storage}
The @racketmodname[web-server/stuffers/hash] @tech{stuffers} rely on a key/value store.
The @racketmodname[web-server/stuffers/hash] @tech{stuffers} rely on a
key/value store.
@defmodule[web-server/stuffers/store]{
@ -155,8 +160,10 @@ The @racketmodname[web-server/stuffers/hash] @tech{stuffers} rely on a key/value
@defproc[(hash-stuffer [H hash-fun/c]
[store store?])
(stuffer/c bytes? bytes?)]{
A content-addressed storage @tech{stuffer} that stores input bytes, @racket[input], in @racket[store] with the key @racket[(H input)]
and returns the key. Similarly, on @racket[out] the original bytes are looked up.
A content-addressed storage @tech{stuffer} that stores input bytes,
@racket[input], in @racket[store] with the key @racket[(H input)] and
returns the key. Similarly, on @racket[out] the original bytes are
looked up.
}
@defproc[(md5-stuffer [root path-string?])
@ -172,24 +179,32 @@ The @racketmodname[web-server/stuffers/hash] @tech{stuffers} rely on a key/value
@defproc[(HMAC-SHA1 [kb bytes?] [db bytes?])
bytes?]{
Performs a HMAC-SHA1 calculation on @racket[db] using @racket[kb] as the key. The result is guaranteed to be 20 bytes.
(You could curry this to use it with @racket[hash-stuffer], but there is little value in doing so over @racket[md5].)
Performs a HMAC-SHA1 calculation on @racket[db] using @racket[kb] as
the key. The result is guaranteed to be 20 bytes. (You could curry
this to use it with @racket[hash-stuffer], but there is little value
in doing so over @racket[md5].)
}
@defproc[(HMAC-SHA1-stuffer [kb bytes?])
(stuffer/c bytes? bytes?)]{
A @tech{stuffer} that signs input using @racket[HMAC-SHA1] with @racket[kb] as the key. The result of the @tech{stuffer} is
the hash prepended to the input data. When the @tech{stuffer} is run in reverse, it checks if the first 20 bytes are the correct
has for the rest of the data.
A @tech{stuffer} that signs input using @racket[HMAC-SHA1] with
@racket[kb] as the key. The result of the @tech{stuffer} is the hash
prepended to the input data. When the @tech{stuffer} is run in
reverse, it checks if the first 20 bytes are the correct has for the
rest of the data.
@warning{You should compose this with @racket[base64-stuffer] to get URL-safe bytes.}
@warning{You should compose this with @racket[base64-stuffer] to get
URL-safe bytes.}
@warning{Without explicit provision, it is possible for users to modify the continuations they are sent through the other @tech{stuffers}.
This @tech{stuffer} allows the servlet to certify that stuffed data was truly generated by the servlet. Therefore, you @bold{should} use this
if you are not using the @racket[hash-stuffer]s.}
@warning{Without explicit provision, it is possible for users to
modify the continuations they are sent through the other
@tech{stuffers}. This @tech{stuffer} allows the servlet to certify
that stuffed data was truly generated by the servlet. Therefore, you
@bold{should} use this if you are not using the
@racket[hash-stuffer]s.}
@warning{This @tech{stuffer} does @bold{not} encrypt the data in anyway, so users can still observe the stuffed values.}
@warning{This @tech{stuffer} does @bold{not} encrypt the data in
anyway, so users can still observe the stuffed values.}
}
}
@ -200,14 +215,17 @@ The @racketmodname[web-server/stuffers/hash] @tech{stuffers} rely on a key/value
@defproc[(is-url-too-big? [v bytes?])
boolean?]{
Determines if stuffing @racket[v] into the current servlet's URL would result in a URL that is too big for Internet Explorer.
(@link["http://www.boutell.com/newfaq/misc/urllength.html"]{IE only supports URLs up to 2048 characters.})
Determines if stuffing @racket[v] into the current servlet's URL would
result in a URL that is too big for Internet Explorer.
(@link["http://www.boutell.com/newfaq/misc/urllength.html"]{IE only
supports URLs up to 2048 characters.})
}
@defproc[(make-default-stuffer [root path-string?])
(stuffer/c serializable? bytes?)]{
Constructs a @tech{stuffer} that serializes, then if the URL is too big, compresses (and base64-encodes), if the URL is still too big
then it stores it in an MD5-indexed database rooted at @racket[root].
Constructs a @tech{stuffer} that serializes, then if the URL is too
big, compresses (and base64-encodes), if the URL is still too big then
it stores it in an MD5-indexed database rooted at @racket[root].
Equivalent to:
@racketblock[

View File

@ -293,7 +293,7 @@ the template to be unescaped, then create a @racket[cdata] structure:
Expands into
@racketblock[
(for/list ([x xs])
(begin/text e ...))
(begin/text e ...))
]
Template Example:

View File

@ -36,7 +36,10 @@ This function accepts a servlet function and provides a function that accepts a
]
}
This facility is designed to be used in concert with a technique of extracting continuation URLs and relevant values; @racketmodname[xml/path] is one way to do this. Here is an extended example that tests an Add-Two-Numbers.com:
This facility is designed to be used in concert with a technique of
extracting continuation URLs and relevant values;
@racketmodname[xml/path] is one way to do this. Here is an extended
example that tests an Add-Two-Numbers.com:
@(require (for-label xml/path
rackunit
racket/list

View File

@ -95,17 +95,22 @@ represented as an X-expression in Racket, by using
@racketblock[
(define xexpr/c
(flat-rec-contract
xexpr
(or/c string?
(or/c (cons/c symbol? (listof xexpr))
(cons/c symbol?
(cons/c (listof (list/c symbol? string?))
(listof xexpr)))))))]
(flat-rec-contract
xexpr
(or/c string?
(or/c (cons/c symbol? (listof xexpr))
(cons/c symbol?
(cons/c (listof (list/c symbol? string?))
(listof xexpr)))))))]
For example:
The HTML @tt{hello} is represented as @racket["hello"]. Strings are automatically escaped when output. This guarantees valid HTML. Therefore, the value @racket["<b>Unfinished tag"] is rendered as @tt{&lt;b&gt;Unfinished tag} not @tt{<b>Unfinished tag}. Similarly, @racket["<i>Finished tag</i>"] is rendered as @tt{&lt;i&gt;Finished tag&lt;/i&gt;} not @tt{<i>Finished tag</i>}.
The HTML @tt{hello} is represented as @racket["hello"]. Strings are
automatically escaped when output. This guarantees valid HTML.
Therefore, the value @racket["<b>Unfinished tag"] is rendered as
@tt{&lt;b&gt;Unfinished tag} not @tt{<b>Unfinished tag}. Similarly,
@racket["<i>Finished tag</i>"] is rendered as
@tt{&lt;i&gt;Finished tag&lt;/i&gt;} not @tt{<i>Finished tag</i>}.
@tt{<p>This is an example</p>} is

View File

@ -51,19 +51,19 @@ transformations of the program into continuation or store passing style.
web-server/insta
(define (start initial-request)
(define counter1 (make-counter))
(define counter2 (make-counter))
(define include1 (include-counter counter1))
(define include2 (include-counter counter2))
(send/suspend/dispatch
(lambda (embed/url)
(response/xexpr
`(html
(body (h2 "Double Counters")
(div (h3 "First")
,(include1 embed/url))
(div (h3 "Second")
,(include2 embed/url))))))))
(define counter1 (make-counter))
(define counter2 (make-counter))
(define include1 (include-counter counter1))
(define include2 (include-counter counter2))
(send/suspend/dispatch
(lambda (embed/url)
(response/xexpr
`(html
(body (h2 "Double Counters")
(div (h3 "First")
,(include1 embed/url))
(div (h3 "Second")
,(include2 embed/url))))))))
(define (make-counter)
(make-web-cell 0))

View File

@ -212,6 +212,7 @@ functions of interest for the servlet developer.
returns the instance id, continuation id, and nonce.
}
@defthing[servlet-prompt continuation-prompt-tag?]{The tag used for Web interaction continuation capture.}
@defthing[servlet-prompt continuation-prompt-tag?]{
The tag used for Web interaction continuation capture.}
}

View File

@ -47,7 +47,8 @@ Represents a location in an input stream.}
@defstruct[source ([start location/c]
[stop location/c])]{
Represents a source location. Other structure types extend @racket[source].
Represents a source location. Other structure types extend
@racket[source].
When XML is generated from an input stream by @racket[read-xml],
locations are represented by @racket[location] instances. When XML
@ -174,7 +175,8 @@ and a @racket[_misc] is an instance of the @racket[comment] or
@racket[p-i] structure types.}
@defthing[xexpr/c contract?]{
A contract that is like @racket[xexpr?] except produces a better error message when the value is not an @tech{X-expression}.
A contract that is like @racket[xexpr?] except produces a better error
message when the value is not an @tech{X-expression}.
}
@; ----------------------------------------------------------------------