focusdynamically typed 1 languages Seaside: A Flexible Environment for Building Dynamic Web Applications

Stéphane Ducasse, Université de Savoie Adrian Lienhard and Lukas Renggli, University of Bern, Switzerland

age-centric Web development structures an application into indi- The Seaside vidual scripts, each responsible for processing a user request and framework generating a response. Links pass control from one script to the provides a uniform, next. This imposes a go-to hardwiring of the control flow because pure object-oriented P each page must know what comes next. Although developers have view for Web long considered go-to statements harmful,1 they are still present in today’s applications. mainstream frameworks, and they hamper the reuse of pages in different parts Exploiting ’s of the application. Another issue with Web ap- approaches provide mechanisms to model con- plication frameworks is the limited support trol flow over several pages with one piece of reflective features, they provide for composing multiple parts on code.3–5 WebObjects, , Google Seaside reintroduces the same page. The client-server relationship’s Web Toolkit, and .NET, on the other hand, of- stateless nature requires passing the current fer better abstractions by composing an appli- procedure call state back and forth between browser and cation from components, but they fail to model abstraction in server, inevitably leading to undesired coupling control flow at a high level. With any solution, between these parts. combining multiple simultaneous flows inside a client-server Recent frameworks have the same page is difficult. context. tackled both of these problems. JWIG ( In this article, after briefly discussing the key Extensions for High-Level Web Service Devel- challenges of modern Web application develop- opment),2 RIFE (Full-Stack Open Source Java ment, we present Seaside (www.seaside.st), a Web Application Framework), Jakarta Struts, highly dynamic framework for developing Web and JBoss SEAM (Web 2.0 Application Frame- applications in Smalltalk. By exploiting Small- work) solutions model control flow explicitly. talk’s dynamic nature and reflective capabili- However, most of these approaches don’t inte- ties, Seaside offers a unique way to have multi- grate well with the rest of the code, because it’s ple control flows active simultaneously on the necessary to specify the flow in external XML same page. Furthermore, there’s no need to re- page-flow specifications or to use a different compile and restart Seaside application servers . -based after each modification. Web developers can

