<Dynamic Documents>

[ Introduction | Document Values | Static safety | Syntax | Semantics | Flow Join Requirements | HTML Prototypes | Code Gaps ]


Introduction

In addition to the usual general-purpose programming-language types, (bool, int, float, and so forth), <bigwig> is equiped with a more domain specific type, namely that of html. The type html, ranges over HTML documents that may contain named gaps that act as placeholders for either HTML fragments or attributes in elements. HTML documents are first-class values that may be computed and stored in variables. The documents are represented in a very compressed format, with maximum sharing and where the plug operations takes constant time only. A flow-sensitive type checker ensures that documents are used in a consistent manner. Another flow-sensitive program analysis can statically check that all generated documents are valid (i.e. conform to the HTML 4.01 specification). The validation is turned on by the "-V" ("--validate") compiler option. Finally, the "--js-expand" compiler option will transform all dynamic documents shown and exited into javascript recipes for client-side reconstruction. This permits common parts to be cached across interactions, yielding a considerable reduction in the size of the files transmitted across the wire.


Document Values

An html document value is comprised of three distinct constituents, gaps, fields, and text:

The default value for variables of type html is the empty html document <html></html>, containing no gaps, no fields, and no text.


Static safety

Using a specialized data-flow analysis, we check programs and provide static safety. Once a program has been checked and found to be well-typed, we can provide static safety, that is, we can statically guarantee that:

Static safety is provided by introducing a somewhat complicated notion of document type. However, these types are not explicitly written by the programmer, but are inferred by the compiler using a global flow analysis. A document type has two distinct components: a gap map and a field map. The gap map describes which gaps are present in a document along with their kinds (html, string) and, similarly, the field map describes its input fields and their kinds (text, radio, checkbox, etc...).

Our interprocedural monovariant first-order forward flow analysis associates sound gap and field information for each document variable to each program point. Based on this information we can then determine if a program is type correct. If it is we can provide static safety, that is, we can statically guarantee that the four properties listed above will in fact hold.


Syntax for html related constructs

exp ::= <html> htmlbody_list </html> constant
| id variable
| exp = exp assignment
| exp <[ plug ] plug
| exp =<[ plug ] plug, then assign
| id ( { exp } ) function call
| track ( exp ) track
stm ::= flash exp ; flash
| show exp ; show
| show exp receive [ getinput ] ; show-receive
| show exp timeout stm show/timeout
| show exp receive [ getinput ] timeout stm show/timeout
| exit exp ; exit
plug ::= id = exp normal plug
| id plug shorthand
| exp tuple plug
getinput ::= exp = id normal g.i.
| id g.i. shorthand
| exp tuple g.i.

Legend:
{ X }: Zero-or-more comma-seperated occurences of X.
{ X }: One-or-more comma-seperated occurences of X.


Semantics for html related constructs

Constant
exp ::= <html> htmlbody_list </html>

html constants are standard html documents augmented with named gaps and a few extra <bigwig> specific input fields (see Document Values above).

Requirements: An html constant must meet the gap requirements and field requirements mentioned above.

Variable
exp ::= id

All variables in <bigwig> must be explicitly declared, html variables are no exception. As usual, they can be either local to the session or shared.

Requirements: Shared html variables are required to have the same flowtype throughout their existence. This flowtype is dictated by the flowtype of the initialization expression.

Assignment
exp ::= exp = exp

The leftmost expression is evaluated first to an html l-value. Hereafter, the rightmost expression is evaluated to an html (r-) value which is assigned by-value to the location designated by the first.

Requirements: Both expressions must be of type html. Furthermore, the first must designate an l-value.

Plug
exp ::= exp <[ { id = exp } ]

The first expression is evaluated to a document value that is required to have a gap by the name of the identifier. After this, the second is evaluated to a document value. Then the second document is plugged (inserted) into a copy of the first where the gap was, filling the gap. Due to efficient runtime representation of document values, the operation takes constant time only! Note that "<[" is one token.

There are actually two kinds of plug operations depending on whether the second expression is an html document or a string:

x1 <[y = x2] document plug (html plug)
x1 <[y = s] attribute plug (string plug)


Plug: "x1 <[y = x2]"

Shorthands:

Requirements:

Function Call
id ( { exp } )

Functions may take html documents as parameters (which are treated as call-by-value) and return html documents. However, since we use a monovariant interprocedural dataflow analysis to infer document flow types, there are certain demands on the functions. All free html variables in a function and all actual parameters must have the same flow types at all calling points for the function. Also, the flow type of the returned document must be the same for all calling points.

Track
track ( exp )

This built-in function is purely included to aid debugging. It acts as the identity function on html documents, but with one important compile-time side-effect. At compile-time, all track expressions will report the flow type of their argument as inferred by the flow analyzer.

