Wednesday, August 31, 2005

<bigwig>

<bigwig> is a domain-specific language for web development that includes statically-checked, higher-order templates and a “session-based” model of a web interaction as a single, coherent flow-of-control. Through flow-based analysis, <bigwig> programs are statically checked for template consistency — for example, that a template includes an expected form field name — and HTML validity. <bigwig> is implemented with a custom Apache module that allocates and maintains a server process for eachuser session.

Though its support for form-based interaction is strong, <bigwig> is unsuitable for content-focused web applications because of its limited support for custom hyperlinks. It provides a “document reference” operator that allows one template to contain a hyperlink to another, forming a — potentially cyclic — “document cluster” of the templates. These clusters must be comprised of templates in the same scope that have identical form elements. <bigwig> has no analogue to send/suspend/dispatch.

<bigwig> has coped with the lack of backtracking in its linear, process-based model of interaction by disallowing the back button in users’ browsers. It accomplishes this by always redirecting the user’s brower to a consistent URL that identifies the session, while the content at that URL changes dynamically. The session only generates a single entry in the browser’s history, so if the user clicks “back,” the browser will go to the page that immediately preceeded the start of the session. We believe this solution is unsatisfactory because it does not conform to users’ expectations of back button behavior, and eliminates the common use and usefulness of the back button as an “undo” for intermediate steps in web interactions.

JWIG, the Java-based successor to <bigwig> is based on, and compatible with, standard Java, and is implemented with a combination of Java libraries and a preprocessor that converts the JWIG language extensions into standard Java and performs the static verifications.



Attractions
  • Custom high-level, domain-specific language that compiles down into server- and client-side implementations
  • Sessions are explicit… but do they have environments?
  • Temporal logic and other static analysis
  • “Session-centered” approach, which means non-CPS web programming
  • Uses suspended threads to simulate continuations
  • Flow analysis to make sure templates are constructed correctly from fragments
  • Allows for “simple” inline templates to be automatically replaced by more elaborate external versions (presumably written by a web designer)
  • Nifty sub-page caching of templates (though it requres JavaScript and eliminates searchability)
  • Handles compiling validation code into both client- and server-side versions, including an extension to regular expressions that supports binary decision trees (for form validation that spans several fields)

Detractions
  • Superceded by JWIG
  • Punts on the back button. Disallows it. Says bookmarking is stupid. Tells you to write your own back functionality if you really want it. Usability score: -89.12
  • Template fragments cannot contain closures. “Code fragments” can only reference global methods and variables. (Though they don’t really have any higher-order functions.)
  • Not much support for arbitrary graphs of pages and links (i.e.: what you’d need for a CMS or blog)

Sunday, August 28, 2005

Seaside

Seaside is a Smalltalk-based web development framework with continuation support. Seaside models a web page as a tree of nested component objects, each of which can independently render itself and respond to user interaction. A component can use the call method to suspend its own processing and replace itself with another component, which appears in its place on the page. The replacing component may use its answer method to remove itself, resuming the original component and passing it data. As with send/suspend/dispatch, Seaside allows web applications to associate blocks of code with links, which are executed when the links are clicked. Applications do not have access to the URLs generated for these links, as they do with send/suspend/dispatch, and therefore cannot re-use them on a page (to conserve resources), modify them, or include them in JavaScript. Nevertheless, Seaside also supports attaching blocks of code to form input elements and submit buttons, which get executed automatically when the associated form is submitted. Though Seaside’s object-oriented approach makes it more susceptible to the Orbitz bug and other misplaced mutations, it overcomes this with a mechanism to “backtrack” the state of components if the user uses the back button.

While Seaside’s component-based approach is very good for modularizing complex pages, it does have the limitation that a single component cannot interrupt its computation to send a page to the user without passing control to another component using the call method. Furthermore, Seaside’s request-processing strategy requires that a component define a method to return a list of all subcomponents it might render, separate from the method that actually chooses and renders those components.