56 IEEE SOFTWARE Published by the IEEE Computer Society 0740-7459/07/$25.00 © 2007 IEEE debug and update applications on the fly, thus between the client and server to provide the il- reducing development time considerably. lusion of developing a desktop application. Smalltalk’s reflective capabilities make this Web development challenges high abstraction level possible. Smalltalk is a To bring Web application development to uniform language that applies simple princi- the same level as desktop application develop- ples systematically. In Smalltalk, everything is ment, a Web development environment or lan- an object—an instance of a class. Objects ex- guage should offer the following key features: clusively communicate through message pass- First, it should have reusable and compos- ing. In addition, Smalltalk supports closures, able components. A Web application logically anonymous functions that can be passed contains reusable components—input forms, around, stored in variables, or executed at a sortable reports, and so on. Building applica- later time. tions from reusable parts is natural. In addition, Smalltalk is written in itself and offers pow- these components should define their own con- erful reflective capabilities: structural as well trol flow. Composing new components out of as behavioral reflection.7 We limit our brief several other components, each having a differ- overview to the reflective capabilities that en- ent flow, should be easy to achieve. able creating a powerful Web development Second, it needs to produce valid XHTML. framework that offers multiple control flow Producing valid XHTML code and connecting composition, hot debugging, and hot recompi- it to the application logic is difficult, especially if lation. The reflective features of Smalltalk are the XHTML code and application logic must be comparable to those of the Ob- developed in different environments. Template- ject System (CLOS),8 except that Smalltalk of- based XHTML generation lacks the host lan- fers full access to the execution stack. These guage’s power and expressiveness. Seamless in- features include the following: tegration of development tools is often missing. Third, it should enable hot debugging. Effi- I Shape and class changing. Objects are in- ciently identifying bugs is a major challenge for stances of classes. When the class changes Web developers. Web applications are becom- (that is, when instance variables are added, ing increasingly more complex, and the charac- renamed, or removed), Smalltalk automat- teristics of client-server interaction make de- ically migrates all instances of the class. bugging more complicated, especially because I On-the-fly recompilation. Developers can advanced debugging support is often missing in define and recompile methods on the fly. A today’s mainstream approaches. The ability to changed method’s currently active execu- hot-debug exceptions and use break points tion contexts run to completion using the would speed up productivity considerably. old definition. Once a problem was fixed, the session could re- I Stack reification. In addition to self and sume at the place where it had left off. There super, Smalltalk offers a third pseudovari- should be no need to restart and navigate to the able, thisContext, which represents the problematic part of the application continually. execution stack on demand. For efficiency, Fourth, it should support hot recompilation. Smalltalk reifies the stack (that is, makes it On-the-fly method recompilation—that is, re- an object) only when the pseudovariable is compiling a method while the application is run- used. This object is causally connected to ning—is important because it lets developers up- the stack it represents. Therefore, not only date the code without restarting the session. does this object represent the stack, but any This is especially beneficial for Web develop- change made to the object reflects onto the ment because it avoids time-consuming edit- execution stack itself. Hence, developers compile-run cycles. Hot recompilation is a nec- can manipulate the stack to change the pro- essary requirement for hot-debugging support. gram’s execution. For a more in-depth presentation of these problems, please see our previous work.6 Seaside’s key features Seaside is open source, and many applica- Smalltalk’s reflective capabilities tions have used it since the first version of it Seaside introduces an abstraction layer was released in 2002. Originally written by Avi over the asynchronous interaction protocol Bryant (a consultant at the time, and now

September/October 2007 IEEE SOFTWARE 57 I Programmatic XHTML generation. Fol- TodoFilterView lowing Smalltalk’s principle of treating http:/ / localhost/seaside/todo everything as an object, Seaside provides a TodoApplication very different approach to XHTML gener- To-Do List ation compared to template systems. Sea- What can you do today? side generates XHTML through an object TodoListView Filter: All Completed Pending Due Date layer using pure message sending. Using block closures, Seaside binds action call- Repair and clean the bike 1 February 2007 edit remove backs to components. Read “The ACME Novelty Library” I Multiple simultaneous control flows. Each 15 May 2007 edit remove component can define its own control Buy birthday present 11 June 2007 edit remove flow independently from the other com-

add ponents displayed on the same page. This makes it possible to implement business logic spanning multiple pages as one con- tinuous piece of code. The enabling fea- ture is the concept of , which Figure 1. The to-do harness Smalltalk’s ability to access and application, built from owner of dabbledb.com), Seaside is continually manipulate an execution stack. three different Seaside under active development by a growing com- I Hot debugging, code-editing, and recom- components. munity of contributors, including the third au- pilation. Seaside offers excellent develop- thor of this article. Here, we discuss the key ment support; most notably, it makes the features and characteristics of Seaside and how debugger work seamlessly with Web ap- they address the Web development challenges plication code. Smalltalk enables this that we identified earlier. Because of space lim- through hot recompilation and its treat- itations, we won’t discuss the advanced ment of exceptions as first-class objects, (Asynchronous JavaScript and XML) support which can be inspected and resumed. offered by Seaside (see http://scriptaculous. seasidehosting.st for details). In the remainder Domain-specific language of this article, we use a simple application that for generating XHTML lets users manage a to-do list of pending tasks. Seaside doesn’t keep XHTML code fragments Figure 1 shows the main view, which contains in external files; there is no template system. In- three components. The main component is stead, a high-level interface relieves developers TodoApplication, which consists of the title from checking correct tag nesting and attributes. and two subcomponents. One subcomponent, The Smalltalk block closure syntax defines a do- TodoFilterView, implements filters applied main-specific language (DSL) for XHTML ren- to the list of to-do items that the other sub- dering. Thus, through this dedicated language component, TodoListView, applies. A to-do defined in Smalltalk, Seaside lets developers pro- item consists of a title, a due date, and a com- grammatically generate XHTML code. pletion status. Users can change an item’s sta- tus by selecting its corresponding checkbox. Rendering. When the framework generates a Components are the main building blocks in response, each component visible on the page a Seaside application. A component is an in- invokes its hook method, renderContentOn:, stance of a user-defined subclass of Component so that it can render a representation of itself and defines the look and behavior of a portion on a RendererCanvas instance passed as a of a page. For each request, the session lets the method argument by a convention named . components evaluate their action callbacks and (In Smalltalk, developers can read attributes and render their current visual representation. In ac- local variables by using the name in an expres- tion callbacks, components can define control sion. They can write them by using the := con- flow, for example, to temporarily pass control struct. In a first approximation, messages follow to another component. The following summa- the receiver methodName1: arg1 name2: rizes the three key features of Seaside and iden- arg2 pattern, which is equivalent to the Java tifies the dynamic Smalltalk capabilities that syntax receiver.methodName1Name2(arg1, make them possible: arg2).)

58 IEEE SOFTWARE www.computer.org/software Figure 2 shows a sample rendering of an im- plementation involving the TodoApplication TodoApplication>>renderContentOn: html component. self renderTitleOn: html. The render canvas returns instances of ... XHTML tags, called brushes. In the code given in figure 2, for example, the object returned TodoApplication>>renderTitleOn: html from html div is a brush for the div tag. html div class: ‘title’; with: [ Brushes define the interface to specify attributes html heading and the tag’s contents. Seaside passes the con- level: 1; tents (that is, nested tags or strings) as argu- with: self model title. ments to the with: message. The closures en- html paragraph force the correct nesting of tags. It’s not possible with: ‘What can you do today?’] to forget a closing tag, because the compiler complains about the invalid source code. (a) Strings, such as the title in figure 2, can be passed directly to the render canvas and are

automatically encoded. Because the attributes

Todo List

are set through accessor methods, the frame-

What can you do today?

work ensures the validity of the tag declaration.

Action callbacks. So far, we have discussed only (b) how a component renders itself. But compo- nents can also react to actions triggered by Figure 2. Sample users via action callbacks. Seaside lets users em- col. Application developers need not manually rendering involving ploy closures to define action callbacks on an- fetch submitted parameters from HTTP re- the TodoApplication chors and buttons, as well as on form elements quests or validate and parse these strings with component in Seaside: such as text input fields, check boxes, and select every request. Instead, Seaside automatically (a) the implementation boxes. Execution of these closures is delayed calls the appropriate handlers with real objects and (b) the generated until the user triggers the action. Buttons and as parameters. XHTML. anchors use closures without arguments. Other form fields use closures that expect an argu- Control flow ment that is bound to the current value of the Whenever the user requests a new page by element upon activation. The following code clicking on a link or a button, Seaside executes snippet from the TodoListView class displays an action callback of a component. In this call- an item’s checkbox and lets users check or back, the component can change the application uncheck a to-do item. mode’s state, as we discussed in the previous sec- tion. Moreover, callbacks can serve to define a html checkbox control flow while other components on the submitOnClick; page remain unchanged. Every component can value: anItem done; have its own control flow, which describes the callback: [:value ï sequence in which it is temporarily replaced by anItem done: value]. other components. Control flows in Seaside html span: anItem title need not be linear; developers can mix control statements, loops, method calls, and domain The html checkbox statement returns a code with messages to display components. All checkbox brush, which automatically submits this is possible with plain source code; there is the form when clicked. Furthermore, it sets no need to build complex state machines. the checked Boolean value, depending on the Users can employ the TodoFilterView>> item’s current status. Finally, the action call- due method to set a due-date filter. The back, which executes when the user clicks the TodoFilterView>>due method displays checkbox, expects one argument, a Boolean two calendar components in sequence, letting value, reflecting the item’s new status. users select start and end dates as the range to These kinds of callbacks provide a high ab- filter the items. This method first instantiates straction level over the low-level HTTP proto- and calls a calendar component to let the

September/October 2007 IEEE SOFTWARE 59 TodoFilterView>>due Call. One component can pass control to an- other component. Thus, the latter temporarily ï start end ï replaces the former. The developer achieves start := self call: (Calendar new this by sending the call: message to the old addMessage: ‘Select Start Date’). component with the new component as the ar- end := self call: (Calendar new gument. In figure 4, sending the call: canSelectBlock: [:date ï date > start]; method with an instance of a calendar compo- addMessage: ‘Select End Date’). nent installs this calendar atop the filter com- self filter: [:item ï ponent and passes it control. Other compo- item due between: start and: end] nents elsewhere on that page remain functional and can be used independently of Figure 3. Using the TodoFilterView>>due method to set a due-date the new component. filter in Seaside. Answer. A component can return control to the component from which it was called by using Server code Components in browser the answer: method. When returning, a component can additionally return an object Filter>>due to the caller. In figure 4, the expression self := self call: Calendar Filter d printString answer: aDate makes the calendar component return a date object to the filter component.

Calendar>>select: aDate Calendar Composing components self answer: aDate A user interface is built mostly from differ- ent parts visible on the same screen, as our ex- Filter>>due ample illustrates. Seaside implements these d := self call: Calendar Filter parts as components that can be composed d printString -> 11.05.2007 from other components. The following code describes how the to-do application’s top-level component plugs together the filter and the to- Figure 4. The basic elements of control flow in Seaside: the call: do list. Seaside stores the two components in and answer: methods. instance variables of the TodoApplication component instance and places them inside user select a start date. When selected, this XHTML div elements to be rendered one af- date is returned and stored in the start local ter another. The title displays above the two variable. Because start is a date object, de- components. velopers can employ it right away in the sec- ond calendar component to ensure that the TodoApplication>> end date is after the start date. Eventually, in renderContentOn: html the method’s last line, a closure referencing the self renderTitleOn: html. start and end dates defines a filter. This closure html div then serves to filter the to-do items, as shown class: ‘filter’; in figure 3. with: filterView. As figure 3 shows, there is no need to seri- html div alize states into strings and pass information class: ‘list’; from one page to another. Temporary vari- with: listView ables serve to keep track of the state between the different steps of the flow. Control flows in Earlier, we illustrated a control flow of the Seaside are based on the interplay between the filter component, and the selection of start call: and answer: methods, as figure 4 and end dates. The list view component, how- shows. The framed Calendar in the due ever, also defines several control flows—for method is an instance of a Seaside component. example, a confirmation dialog box displayed Seaside invokes the select: method in Cal- when the user is about to delete a to-do item, endar from an action callback—that is, when and dialog boxes for adding or editing items. the user confirms the date selection. Without additional changes to the code, both

60 IEEE SOFTWARE www.computer.org/software Figure 5. Multiple flows on the same page in the to-do application user interface. The user can interact freely with different components ... and their flows.

components can have simultaneously active raised exception in an instance variable, and control flows. later open a debugger for this exception if the Figure 5 shows this process in the Web developer so desires. The developer can then browser, presenting four states of the to-do ap- fix the problem within the integrated develop- plication user interface. First the user decides to ment environment and resume the application define a filter on the items. Then the user decides at the point where he left off. This feature to remove the first to-do item and clicks on re- makes debugging Web applications very pow- move, which displays a confirmation dialog erful. Recompiling and restarting the Web box. Now there are two flows simultaneously server isn’t necessary. The developer can go active, and the user can continue with either right back to the questionable page to see if he one. In the example, the user selects the start fixed the error correctly and then resume the date and, hence, sees the end date calendar next. testing session.

Implementation points Stack reification for call and answer Seaside inherits most of its dynamic capabil- Seaside implements a call-and-answer mech- ities directly from Smalltalk’s strong reflective anism using continuations, which are im- capabilities. Here, we discuss the key imple- mutable representations of the execution stack mentation points that enable Seaside debugging at a certain point in time. A continuation is ba- support and the call-answer protocol. sically a suspended process that is resumable from the stored state several times. The follow- Hot debugging and recompilation ing Seaside code excerpt shows a slightly sim- Most of today’s Web frameworks provide plified implementation of this call-and-answer only weak support for Web application debug- mechanism: ging. Typically, only a line number and a stack trace results from an unhandled exception. Fix- Component>>call: aComponent ing and finding bugs is tedious and often re- ^ Continuation currentDo: quires introducing log statements to gather ad- [:continuation ï ditional data points. self replaceWith: Seaside adopts Smalltalk’s philosophy of aComponent. incremental programming in an interactive en- aComponent onAnswer: vironment. Developers can add or edit code [:result ï while the Web application is running. This aComponent greatly eases development. Figure 6 illustrates replaceWith: self. Seaside’s debugging process—in this case, fix- continuation ing an array index out-of-bounds bug without value:result]. restarting the application. WARenderNotification Smalltalk exceptions are first-class objects raiseSignal] that reference the original execution context from which they were raised. Exceptions are Calling a component—that is, invoking the not unwound until they are properly handled. call: method with an instance of a compo- Therefore, Seaside can remember an earlier nent—captures a continuation and passes it

September/October 2007 IEEE SOFTWARE 61 Figure 6. Debugging a Seaside application: (a) when an unhandled exception occurs, the displays a stack trace with a link called debug; (b) the developer clicks on this link to activate a debugger within the development environment to inspect variables and modify the code on the fly; (c) the debugger now (a) (b) displays the recompiled method, during which the Web browser waits for the server’s response; (d) when the developer clicks on proceed, Seaside resumes processing the request that had caused the error, and the resulting page displays in the Web browser.

(c) (d)

into a closure as the continuation variable. method) and return the result to the caller. This closure replaces the current component, Thanks to Smalltalk’s reflective nature, im- self, with the one passed to the aComponent plementing a continuation in Smalltalk takes method and assigns an event handler to the less than 30 lines of code. A continuation cap- called component, which Seaside will evaluate tures the current execution stack by fetching when sending answer:. The last statement the active context with the thisContext raises an exception, causing Seaside to stop the pseudovariable and then proceeding up the ex- control flow evaluation and redisplay the page ecution stack and copying all the frames. with the new aComponent component in place. When evaluating a continuation later on, This means sending call: to a component will Seaside discards the active execution stack and not immediately return an answer: message to restores and reactivates the captured one by it- the caller after the method executes. erating through the stored stack frames and Later, during a subsequent HTTP request, chaining them together again. As a final step, aComponent might send the answer: mes- the argument passed into the continuation is sage, and Seaside will evaluate the closure de- answered as a return value, making it possible fined as the answer handler. This message to return the answer to the call: statement. swaps back the called component with the Seaside keeps all captured continuations original one and evaluates the continuation within a cache, so using the Back button in the with the answer argument that has been Web browser isn’t a problem. For example, passed to the handler. This causes the con- when defining a filter in the TodoApplica- tinuation to return to the point where it had tion, the user can change the start date after been captured (that is, to the top of the call: setting it by pressing the Back button until the

62 IEEE SOFTWARE www.computer.org/software dialog box for choosing the start date reap- About the Authors pears. Because it’s possible to invoke continu- ations multiple times, the send message to the Stéphane Ducasse is a full professor in LISTIC (Laboratoire d’Informatique, Systèmes, call: method returns a second time, but now Traitement de l’Information et de la Connaissance) at Université de Savoie, where he leads the Language and Software Evolution Group. He is also the president of the European Small- with a different start date, and the flow con- talk User Group. His research interests include dynamic languages, reflective systems, re- tinues from there on. engineering of object-oriented applications, program visualization, and maintenance. Du- casse received his PhD in computer science from the University of Nice-Sophia Antipolis. Contact him at [email protected]. easide provides a high-level abstraction for implementing Web applications, Adrian Lienhard is a doctoral candidate in computer science at the University of Bern which alleviates developers from deal- and cofounder of netstyle.ch, a startup company specializing in business Web application de- S velopment. His research interests include reengineering of object-oriented systems, dynamic ing with the page-oriented client-server interac- languages, language design, and Web applications. He received his MSc in computer science tion model imposed by HTTP. Seaside lets de- from the University of Bern. Contact him at [email protected]. velopers build applications as interacting components that are freely composable, and ex- presses an application’s control flow as plain

method invocations without requiring special Lukas Renggli is a doctoral candidate in computer science at the University of Bern. facilities such as state machines or configura- He is also a core developer of Seaside and is an independent software consultant. His re- tion files. The dynamic and reflective capabili- search interests include programming languages, software engineering, software design, metaprogramming, and Web application development. He received his MSc in computer sci- ties of Smalltalk are enabling factors for the ence from the University of Bern. Contact him at [email protected]. Seaside core as well as for Seaside-enabled de- velopment tools. Seaside has been successfully adopted by various commercial and open source Web ap- plication projects during the past five years. A lively community is constantly improving Sea- side—for example, with a seamless interface for AJAX-enabled applications. More re- IEEE Pervasive cently, Seaside was adopted by other Smalltalk platforms—among them, commercial vendors Computing such as Cincom Smalltalk and . delivers the latest peer-reviewed develop- References ments in pervasive, mobile, and ubiquitous 1. E.W. Dijkstra, “Go To Statement Considered Harmful,” computing to developers, researchers, and Comm. ACM, vol. 11, no. 3, 1968, pp. 147–148. 2. A.S. Christensen, A. Moller, and M.I. Schwartzbach, educators who want to keep abreast of “Extending Java for High-Level Web Service Construc- rapid technology change. With content tion,” ACM Trans. Programming Languages and Sys- tems, vol. 25, no. 6, 2003, pp. 814–875. that’s accessible and useful today, this 3. C. Queinnec, “The Influence of Browsers on Evaluators publication acts as a for progress in or, Continuations to Program Web Servers,” Proc. ACM SIGPLAN Int’l Conf. Functional Programming, this emerging field, bringing together the ACM Press, 2000, pp. 23–33. leading experts in such areas as 4. P. Graunke et al., “Programming the Web with High- Level Programming Languages,” Proc. European Symp. Hardware technologies Programming (ESOP 01), LNCS 2028, Springer, 2001, • pp. 122–136. • Software infrastructure 5. C. Queinnec, “Inverting Back the Inversion of Control or, Continuations Versus Page-Centric Programming,” • Sensing and interaction with the SIGPLAN Notices, vol. 38, no. 2, 2003, pp. 57–64. physical world 6. S. Ducasse, A. Lienhard, and L. Renggli, “Seaside—A Multiple Control Flow Web Application Framework,” • Graceful integration of human users Proc. 12th Int’l Smalltalk Conf. (ISC 04), European Subscribe Smalltalk User Group, 2004, pp. 231–257; www.iam. • Systems considerations, including unibe.ch/~scg/Archive/Papers/Duca04eSeaside.pdf. Now! 7. F. Rivard, “Smalltalk: A Reflective Language,” Proc. scalability, security, and privacy Reflection Conf., Xerox, 1996, pp. 21–38; www2.. com/csl/groups/sda/projects/reflection96/docs/rivard/ rivard.html. 8. G. Kiczales, J. des Rivières, and D.G. Bobrow, The Art VISIT www.computer.org/pervasive of the Metaobject Protocol, MIT Press, 1991.

September/October 2007 IEEE SOFTWARE 63