Flash
stm ::= flash exp ;

The expression, that must be of type html, is evaluated yielding a document value, whose remaining gaps are implicitly closed (filled with nothing). The effect of executing the flash statement is that whenever no response is given within some time bound (eight seconds by default), this document appears in the client's browser. It can be used to give a reason explaining the delay (e.g. "Searching database - this might take a while..."). By default, a document stating "Reply not ready yet - please wait..." is flashed. This may be overwritten by any other flash statement. Flashed documents automatically reload themselves every 5 seconds (per default). The automatic reload delay may be controlled through the refresh modifier.

Requirements: The expression is of type html and the flashed document must not contain any input fields.

Show
stm ::= show exp ;

The expression, that must be of type html, is evaluated yielding a document value, whose remaining gaps are implicitly closed (filled with nothing). If no continue fields were present, a default continue button labeled "Continue" (or a submit button if the service is compiled with "--nojavascript") will be added to the document (lefthand bottom corner). The document is subsequently shown to the client after which the session goes to sleep. When the client clicks one of the continue fields, the session resumes from whence it paused (with the local state preserved).

Note: If the client decides to abandon the session (i.e. not submit a shown page), the session thread will timeout and terminate when a certain time has passed (48 hrs by default). This amount of time (in seconds) can be defined either globally in the <bigwig> configuration file (SPANDEFAULT [48hrs by default]) or per service, per session, or even per show statement using the span modifier. The span modifier takes an expression in parentheses and can be placed after the show keyword in show statements.

Requirements: The expression is of type html and the shown document must not contain any value-submitting input fields.

Show-Receive
stm ::= show exp receive [ { exp = id } ] ;

The semantics is as for show. When the document is submitted, the input fields listed in the receive are assigned to the mentioned variables. After this, execution resumes (with the local state preserved).

Shorthands:

Requirements: The expression must be of type html and the number of received program variables must equal the number of document input fields in the document. Also, the types of the received program variables must match the corresponding input field kinds in the document. No input field or program variable may be mentioned twice in the receive assignment list.

Show/Timeout
stm ::= show exp timeout stm
stm ::= show exp receive [ { exp = id } ] timeout stm

The show statement may include a timeout statement that will be executed if the client does not submit the page shown before a certain amount of time has passed. This amount of time can be defined either globally in the <bigwig> configuration file (SPANDEFAULT [48hrs by default]) or per service, per session, or even per show statement using the span modifier. The span modifier takes an expression in parentheses and can be placed after the show keyword in show statements.

Exit
stm ::= exit exp ;

The expression, that must be of type html, is evaluated yielding a document value, whose remaining gaps are implicitly closed (filled with nothing). The exit statement will show the computed document to the client and the service will terminate. Exit can also be called with a string (designating a URL) argument or with no arguments. We refer to the Control Structures section for information on these two variants.

Requirements: The expression is of type html and the exited document must not contain any input fields.


Flow Join Requirements

Because the flow analysis needs to infer the flow types of all html variables at all program points, all flow paths joining together must agree on the flow types of all live document variables.

If a gap is not present in all flows joining together at some program point, the gap is implicitly closed (plugged with nothing) by the compiler and henceforth no longer available for plugging.


HTML prototypes

html ::= <html> htmlbody_list </html> @ stringconst

The stringconst must designate an html file. If the file is not present (at compile-time), the value of the construct is the value of the constant document listed. If, however, the file is present (at compile-time), it will be the value of the construct. The html document in the file is required to have the same document type as the constant document (i.e. same gaps and fields) which is checked at compile-time. The idea behind this construct is to provide a means for rapid prototyping. The programmer rapidly makes some prototype html documents, with focus on the functionality (fields and gaps) and not on the graphical layout of the document. Then, as the real documents are gradually created, they replace the prototype ones.


Code Gaps

Code gaps are reminiscent of PHP and ASP evaluation tags. There are two kinds available in <bigwig>:

Code Expressions:

htmlbody ::= <[ ( exp ) ]>
attr ::= [ ( exp ) ]

Documents are allowed to contain in-lined expressions that are evaluated just before the document is shown. The value of such an expression is coerced to a string and inserted in the document in the place of the code expression.

Code Statements:

htmlbody ::= <[ compound_stm ]>
attr ::= [ compound_stm ]

The same thing is possible with statements. The last statement in the compound_stm must be a statement-expression (stm ::= exp ;) whose type must not be void and whose value (coerced to a string) is inserted in the document.

Code gaps are evaluated in the order of occurrence in the document shown.


Research papers on Dynamic Documents:


bigwig@brics.dk
Last updated: November 2, 2001
Valid HTML 4.01!