Good Things
  • HTML is generated by sending messages to an HTMLRenderer object. Nested content is created by using a block with its own messages as an argument. Good means of abstraction.
  • Anchors and submit buttons are given blocks, which function as s/s/d callbacks
  • Small support for custom URLs: components can implement an updateUrl method. Needs more documentation.
  • Support for embedding subcomponents, who can call: other components, which replace them in the rendered page.
  • Has an isolate: method for preventing backing into committed transactions.
  • Strong development environment, with updating running code and online debugging
Curious Things
  • All input elements are given callbacks that are invoked when the form is submited. The argument to the callback is the value of the form field. Used for saving the form state to an object. Seems like a lot of boilerplate?
  • It’s good that Seaside provides a mechanism for “backtracking” objects, but bad because it needs this because of its heavy reliance on mutation.
Bad Things
  • Because Smalltalk keywords must come in a particular order, need a hack, the attribute buffer, to handle arbitrary attributes on HTML elements.
  • Is it true that call: must take a separate controller as its argument?
  • Leakage: “Each parent component must implement a #children method that returns a collection of all of the subcomponents that it might display on the next render.”
  • Don’t seem to have access to URLs (for re-using or for appending #s to)
  • Can a subcomponent make a call to another component modally? i.e.: the called component takes over the screen, but when it answers it does it to subcomponent?

Opinion Things
  • Award for slickest-looking web site so far

Tuesday, August 23, 2005

Cocoon

Apache’s Cocoon framework was developed as part of a project to provide online documentation for the Apache Software Foundation’s Java libraries. Owing to this history, Cocoon’s page generation is built around the concept of a “pipeline,” where data, encoded as an XML document, passes through several transformations (which can be described using Java or XSLT) before it is presented to the user as HTML, XML, or another format. Cocoon makes heavy use of XML languages and XSLT in definining pipelines, templates, forms, and even as a preprocessor that generates Java. One of Cocoon’s unique features among Java frameworks is its support for continuation-based web programming. Cocoon allows deveopers to write controller logic in JavaScript, which it interprets with an embedded version of the Mozilla Foundation’s Rhino JavaScript interpreter. Cocoon’s Flowscript JavaScript API provides a sendPageAndWait method that is analagous to the PLT server’s send/suspend. Though the JavaScript code has full access to Java classes and objects, Cocoon is limited by the inability to capture a continuation from Java. Once a JavaScript controller calls sendPageAndWait to invoke a pipeline to generate a page, the web application cannot capture any continuations until the user responds to the page and control passes back into JavaScript. Since the view elements of Cocoon — the pipelines — cannot dynamically create continuations to tie to links, Cocoon has no analogue to the PLT server’s send/suspend/dispatch.



Highlights
  • Pipeline model of handling requests, based around XML transformation
  • Combines XSLT and Java as a preprocessor: Logic files use XSLT to pattern match on input XML and generate Java code
  • Has a “view” mechanism for accessing content orthoginal to a normal pipeline
  • Built-in and configurable support for automatically caching steps of a pipeline
  • Overall application layout and pipelines specified externally in an XML file
  • Contains a JavaScript interpreter with continuation and sendPageAndWait (send/suspend) support that can invoke pipelines and also call back into Java
  • Form definitions written in XML, rather than Java
  • Two-step form creation: widget -> XML, XML -> HTML (via XSLT)
Downsides
  • Pipeline itself does not support continuations
  • Forms support still under development
Rampant Speculation and Uninformed Opinion
  • “Pipelines” are basically just functional programming. But that’s a big deal in Java, I guess.

Fun Excerpts from the Docmentation
  • “In getting started with Cocoon, one must learn not only a number of concepts, but a number of details as well.”
  • “Given the amount of hype, you can't afford to go around ignoring XML”

Monday, August 22, 2005

Struts

Struts brings an MVC structure to Java servlet programming. It provides mechanisms for routing HTTP requests to application components in the controller layer, and connecting those components to appropriate model JavaBeans and views. Views can be written in JSP or any other HTML-generating system, and Struts provides utilities for converting between JavaBeans and HTML forms, with appropriate validation and error reporting. Struts gives developers the full capabilities of Java servlets, including built-in internationalization support, verbose XML-based configuration, and large-scale deployment. Nevertheless, Struts is based on a session-state model of web applications and does not provide a mechanism for state with environment semantics. This makes it very susceptible to the Orbitz bug.




Highlights
  • Forms defined with DynaBeans (like JavaBeans but not statically-coded)
  • Comprehensive control over sessions
  • Enterprise-level tools (WAR files for deployment)
  • A bit of magic to go between JavaBeans and forms, with free validation and error reporting
  • Built-in support for i18n
  • Simple module mechanism
Downsides
  • Regular JSP has poor modularization semantics (only textual include), though tag libraries may promise some more sensible reuse
  • Has no “interaction” scope to emulate the environment

Opinion and Idle Speculation
  • A serious mess of XML configuration files
  • Similar functionality to Rails, but without the amazing magic that makes Rails worthwhile

Sunday, August 21, 2005

WASH/CGI

WASH/CGI is a comprehensive web application framework for Haskell whose focus is to abstract away the creation and processing of HTML forms. Using Haskell’s type system, WASH/CGI can determine the expected type for form inputs and automatically validate them, re-displaying the form with appropriate error messages if necessary. To further aid development, it provides pure-functional wrappers over both cookies and server-side persistent state and uses the type system to guarantee that, in most cases, all application pages are valid XHTML.

Though WASH/CGI and Continue programs share a similar structure — user interactions can occur at arbitrary points in the code — WASH/CGI relies, not on continuations, but on saving a log of past inputs and replaying the web application from the beginning for each interaction, referring to the log when necessary. As Haskell programs are deterministic, this strategy gives consistent results, but with the cost of duplicate computation. WASH/CGI conserves server resources by saving the log in a hidden form field, with the consequence that, unlike Continue web applications, WASH/CGI applications cannot maintain environment state when user interaction takes place through hyperlinks. (Though it is possible to use JavaScript to make hyperlinks that act like form submission buttons, this trick does not work for situations such as our e-mail verification example.) For security reasons, the contents of the hidden form field are encrypted, though the strategy the authors claim to use — one-time pads — would require that the webserver keep, byte-for-byte, the same amount of data present in the clients, completely eliminating any resource savings gained by storing state in hidden form fields.



Highlights

  • Type system used to ensure page validity
  • Inputs from form fields are validated and given types
  • Stores “session” data in hidden form fields
  • Neat use of static type inference to avoid declaring types or validators for form fields
  • The once operator neatly deals with transactional stuff by collapsing the result of a series of interactions into just the result
Drawbacks
  • Needs a whole separate system (decision trees) to deal with forms where not all fields are validated. (Example: choose between two payment methods w/ radio button, don’t need to validate the unselected method’s fields)
  • Has to invent an entire persistence layer to compensate for Haskell’s pure-functional nature.
  • OMG, this can’t be practical: the entire program is replayed with each new input
  • A true one-time pad has to be the same length as the data it’s encrypting, so there’s no space savings if that’s what they’re actually doing
Opinions and Speculation
  • Seems much more interested in form interactions
  • Authors claim that mismatched input form names is a “common source of errors.” I disagree. It’s a problem easily solved by defining a string constant that’s your input form name, and using it when you create the form and when you extract values from the request. While a mechanism for automating it is as helpful as pretty much any little abstraction, it is not a huge deal and not worth the loss of human control over form field names. Using well-known form field names helps users who use programs that automatically fill out forms (inserting name, e-mail address, home address, etc.)
  • This is totally indecipherable type systems and semantics