racket/collects/web-server/scribblings/web-cells.scrbl
Eli Barzilay a70bf64fd9 Newlines at EOFs
svn: r15380
2009-07-04 02:28:31 +00:00

87 lines
2.9 KiB
Racket

#lang scribble/doc
@(require "web-server.ss")
@title[#:tag "web-cells.ss"]{Web Cells}
@(require (for-label web-server/servlet/web-cells
web-server/servlet/web))
@defmodule[web-server/servlet/web-cells]{The
@schememodname[web-server/servlet/web-cells] library provides the
interface to Web cells.
A Web cell is a kind of state defined relative to the @defterm{frame tree}.
The frame-tree is a mirror of the user's browsing session. Every time a
continuation is invoked, a new frame (called the @defterm{current frame}) is
created as a child of the current frame when the continuation was captured.
You should use Web cells if you want an effect to be encapsulated in all
interactions linked from (in a transitive sense) the HTTP response being
generated. For more information on their semantics, consult the paper
@href-link["http://www.cs.brown.edu/~sk/Publications/Papers/Published/mk-int-safe-state-web/"
"\"Interaction-Safe State for the Web\""].
@defproc[(web-cell? [v any/c])
boolean?]{
Determines if @scheme[v] is a web-cell.
}
@defproc[(make-web-cell [v any/c])
web-cell?]{
Creates a web-cell with a default value of @scheme[v].
}
@defproc[(web-cell-ref [wc web-cell?])
any/c]{
Looks up the value of @scheme[wc] found in the nearest
frame.
}
@defproc[(web-cell-shadow [wc web-cell?]
[v any/c])
void]{
Binds @scheme[wc] to @scheme[v] in the current frame, shadowing any
other bindings to @scheme[wc] in the current frame.
}
Below is an extended example that demonstrates how Web cells allow
the creation of reusable Web abstractions without requiring global
transformations of the program into continuation or store passing style.
@schememod[
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)
`(html
(body (h2 "Double Counters")
(div (h3 "First")
,(include1 embed/url))
(div (h3 "Second")
,(include2 embed/url)))))))
(define (make-counter)
(make-web-cell 0))
(define (include-counter a-counter)
(let/cc k
(let loop ()
(k
(lambda (embed/url)
`(div (h3 ,(number->string (web-cell-ref a-counter)))
(a ([href
,(embed/url
(lambda _
@code:comment{A new frame has been created}
(define last (web-cell-ref a-counter))
@code:comment{We can inspect the value at the parent}
(web-cell-shadow a-counter (add1 last))
@code:comment{The new frame has been modified}
(loop)))])
"+")))))))
]
}