| 11/10/1998 | 299 Promenade Street, Providence, Rhode Island 02908 |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| UI Development Using XSL Beans | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Discussion of Application Development Environments With A Focus On XSL Beans | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Gavin Thomas Nicol | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Chief Scientist | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| eBusiness Technologies | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
GUI Development Environment Using XSL Beans
Basic Development Environment Look and Feel
Applications and Application Behavior
What Is an Application Physically?
WWW Applications and Distributed Closures
To Script, or Not to Script — That is the Question.
Scripting, Functional Programming, and XML Instances
Development Environment Extensibility
Extending the Vocabulary — Functional Composition
Extending the Development Environment
In a companion paper 'Platform Independent UI Objects', the author introduced XSL Beans, a technology that allows UI's to be instantiated using different display technologies, and different object systems. It is assumed that the reader is familiar with the XSL Bean concept.
The following is a summary of the advantages of the approach outlined in that paper:
This paper discusses application development environments, and the background issues associated with them.
The intent of this paper is to provide a basis for discussion and development of an application development environment and in particular, one that is compatible with the XSL Bean approach to UI instantiation. Some possible deployment strategies are also discussed in later sections.
There are many different ways XSL Beans could be used within a development environment. This paper discusses, at a high level, how an application[1] development environment using XSL Beans might look and feel, and the issues associated with it. The discussion here is necessarily specific to an imagined implementation, but the concepts can be carried over to other implementations. In particular, the exact GUI depends very much on the layout and scripting paradigms chosen.
The primary goal for an XSL Bean development environment should be to support rapid application development or RAD, in much the same way that Visual Basic does: Visual Basic does not claim to be comprehensive, or necessarily the best tool, but for many cases, it is sufficient. Anecdotally, it provides 80% of the value for 20% of the complexity.
Target Users for UI Development Environment
An application development environment should strive for a balance similar to that shown above: it should be easy and intuitive to accomplish the tasks at hand for the majority of users, with a minority feeling constrained or overwhelmed (users at the edges of the bell curve).
As stated above, an XSL Bean based UI development environment should strive to be roughly on par with Visual Basic. It is also reasonable to say that the basic paradigm for an XSL Bean development environment itself should be similar those for Visual Basic and JavaBeans. The Visual Basic for Applications development environment is shown below.
Visual Basic for Applications Development Environment
The main features of such an environment are:
Most basic GUI-builder interactions with the components take place via property editing. Programmed blocks of code that respond to events (one can look at these blocks of code as properties of the object as well) handle behavior (such as calling out to ODBC to get the value for a property) that cannot be described by properties alone. This paradigm is widely accepted by developers as being powerful and easy to use.
It should be noted that in general, environments such as the above focus on rapid development of the GUI layout, rather than the application. This is a subtle and important distinction. This paper discusses application development in addition to GUI development.
Given the desire to emulate Visual Basic, a development environment using XSL Beans might look like the following (and all development GUI mock-ups will use this as a base from now on).
Example GUI for Web Page Layout Editor using XSL Beans
The GUI provides a palette of available XSL Beans (left) that can be used to layout a page (right) in a semi-WYSIWYG manner. XSL Beans can be dragged from the palette onto the page. Once instantiated on the page, double clicking produces a property list that can be edited. Setting some properties may involve interaction with a wizard.
Layout of the GUI objects is a fundamental action in application development. While it could be argued that a page-centric layout model is applicable to the WWW the paradigm espoused here is application-centric[2] as it is the author's (possibly mistaken) belief that Web application development is an overarching goal for many WWW developers. However, the issues involved with laying out GUI controls are> very similar to those in text formatting.
In Visual Basic, objects are placed in fixed positions on a fixed-size form. When a window is resized, or if the form is displayed at different resolutions, objects are generally scaled linearly (though programmers can override the default behavior). This results in forms that either look ungainly at certain sizes/resolutions (for example, toolbars that are oversized), or that require significant amounts of coding.
The model espoused here differs in that it dynamically reconfigures itself to handle arbitrary window sizes and resolutions. This is particularly suitable for the WWW, where screen resolution, available fonts, and locale can differ greatly between clients. This is also superior for I18N, because labels, menus, etc. will resize according to the size needed by a given language. The model is based on one of the most famous text formatters every produced: TeX, by Donald Knuth. It has been used with great success in the Fresco and InterViews GUI frameworks, and was the basis of the layout model used in Nemo, the prototype GUI builder for DynaWeb.
The basic model is that there is a top-level box, which can contain other boxes or glue that can stretch and shrink. Different combinations of this can result in different effects. For example:
Sample of Box and Glue Layout
This is a horizontal box, containing three components, 2 pieces of glue, and one piece of text. If the pieces of glue are given an infinite desired size and an infinite amount of ability to stretch and shrink, the text component will be centered within the horizontal box, no matter what size the horizontal box becomes. This is often called constraints based layout, because constraints on sizes determine object dimensions. It is also often called the boxes and glue model.
More complex controls can be built out of the combination of boxes, glue, and primitives, such as buttons. In InterViews, even primitives such as buttons were built from a number of finer grained objects, such as icons.
For example, a browser window such as the following
A Sample UI
could be built using boxes and glue, as shown in the next example.
Example of Complex Boxes and Glue Layout for GUI
Obviously, because the boxes and glue model is purely hierarchical, it can easily be represented using XML, as a flow object tree (FOT), or as a hierarchy of JavaBeans (Swing already does something like this).
In a development environment, the boxes and glue model provides a simple and consistent model for development. In the Jupiter information delivery environment, most GUI's will not be anywhere near as complex as the preceding example. For example, the following is the GUI layout of DynaWeb, as it would appear within the example editor shown earlier.
Example GUI for Web Page Layout Editor using XSL Beans
This GUI could be created using the following steps:
Given a suitable set of XSL Beans with knowledge of one another, the user need do little more than this for most cases, because the objects will automatically synchronize themselves. For example, a standard set of objects that comprise a DynaWeb UI (TOC, content, search sliver) might be provided that knew how to look for, and update one another. This logic would be coded into the default action handlers supplied with the objects.
While this is sufficient for many simple tasks, it soon proves to be limiting. Some means of modifying the runtime behavior of an application is also needed.
While simple layout and simple configuration changes can be easy to make, editing application behavior is more complicated. Before discussing behavioral editing in detail, it is useful to have some notion of what precisely an application is[3].
Like objects, an application can be split into two pieces: what it is physically, and what it does (this should not be surprising, because an application is an object in itself). Each of these can be analyzed separately:
As with objects, an application can be represented by its state (though obviously the code is a necessary component too). This state is the set of objects and their properties and values at a particular point in time. This is proven by the fact that it is possible to serialize and then deserialize an application. The deserialized application is essentially identical to the application as it was serialized (at least for the split second at which the deserialization was complete, because timers etc. could alter application state almost immediately).
The behavioral aspects of an application can be seen as actions causing state transitions[4]. Not all aspects of behavior can easily be described this way however, because a state transition implies an atomic action, and in some cases, a sequence of actions needs to be performed, possibly with control flow. These can be described using single transitions, but such fine-grained descriptions of a system are very hard to create and comprehend.
Given the above, a reasonable definition of an application is:
An application consists of a network of objects making up the state of the application, and logic that results in changes to that state (state transitions).
The state of an application can also be looked upon as a closure, as commonly found in LISP systems.
The notion of a closure is foreign to many people, and indeed to many programming languages, but falls out naturally from the way LISP systems manage objects. In most LISP systems, there is an object called the environment. The environment grows and shrinks as procedures are called, because frames are added/removed during program execution to provide lexical scoping for parameters etc. (similar to the stack in other languages).
All active objects in the system are found in the environment or within objects in the environment (including procedures, numbers, constants, symbols, etc.). As such, a closure is essentially a snapshot of the environment at a given point in the execution of the application.
For WWW applications, and particularly those involving sessions, the notion of closure is extremely useful, because a closure is the Application State frozen at a point in time[5]. When multiple simultaneous clients are connected to a WWW server, it is effectively running multiple applications concurrently. Closures and environments provide a good conceptual (and possibly actual) way of managing application data, and maintaining the correct scoping relationships between applications, as shown in the following diagram.
Application Environments In The WWW
In effect, an environment spanning the client and the server[6] is being maintained, and each application environment is logically separate from any others (though some things in the environment might be shared, such as system-wide objects like logging services).
In cases where there is no explicit session (for example, no cookies are used to manage session id's), a closure is transmitted back and forth (i.e. the application state is held in the URL's, URL parameters, etc.). Clicking on a link in client results in an altered closure being sent to the server, which in turn returns a modified closure to the client[7].
In cases where sessions are used, deltas to the environment are transmitted back and forth such that the client and server, together, maintain the environment. For example, some local DHTML might alter the environment such that the color of a button is changed. At the point where the server next needs to know the button color, it needs the updated information. The exact way on which the environment is synchronized depends very much on the protocol and object system in use. For example, CORBA would allow the server-maintained Button State to be updated directly (effectively having the environment always live within the server address space), while HTTP does not.
The important thing is that any change to the environment is constrained to the environment within that application: so applications cannot interfere with one another. This is very important for reliability, security, and many other things. While environments can be simulated in CORBA, it is always possible for one application to interfere with another, because applications are scoped through the naming service. With environments, this cannot happen, because an application can only see what is in contained within its environment.
Given the above, the problem of editing application behavior becomes one of describing responses to state transitions (changes to the environment), that in turn cause other state transitions (changes to the environment). For example, when a button is pushed, the pushed property of the button changes from FALSE to TRUE. The task is to associate an action with the event[8] generated by the change.
Obviously, the objects and properties affected during a state change are those to be found in the environment of the application (within its closure), so within the development environment, it is easy to determine the objects that can be affected. This makes it relatively easy to provide functionality akin to the Visual Basic auto-completion feature, where a 'word wheel' of objects and properties pops up when a few characters are typed (this could be called an environment browser).
Having identified an object or property, there are only 3 actions that need to be performed directly:
In addition to these primitives, some means of combining them is necessary (and naming the combinations), and some means for altering control flow, are necessary. The first of these tasks provides one axis upon which to extend the vocabulary for describing the application behavior (this is essentially adding verbs, the second axis is to add objects/nouns).
One of the recurrent questions regarding application development is whether scripting is necessary, or desirable. From a manageability, maintainability and reliability perspective, scripting is certainly undesirable (witness the rising costs of WWW sites!), so a general guideline is that there should be no scripts.
However, from a purely practical perspective, some scripting is necessary, because it is very hard to comprehend large state transition networks, and very difficult to build design tools for them that scale well. Programming with transition networks is beyond the capabilities of most developers, who are used to procedural programming languages, or ad hoc scripting languages such as Perl.
In addition, there are cases where managing a set of actions as a unit allows greater modularity, and maintainability etc. Thus, the question is not whether scripting needs to be provided but rather, what form the scripting should take. A development environment must provide some form of scripting capability to be used in 'gluing' the application together that does not reduce the ability to manage and maintain the application.
Computer programs are difficult for both humans and computers to analyze well. Many procedural programming languages allow procedures to modify global state (global variables) which compounds the already difficult problem, effectively rendering analysis impossible. It is well know that global variables lead to bugs, and generally cause grief to all that encounter them. In order to support the goals given above, global variables should be avoided.
An older form of programming, called functional programming gives at least equivalent expressive power[10], but can be more readily analyzed by computers, and can be built with GUI's. Functional programs can also be represented meaningfully in XML (in other words, XML structure can meaningfully be used to represent the structure of a functional program), as explained in the next section[11].
The following is a fragment of JavaScript and HTML that reacts to events on a selection menu, and then changes the background color of a document.
<SCRIPT LANGUAGE="JavaScript1.2">
function setColor() {
var choice;
choice = document.colorForm.color.selectedIndex;
switch(choice) {
case 0: document.bgColor = "FF0000"; break;
case 1: document.bgColor = "00FF00"; break;
case 2: document.bgColor = "0000FF"; break;
}
}
</SCRIPT>
<SELECT NAME="color" onChange=setColor()>
<OPTION VALUE="red">Red
<OPTION VALUE="green">Green
<OPTION VALUE="blue">Blue
</SELECT>
JavaScript Fragment for Background Color Selection
This uses the value of one property to decide the value of another, which is a very common pattern in GUI programming.
The important thing to note about the script here is that even though it is written using a procedural language, it is almost entirely declarative. For declarative statements, functional and procedural languages generally look very similar. For example, here is the equivalent script in Scheme:
<SCRIPT LANGUAGE="scheme">
(define setcolor
(let choice (document.colorForm.color.selectedIndex)
(cond
(eq choice 0) (define document.bgColor "FF0000")
(eq choice 1) (define document.bgColor "00FF00")
(eq choice 2) (define document.bgColor "0000FF"))))
</SCRIPT>
<SELECT NAME="color" onChange="(setcolor)">
<OPTION VALUE="red">Red
<OPTION VALUE="green">Green
<OPTION VALUE="blue">Blue
</SELECT>
Scheme Fragment for Background Color Selection
Obviously, the syntax is different, but the control flow is identical, as is the gross structure of the script.
The object and behavior definition examples above actually reflect a poor design, because the script is defined outside the scope of the object using it. This complicates namespace management (what if a user wants to have 2 different setcolor procedures?), and also raises the question of which environment the script should be executed in[12].
The definition style shown above is almost entirely due to the models of HTML and JavaScript being brought together[13]. In more object-oriented systems, the setcolor function would be a method on the object. For example, in Java, this is almost certainly how it would be modeled. Another way of looking at this is that DHTML has all the MVC (model view controller) components in a single place.
An alternative representation of the above, written entirely in scheme, could be written:
(radio-button-group
(define options '("Red" "Green" "Blue"))
(define OnChange
(lambda ()
(cond
(eq choice 0) (define document.bgColor "FF0000")
(eq choice 1) (define document.bgColor "00FF00")
(eq choice 2) (define document.bgColor "0000FF")))))
Alternate Scheme Fragment for Background Color Selection
Which is clearer[14], shorter, more maintainable (because of increased modularity), and does not have the scoping problem discussed above.
More importantly, this can easily be represented in XML:
<select type="radio-button'>
<options>
<option name="Red"/>
<option name="Green"/>
. . .
</options>
<method name="OnChange">
<switch>
<expr><get name="choice"/></expr>
<case expr="1">
<set name="document.bgColor" value="FF0000"/>
</case>
<case expr="2">
<set name="document.bgColor"value="00FF00"/>
</case>
. . .
</switch>
</method>
</select>
Background Color Selection Using XML
This is somewhat verbose, but the important point is that equivalent functionality can be achieved using an XML-based syntax, and that in XML, the scoping of variable names (lexical scoping) is intuitive, because it reflects the hierarchy of the document tree. The variables that can be seen from within a given expression are those variables defined at some point within the ancestry of the expression.
The use of the call primitive to call functions is reasonable in such cases, because the scope of changes a function can make are limited to the scope of the environment in effect at the time the call was made. Another way of saying this is that a function (lambda) can be expanded inline (similar to macro expansion) with no change of behavior in the application. This point is a subtle, but very important one.
Note also that a minimal LISP implementation only includes about a dozen language constructs, and relies heavily upon functional composition, so a simple XML-based language could be made very small, but very powerful.
That said, it should be noted that pure functional programming is not a panacea: many programmers find it foreign and counterintuitive. It is the authors' contention however, that within the scope of UI programming, and UI object composition in particular, functional programming is not only desirable, but critical.
In Visual Basic, and other similar environments, the development environment does little to aid in the task of actually writing code. Such environments will generally produce a procedure or function skeleton that the developer must flesh out, and debuggers to allow the programmer to easily debug the code they've written. Writing and debugging the code fragments is where most development effort occurs.
Obviously, code such as the above can be written using a text editor, but it is equally obvious that this is not an ideal environment for developers. An application development environment should provide tools that not only make it easy to produce GUI and event handler skeletons (as outlined earlier), but also offers tools for actually producing code as well. The following figure shows one potential UI used for editing the code above[15].
Example GUI for Action Editing
This figure shows a dialog box for editing the action associated with selecting something in a radio-button menu. The steps leading to this display might be something like:
This is a very simple example, but demonstrates most of the pertinent components:
Notably absent from the example above is the ability to add user-defined functions and procedures through composition. This is discussed in detail in a later section.
For some developers, such an environment will prove limiting or confusing, because as expressions become more complex, the number of open expression wizards will conceal the overall control flow. This results in something akin to the 'lost in hyperspace' feeling, which is caused by too many open windows, or lack of link context.
As such, some ability to escape out of the wizards, into an editor, or development environment of choice is needed. For most systems, code written at this point is essentially a black box, and can no longer be edited, or analyzed by the development environment. A good development environment should not only support such code, but make it easy for the programmer to develop it. For example, rather than forcing the programmer to escape to an external application, the development environment could provide an 'expert mode' interface that allowed expressions to be typed in directly. This 'expert mode' should provide hints along the way, indicating possible functions to use, available variables, syntax errors, etc.
However, with the type of declarative language being discussed here, even external environments can be supported directly. The main difference between standard development environments using procedural languages, and what is discussed above, is in the handling of variables. Procedural languages generally allow variables to occur at a global level (as discussed earlier), and also allow references to variables to be passed to, and returned from procedures or functions. This leads to many situations where it is simply impossible to determine what effect changing a variable will have, because it is impossible to determine where in the application it is being used. In many cases, it is even possible for the exact same memory region to have multiple names (variable aliasing). These problems make it essentially impossible to analyze arbitrary code contributed from a developer.
In the type of language discussed above, arbitrary fragments of code can be contributed, because lexical scoping makes it impossible for the code to modify any variable not directly within the expression ancestry. As such, the development environment can parse and make sense out of contributed code because it knows all of it's dependencies.
Obviously, and XML-based, or even functional scripting language is useless if no widely deployed interpreters for it exist. An important point about the language discussed above is that the syntax is largely irrelevant: XML, scheme, or any number of other representations could have been used. In other words, it can easily be transformed into alternate syntaxes.
For example, given the following code snippet
<select type="radio-button'>
<options>
<option name="Red"/>
<option name="Green"/>
. . .
</options>
<method name="OnChange">
<switch>
<expr><get name="choice"/></expr>
<case expr="1">
<set name="document.bgColor"value="FF0000"/>
</case>
<case expr="2">
<set name="document.bgColor"value="00FF00"/>
</case>
. . .
</switch>
</method>
</select>
Background Color Selection Using XML
It is obvious that it can be transformed into something like the following:
Function select As Integer
Dim dialog as Dialog
dialog = Selection("Red","Green","Blue")
Switch dialog.select()
Case 1: document.bgColor="#FF0000"
Case 2: document.bgColor="#00FF00"
Case 3: document.bgColor="#0000FF"
End Switch
select = dialog.selected()
End Function
Background Color Selection Using Basic
Even much more complicated expressions, even function declarations, can be converted to alternative syntaxes. This is entirely consistent with the XSL Beans approach to UI objects, which are platform independent. The above represents a platform independent scripting language.
Once the GUI has been built, and actions edited, the developer will need to test the application. In most environments, there is some way to switch from edit mode, to run mode. In run mode, the application executes as normal, though in most environments, the application executes within a debugging environment. An XSL Bean development environment also needs to minimally provide a run mode, and should also provide some form of debugger.
Note that with a functional language of the form outlined above, debugging is a much simpler task because application state changes are localized. As such, it becomes obvious where the bugs lie.
Perhaps the most complicated part of debugging applications such as those discussed in this paper, is that the events, and state transitions can happen in a distributed manner. Indeed events could be handled in any number of different environments (DHTML, Java Applets, CORBA objects, etc.). The two basic approaches to this problem are:
Extensibility within a GUI builder, or development environment generally falls into four categories:
Each of these is discussed below.
The ability to add new objects is obviously desirable and indeed crucial to the success of the development environment: it is impossible to create a set of objects that will meet everyone's needs. The exact amount of direct support for creating new objects that should be provided is a difficult and important decision to make. Development environments such as JBuilder and Visual C++ provide wizards that guide people through the creation of a new object (either from scratch or as a derivation of an existing object). Such functionality should exist in an XSL Bean development environment as well, but adding more than just this quickly increases the complexity of the development environment.
In an XSL Bean based development environment, the primary task will be creating new XSL stylesheets, but at times, creating new flow objects might be necessary. For example, if a user wanted to create a variant of a TOC Bean that merged ODBC data and XML data together, one possible implementation strategy would be to write a flow object that did this. A sample XSL stylesheet for such cases might look like:
<xsl:rule pattern='h1'>
<h1><xsl:process-children/></h1>
</xsl:rule>
<xsl:rule pattern='div'>
<foo:odbc query='..'../>
</xsl:rule>
Sample XSL Stylesheet Using Custom Flow Objects
The important point in the above being that namespaces provide a perfectly reasonable way of partitioning the object space such that customizations do not conflict.
In cases where XSL functionality alone is insufficient, custom flow objects provide an 'escape hatch' to code, that is still well contained, and maintainable.
It is imagined that system programmers will deal with XSL Bean components (instances, stylesheets etc.) as discreet objects, and possibly directly implement custom flow objects to achieve their goals. Such programming can greatly benefit from an integrated development environment or IDE, but the low return on investment (in terms of productivity), and complexity of developing such IDE's makes it infeasible to either describe or implement a comprehensive solution for this. As such, a COTS product might be used: for example, if development takes place in Java, then JBuilder, Visual J++, or some such environment could be used.
Minimally, a development environment should make it easy to integrate with such third party tools. For example, a menu item might be provided that allowed a programmer to launch an application to develop a flow object (i.e. a flow object might have an associated application project), and/or provide wizards to guide through the initial skeleton creation phase.
The boxes and glue model espoused here leads to the obvious ability to compose objects and name them. From a developmental perspective, the main capabilities the development environment needs to provide are:
When composing a new object from existing objects, there needs to be the ability to create a composite object instance, or a template. A template is something that can be named, and later instantiated again (reused), whereas a composite object is instance specific. Ideally, a user should be able to save any composite object, as a template at will.
The development environment should alert the user of things that might make reuse difficult. For example, if all the objects within a single composite object had hard-coded, and different data source properties, instantiating a new object from the template would involve a great deal of work (i.e., the system should help users define templates in an object-oriented manner).
As noted earlier, the power of a language is not really in it's breadth, but rather in the ways in which it can be extended, and the ways in which constructs can be combined. For example, even though English has well over 500,000 words in the language, only extraordinary people have a usable vocabulary exceeding a few thousand words.
As noted earlier, one axis for extension is the addition of first-class objects with properties (i.e. adding nouns to the language). The other axis for extension is through packaging combinations of expressions into a unit that can be referred to. This is often called functional composition. Expressions in an XML-based functional language could occur anywhere a literal value could occur, so combinations can easily be created, and given that a function call is another form of expression, functions cal also be used at arbitrary points.
In procedural languages, there is something akin to functional composition called procedures, or functions.
In an XML-based language[16] parameter scoping should be purely lexical in nature, making it fairly easy to write functions independent of their usage. A GUI could even be build for this, though again, a GUI environment will generally be constraining to more sophisticated users, so some escape mechanism would be needed.
While this is a desirable feature, it can be very difficult to provide a seamless way to extend the development environment. Perhaps the key thing here is to provide hooks for all areas of functionality the application development environment provides. For example, hooks that allow custom object inspectors to be 'plugged in', or that allowed some code to catch debugging events, would be extremely useful.
Any extension to the environment should require system programming, and as such, only minimal support needs to be given to it.
Basically, there are three approaches to providing a development environment:
The author's personal preference is to develop the environment.
This paper has looked at WWW applications and development environments for them. The main points can be summarized as follows:
The following is a list of recommended reading only. Compiling a full bibliography for the ideas in this paper is an almost impossible task.
The author wishes to gratefully acknowledge the early reviewers of this paper for their conscientious review and thoughtful comments. The reviewers, in no alphabetical order were:
[1] It has become common to call interactive WWW sites applications, and it is in this sense that the term is used here.
[2] The author feels that both have a place. Page-centric layout is crucial for producing acceptable print output, but application-centric layout is better for WWW pages. Within certain objects on a WWW page however, the page-centric model may still be applicable.
[3] A complete discussion of this is beyond the scope of this paper, so only a brief discussion is given. This may be the topic of a future paper.
[4] The topic of behavioral specification using transition networks as described in chapter 5 of 'Object-Oriented System Development) is very applicable here.
[5] This is not quite true. The true state of the application includes the state of the process itself. In some LISP systems, there is another first-class object called a continuation, which is a closure and an associated (lambda) function to be called to restart processing.
[6] The term environment was often used in this sense in DynaWeb 1.0.
[7] Actually, the server keeps sending an environment with continuations to the client. Clicking on a link effectively activates a continuation. It is not expected that readers will understand this.
[8] Note that the term event here differs from the commonly accepted usage, but encompasses all the functionality of it.
[9] This might be better called apply.
[10] An excellent paper discussing functional programming is 'Why Functional Programming Matters', by John Hughes.
[11] Note that first-order functional (applicative) languages are better.
[12] In some cases, global functions/procedures are necessary, but in UI programming, this is less common than is normal in programming, and generally restricted to simple functions.
[13] There has been some work by Microsoft within the W3C to standardize such practices under the label HTML Components. In some ways, these are similar to JavaBeans.
[14] The use of lambda may not be obvious. A lambda function is effectively an unnamed procedure, so in the example, we are assigning an unnamed procedure to onChange, and it will be executed when onClick is called. In many LISP systems, this is actually how procedures and functions are stored.
[15] Note that much of the UI discussed here could be used in other places. For example, many rules engines are essentially a functional language interpreter, and the UI discussed here is equally applicable.
[16] Indeed, this is desirable in most languages, and is part of most functional programming languages.