WWW5 Fifth International World Wide Web Conference
May 6-10, 1996, Paris, France


Distributed Active Objects

Marc H. Brown
DEC Systems Research Center
130 Lytton Ave.
Palo Alto, CA 94301
415 853-2152 (tel)
415 853-2104 (fax)
mhb@pa.dec.com

Marc A. Najork
DEC Systems Research Center
130 Lytton Ave.
Palo Alto, CA 94301
415 853-2153 (tel)
415 853-2104 (fax)
najork@pa.dec.com

Abstract

Most Web browsers now offer some form of active objects, written in a variety of languages, and the number and types of active objects are growing daily in interesting and innovative ways. This paper describes our work on Oblets, active objects that are distributed over multiple machines. The high-level support for distributed active objects provided by Oblets makes it easy to write groupware, collaborative applications, and distributed multi-player games.

Overview

One of the most exciting recent developments in Web-browser technology is active objects, where the browser downloads a program, executes it, and displays the output in a Web page. Sun's HotJava browser with Java applets pioneered active objects, showing Web pages with a wide range of objects, from bouncing balls to spreadsheets to simulated science experiments. Most browsers now offer some form of active objects, written in a variety of languages, including Tcl/Tk, Python, Oberon, Self, and Java.

All of these browsers support mobile code, that is, textual or bytecode representations of programs that the browser downloads and runs. This paper describes a system we have built with the extra feature of support for distributed computation, where the computation can span machines across the Internet. High-level support for distributed computation makes it easy to write groupware, CSCW applications, and distributed multi-player games as active objects.

Our environment for writing distributed active objects is based on Obliq [Cardelli95], an objected-oriented scripting language that was specifically designed for constructing distributed applications in a heterogeneous environment. We call active objects written in Obliq "Oblets" (Obliq applets). We have also built a family of Web browsers (DeckScape [Brown94], WebCard [Brown95], and WebScape) capable of running Oblets.

Obliq supports distributed computation by implementing all objects as network objects [Birrell93]. The methods of a network object can be invoked by other processes, in addition to the process that created the object. The process that invokes a method does not need to know if the object is local or remote. Thus, from a programmer's perspective, there is no difference between local and remote objects. The initial connection between two processes occurs when one process registers an object with a name server under a unique name, and another process subsequently imports the object from the name server. Once the connection is established, network objects can be passed to other processes just as simply as passing any other type of data.

Network object method calls have the same syntax regardless of whether an object resides in the same address space as the caller, or in a different address space, either on the same machine or on some other (possibly different type of) machine. As a result, network objects provide a uniform way for communication among Oblets, regardless of whether the Oblets are on the same Web page or on different Web pages displayed by different browsers on different machines. Moreover, network objects communicate directly, without server intervention. Thus, Oblets do not impose any load on an http server, nor does a heavily-loaded server affect their performance.

The rest of this paper consists of four sections with increasingly complex examples, followed by a review of related work. The first section demonstrates the fundamentals of simple, non-distributed Oblets; the second shows how to build a simple distributed Oblet; the third shows a "chat room" that allows an arbitrary number of clients to participate; and the fourth shows an Oblet for algorithm animation that illustrates how to synchronize multiple views of an animation.

A Simple Oblet

An Oblet is an Obliq program that defines a variable named oblet. This variable must contain an Obliq object with at least two fields: vbt and run. The vbt field is bound to a widget that will be installed on the screen when the page containing the Oblet is loaded. The run field is bound to a method that is invoked just after the vbt field is evaluated.

Oblets are placed into HTML documents via insert, an HTML tag proposed by W3C for inserting multimedia objects into HTML3 pages [HTML3]. The markup for putting the Oblet at URL foo.obl into a document is:


    <insert code="foo.obl" type="application/x-oblet"> </insert>
The insert tag also supports a variety of standard attributes, such as suggested dimensions, border size, and alignment. If suggested dimensions are not specified, the preferred dimensions of the widget contained in the Oblet's vbt field are used. The following screen dump (Figure 1) shows a simple Oblet for adding two numbers:

Figure 1: A Simple Oblet for Adding Two Numbers

The user interface for the Oblet, defined by a FormsVBT s-expression [Avrahami89], is stored in the file adder.fv:

        
    (Rim (Pen 20)
      (HBox 
        (Numeric %num1) "+" (Numeric %num2) "=" (Text %sum "0")))
    

A user interface in FormsVBT is a hierarchical arrangement of components. These include passive visual elements (e.g., Text), basic interactors (e.g., Numeric), modifiers that add interactive behavior to other components (e.g., Button), and layout operators that organize other components geometrically (e.g., HBox). Components can be further categorized as a split, filter, or leaf, based on the number of children components they support. A split can have any number of children (e.g., HBox), a filter has exactly one child (e.g., Rim), and a leaf has no children (e.g., Text).

A component in FormsVBT can be given a name so that its attributes can be queried and modified at runtime. Names are also used for attaching callback procedures to interactors. In this Oblet, the two Numeric components have been given the names num1 and num2, and the Text component where the sum will be displayed is named sum.

The source for this Oblet is as follows:

    
    let doAdd = 
      proc (fv)
        let n1 = form_getInt (fv, "num1");
        let n2 = form_getInt (fv, "num2");
        form_putText (fv, "sum", fmt_int (n1+n2))
      end;


    let oblet = {
      vbt => form_fromURL (BaseURL & "adder.fv"),

      run => 
        meth (self) 
          form_attach (self.vbt, "num1", doAdd);
          form_attach (self.vbt, "num2", doAdd);
        end
    };
    
This Obliq program defines two variables: doAdd and oblet. Variable doAdd is a procedure that retrieves the values of both numeric interactors, and stores their sum in the component named sum.

Variable oblet is an object with two fields, vbt and run. The vbt field is bound to a "form", a widget that displays a FormsVBT s-expression. The procedure form_fromURL takes a URL as an argument and returns a widget whose description is stored at this URL. The run method in this Oblet just attaches the callback procedure doAdd to the two numeric interactors. This procedure will be invoked whenever the user clicks on the plus or minus buttons of either interactor, or types a number into the editing field between the buttons. The form in which the event occurred is passed as an argument to the callback procedure. Recall that when the Web page containing this Oblet is loaded, the vbt field will be evaluated and the result displayed on the Web page, the run method will be invoked, and finally the page will become visible.

A Distributed Game Oblet

This section describes an Oblet for playing Tic-Tac-Toe. We'll first develop a single-site game; then, we'll show how to extend this game to two sites. The following screen dumps (Figure 2) show the first three moves in the single-site game:

Figure 2: First Three Moves in the Single-Site Game
The FormsVBT description for this Oblet contains a message line, a game grid, and a button. The message line at the top, named status, indicates whose turn it is. The game grid consists of nine squares; each square consists of a button and a text. The buttons are named btn1, ..., btn9, and the text components are named lab1, ..., lab9. The button at the bottom of the board, named reset, is used to clear the squares of the game grid. Finally, the top-level component of this form has the name board.

The code for the Oblet is as follows:

    
    let otherPlayer =
      proc (p) if p is "X" then "O" else "X" end; end;
   
    let oblet = {
      vbt      => form_fromURL (BaseURL & "tic-tac-toe.fv"),
      c        => ok,
      reset    => meth (self) ... end,
      move     => meth (self, label, player) ... end,
      nextTurn => meth (self) ... end,
      run      => 
        meth (self)
          self.c := "X";

          let doReset = proc(fv)
            self.reset ();
          end;

          let doPress = proc (m) 
            let label = "lab" & fmt_int(m);
            if form_getText (self.vbt, label) is "" then
              self.move (label, self.c);
              self.nextTurn ();
            end;
          end;
        
          form_attach (self.vbt, "reset", doReset);
          for i = 1 to 9 do
            form_attach (self.vbt, "btn" & fmt_int(i), proc(fv) doPress (i) end)
          end;
        end
    };
    
This Oblet, in addition to the required vbt field and run method, also has a field c, and methods reset, move, and nextTurn, which will be fleshed out later. The field c will be a string indicating the player about to move, either "X" or "O". The reset method clears the label displayed in each square of the game grid. The move method puts the string player into the text component whose name is label (e.g., lab4 is the center square), and also updates the message line at the top to indicate whose turn is next. The nextTurn method changes whose turn it is, that is, it changes the value of the field c.

The body of the run method initializes field c, and then attaches callback procedures to the various interactors on the board. Procedure doReset is attached to the reset button at the bottom, and an anonymous procedure is attached to each of the nine buttons, btn1, ..., btn9. The anonymous procedure effectively captures the value of i, the index of each square on the board. When this anonymous callback procedure is invoked (in response to a user clicking a square of the board), it calls procedure doPress(i).

Procedure doReset invokes the reset method of the object oblet. Procedure doPress checks that the square of the grid is empty, and if so, invokes the Oblet's move and nextTurn methods.

Finally, here are the bodies of the methods reset, move, and nextTurn:

    
    reset => 
      meth (self)
        for i = 1 to 9 do 
          form_putText (self.vbt, "lab" & fmt_int(i), "");
        end;
      end,

    move =>
      meth (self, label, player)
        form_putText (self.vbt, label, player);
        form_putText (self.vbt, "status", otherPlayer(player) & "  is next");
      end,

    nextTurn =>
      meth (self) 
        self.c := otherPlayer(self.c);
      end,
    
The last two methods use the procedure otherPlayer, which takes one player's symbol and returns his opponent's symbol.

We now convert the single-site version of tic-tac-toe into a two-site, distributed version. Figure 3 shows a snapshot of a game in progress. The left image shows the browser (WebScape) used by player "O", the right image shows the browser (DeckScape) used by player "X". The message line at the top of the game boards indicates that player "X" is next, and the game board of player "O" is greyed out, indicating that is is non-responsive for the time being.


Figure 3: Distributed Tic-Tac-Toe
The changes to the Oblet code are remarkably simple. First, we extend the oblet to include an extra field, opp, which is the oblet of the opponent. Second, we use the field c in a slightly different way: in the single-site version, c indicated whose turn it was; in the two-site version, it indicates the player in whose browser the Oblet runs. Finally, there are changes to the nextTurn and run methods. Here is the entire Oblet, with unchanged parts elided:
    
    let otherPlayer = ...;
    let oblet = {
      vbt      => form_fromURL (BaseURL & "tic-tac-toe.fv"),
      c        => ok,
      opp      => ok,
      reset    => meth (self) ... end,
      move     => meth (self, label, player) ... end,
 
      nextTurn =>
        meth (self) 
          if form_getReactivity(self.vbt, "board") is "active" then
            form_putReactivity(self.vbt, "board", "dormant");
          else
            form_putReactivity(self.vbt, "board", "active");
          end;
        end,

      run => 
        meth (self)
          try
            self.opp := net_import ("TicTacToe", "ash.pa.dec.com");
            self.opp.opp := self;
            self.c := "X";
          except net_failure => 
            net_export ("TicTacToe", "ash.pa.dec.com", self);
            form_putReactivity (self.vbt, "board", "dormant");
            self.c := "O";
          end;

          let doReset = 
            proc(fv)
              self.reset ();
              self.opp.reset ();
            end;

          let doPress = 
            proc (m) 
              let label = "lab" & fmt_int(m);
              if form_getText (self.vbt, label) is "" then
                self.move (label, self.c);
                self.opp.move (label, self.c);
                self.nextTurn ();
                self.opp.nextTurn ();
              end;
            end;

          form_attach (self.vbt, "reset", doReset);
          for i = 1 to 9 do
            form_attach (self.vbt, "btn" & fmt_int(i), proc(fv) doPress (i) end)
          end;
        end
    };
    
The first part of the run method attempts to import an object called "TicTacToe" from the name server at machine "ash.pa.dec.com". This call succeeds if there already is a player waiting for a game to begin. In this case, the opponent's oblet is stored in our opp field, our oblet is stored in our opponent's opp field, and we choose "X" to be our symbol. If the attempt to import "TicTacToe" fails, then we export our oblet to the name server at "ash.pa.dec.com", make our game board dormant (i.e., grayed-out and unresponsive to mouse activity), and choose "O" as our symbol.

The change to the doReset callback is simple: we invoke the reset method not only on our oblet, but also on our opponent's oblet. The change to the doPress callback is similar: rather than invoking move and nextTurn only on our oblet, we also invoke these methods on our opponent's oblet. The rest of the run method is unchanged: callbacks are attached to the interactors.

The final change in the Oblet is to the nextTurn method. In the single-site version, we changed the value of field c from "X" to "O" and vice versa. Here, we change the reactivity of the game board, from active to dormant and vice versa. This way, each player can only press a button when it is his turn to move.

It is worth emphasizing that self.opp denotes an object that resides on the opponent's machine. This implies that the assignment to self.opp.opp and the execution of the self.opp.reset, self.opp.move, and self.opp.nextTurn method calls take place on this other machine.

A Distributed Chat Room Oblet

Oblets are flexible enough to allow distributed computations to have arbitrary topologies. In the Tic-Tac-Toe example, we had two oblet objects performing peer-to-peer communication with each other. In this example, we use a star topology to implement a multi-person "chat room". At the center of the star, we have a "conference manager" object; at the periphery are the Oblets belonging to the participants. When a user types into his chat room Oblet, it informs the conference manager of the new text, which then relays the update to all the participating Oblets. Our chat room also provides a mechanism for floor control.

The following three images (Figure 4) show the "chat room" running in different browsers (WebScape, WebCard, and DeckScape, from left to right). Each browser is running on a different machine. The participants in the chat room are Moe, Larry, and Curly (from left to right). Currently the floor is with Moe, as indicated by the status line over the editing area and by the color of the editing area in Moe's browser.


Figure 4: Chat Room Running in Different Browsers
Here is the FormsVBT s-expression for the chat room Oblet:
    
    (Rim (Pen 10)
      (VBox
        (Text %floorWith "The floor is free right now")
        (Glue 10)
        (Shape (Width 300) (Height 200)
          (Frame Lowered 
             (Filter Passive 
               (TextEdit (BgColor "White") %mainEditor))))
        (Glue 10)
        (HBox
          (Text "Your Name:")
          (Frame Lowered (TypeIn (BgColor "White") %myName))
          Fill
          (Button %grabFloor "Grab Floor"))))
    
The floorWith Text component is the banner above the large text region; it will contain a message indicating who owns the floor. The mainEditor is the large (300x200) text region. The Filter component surrounding the region is used to set the reactivity of the region; "Passive" means that the area is unresponsive to mouse and keyboard activity, but it is not grayed-out (as it would be in the "Dormant" state). The type-in field where each participant identifies himself is named myName. Finally, the "Grab Floor" button has been given the name grabFloor.

As we shall see, callback procedures will be attached to the "Grab Floor" button and to the large text region. When the user clicks on the "Grab Floor" button, the banner on all participating Oblets will indicate who owns the floor (the contents of the type-in field), and the text region on all Oblets (other than the one owning the floor) will become passive. The text region in the Oblet owning the floor with become active and its color will change to pink. When the user who owns the floor types a keystroke into the text region, all of the participating Oblets will be notified of the updated text.

As mentioned, in this example, Oblets do not communicate with other Oblets directly. Rather, they use a "conference control" object to report the changes, and this object then relays the changes to the other Oblets. Here is the definition of the "conference control" object:

    
    let ProtoConfControl = {
      oblets => [],
      onFloor => ok,
      contents => "",
    
      register => 
        meth (self, oblet)
          self.oblets := self.oblets @ [oblet];
          oblet.updateText (self.contents);
          if self.onFloor isnot ok then
            oblet.transferFloor (self.onFloor);
          end;
        end,
            
      transferFloor => 
        meth (self, name)
          self.onFloor := name;
          foreach o in self.oblets do
            o.transferFloor (name);
          end;
        end,
            
      updateText =>
        meth (self, contents)
          self.contents := contents;
          foreach o in self.oblets do
            o.updateText (contents);
          end;
        end
    };
    
The oblets data field is an array of the Oblets that have registered themselves with the conference control object. Each element of this array is an oblet that typically resides on a different machine. The onFloor data field is the name of the user who currently has the floor, and the contents data field contains the current contents of the text area. These two fields are needed to initialize the display of a new participant who enters the chat room.

The register method will be called by a new Oblet oblet when it is initialized, as part of its run method. The new Oblet is appended to the oblets array, and then the new Oblet is notified both of the current contents of the text area and of the owner of the floor, if there is one.

The transferFloor method will be called by an Oblet when the user clicks on the "Grab Floor" button. This method stores in onFloor the Oblet that now owns the floor, and then iterates through all of the Oblets in the conference, invoking the transferFloor method on each Oblet to inform it of the new floor owner.

Finally, the updateText method will be called by the Oblet who owns the floor on each keystroke, passing in the current contents of the text area. (Passing just the keystroke is not sufficient, since a single character could result in various editing actions, depending on the editor key bindings used by the Oblet.) The updateText method stores in contents the new contents and then updates all of the Oblets in the conference by invoking the updateText method on each Oblet.

We are now ready to examine the code for the "chat room" Oblet:

    
    let oblet = {
      vbt => form_fromURL (BaseURL & "chatroom.fv"),
    
      transferFloor =>
        meth (self, name)
          form_putReactivity (self.vbt, "mainEditor", "passive");
          form_putColorProp (self.vbt, "mainEditor", "BgColor", color_named("white"));
          form_putText (self.vbt, "floorWith", "The floor is with " & name);
        end,
    
      updateText =>
        meth (self, contents)
          form_putText (self.vbt, "mainEditor", contents);
        end,
    
      run => 
        meth (self) 
          var confControl = ok;
          try 
            confControl := net_import("ConfControl", "ash.pa.dec.com");
          except net_failure => 
            confControl := ProtoConfControl;
            net_export("ConfControl", "ash.pa.dec.com", confControl);
          end;
    
          let doGrabFloor = 
            proc (fv)
              confControl.transferFloor (form_getText (fv, "myName"));
              form_putReactivity (fv, "mainEditor", "active");
              form_putColorProp (fv, "mainEditor", "BgColor", color_named("pink"));
            end;
    
          let doKeyEvent =
            proc (fv)
              confControl.updateText (form_getText (fv, "mainEditor"));
            end;
    
          confControl.register (self);
          form_attach (self.vbt, "grabFloor", doGrabFloor);
          form_attach (self.vbt, "mainEditor", doKeyEvent);
        end
    };
    
The Oblet defines two methods, transferFloor and updateText; as we just saw, these methods will be invoked by the centralized conference control object, in response to a user in an arbitrary Oblet in the chat room grabbing the floor or typing into the text area. These methods are straightforward: the transferFloor method makes the text area passive and sets its background to be white, and then updates the banner. The updateText message changes the contents of the text area.

The Oblet's run method first contacts the name server on the machine "ash.pa.dec.com" to obtain a conference control object registered under the name "ConfControl". If there is such an object, it is stored in the variable confControl. Otherwise, a new conference control object is registered with the name server and also stored in confControl. After defining callback procedures doGrabFloor and doKeyEvent, this Oblet registers itself with the conference controller, and finally attaches the callback procedures to the "Grab Floor" button and the text area.

The doGrabFloor callback procedure invokes the transferFloor method on the confControl object (which then calls the transferFloor method on all Oblets in the chat room, including this one), and then makes its own text area active and colored pink. The doKeyEvent callback procedure simply invokes the updateText method on the confControl object, passing to it the text in the text area.

Again, it is important to point out that invoking a method m on the confControl object is done just by calling confControl.m(), regardless of where the confControl object resides. Because of the way the conference controller is created, it will be a local to one Oblet, and remote to all other Oblets.

There are many features that could be added to the chat room in a fairly straightforward way. For example, it would be nice to be able to prevent another user from taking away the floor, to allow users to leave the chat room, to interactively specify a name server and a chat room, to see existing chat rooms, to handle exceptions that might result from network partitions, and so on. In addition, one can easily imagine more efficient implementations, such as reporting only changes to the text area rather than merely reporting what the updated contents of the text area are after each keystroke.

Oblets for Algorithm Animation

Obliq's network objects provide a uniform and elegant way for objects to communicate, regardless of the machine and address space they exist in. The previous two examples showed the obvious use for network objects: to communicate among objects on different machines. The example in this section exploits the elegance of network objects, rather than their distributed capabilities.

This example uses network objects to synchronize multiple Oblets in the domain of algorithm animation [Brown84]. A typical algorithm animation system has a control panel and a collection of views, each in its own window. The control panel is used for specifying data, starting the algorithm, controlling the animation speed, and so on. In order to animate an algorithm, strategically important points of its code are annotated with procedure calls that generate "interesting events." These events are reported to the algorithm animation system, which in turn forwards them to all interested views. Each view responds to interesting events by updating their displays appropriately.

The following screen dump (Figure 5) shows an animation of first-fit binpacking. The control panel and the views are implemented by separate Oblets.


Figure 5: Animation of First-Fit Binpacking
We use a controller object, as was done in the chat room example, to relay interesting events from the algorithm to the views. For each interesting event there is a corresponding method both in the controller object and in each view. When an interesting event occurs, the algorithm Oblet invokes the corresponding method of the controller, which in turn relays the event to each view. Typically, views react by showing some animation reflecting the changes in the program. In order for the animation in the views to happen simultaneously, the controller forks a thread for each registered view, the thread calls the view's method corresponding to the interesting event, and the controller waits until all of the threads have completed before returning to the algorithm.

For example, when the algorithm is trying to insert a particular weight w into a bin b that already contains a number of weights totaling up to amt, it calls zeus.probe(w,b,amt). The probe method of the controller object zeus is implemented as follows:

    
    let zeus = {
      views => [],
      ...
      probe =>
        meth (self,w,b,amt) 
          let threads = 
            foreach v in self.views map 
              let closure = proc() v.probe(w,b,amt) end;
              thread_fork(closure) 
            end;
          foreach t in threads do 
            thread_join(t) 
          end;
        end;
        ...
    };
    
The image above showed the Oblets for the control panel and each view all on the same Web page. However, there is no need for the Oblets to be located on the same page. In fact, if we put each Oblet on a separate page, the user can dynamically select the set of views (or even have more than one copy of any view) visible. In the following screen dump (Figure 6), the page containing the control panel has links for pages containing the various views. Clicking on such a link brings up a page for the view, which the DeckScape browser can optionally display in a separate window.

Figure 6: Dynamical View Selection
At first blush, it would appear that this example uses networks objects merely for the coding elegance they offer, rather than for any of their distributed aspects. That is, in the two screen dumps above, all of the Oblets exist in the same address space, namely that of the browser. However, because Oblets are network objects, we have far more flexibility. For instance, we can use this animation - without any changes - in an Electronic Classroom setting. In such a setting, the instructor and all students run Deckscape each on their own machine (using the same name server). The instructor uses the control page oblet to drive the animation, and each student sees a set of views portraying the workings of the algorithm.

Related Work

Oblets bring together active objects and distributed computation. The best known language for active objects is Java [Java]. HotJava was the first browser to support Java applets; in the meantime support for Java applets has been integrated into Netscape Navigator. Most major commercial browser vendors have subsequently announced intended support for Java applets.

The most serious potential competitor to Java-based browsers is probably Microsoft's Internet Explorer, which plans to integrate support for active objects written in Visual Basic (as well as for those written in Java) [Microsoft]. However, the current version of Internet Explorer does not support active objects.

In the research community, a number of browsers have been developed that support other languages for writing active objects. Most of these browsers are written in interpreted languages and support active objects written in the same language. Examples include Hush [vanDoorn95] and SurfIt! [SurfIt!] (both Tcl/Tk), MMM [MMM] (CAML/Tk), and Grail [Grail] (Python).

None of the browsers and active-object languages mentioned above has any high-level support for distributed programming. However, the HORB system [HORB] adds the equivalent of network objects to Java. It consists of a name server and a compiler that creates network object classes based on Java interface specifications. Unlike Obliq, HORB is a first-order language, meaning that only data, but not computations, can be migrated over the network. Also, HORB does not provide distributed garbage collection.

Obliq [Cardelli95] is a lexically-scoped language that supports distributed object-oriented computation. Previously, it has been used as the scripting language of a Visual Basic-like rapid prototyping environment for distributed applications [Bharat94]. It has also been integrated into commercial web browsers such as Mosaic by defining an Obliq MIME type and configuring the browser to use the Obliq interpreter as an external viewer [Bharat95].

Many other distributed languages exist, commercially (e.g., General Magic's Telescript [Telescript]) and in academia (e.g., Orca [Bal92]). However, we are not aware of any such language having been integrated with a Web browser.

Conclusion

The example Oblets shown in this paper have been small, for didactic reasons. However, Obliq is a full-strength programming language with access to a rich set of libraries, including multimedia objects and Web pages. The DeckScape browser below on the left (Figure 7) shows a Virtual TV Oblet; the main screen and each of the buttons show live video streams. The WebScape browser below on the right shows an Oblet that implements the look-and-feel of DeckScape (but uses a different color for the main canvas); within the DeckScape Oblet, we are running the binpacking animation Oblet. This DeckScape Oblet consists of about 500 lines of Obliq code and 200 lines of FormsVBT user-interface specification.

Figure 7: Virtual TV Oblet and Binpacking Oblet Running Inside DeckScape Oblet Running Inside WebScape Oblet
We have not explored the issues of security and fault tolerance, both very important and very real problems. In the area of security, Web browsers should be able to authenticate the origin of an Oblet and to protect the user against malicious Oblets. In the area of fault tolerance, Oblets should be able to gracefully handle disruption of network services and nonavailability of network resources.

Many analysts feel that two of the most important technology themes for the remainder of the decade are the Web and using computers for collaboration. Oblets provide an elegant programming framework for bring groupware, CSCW, and other collaborative applications to the Web.

References

[Avrahami89]
Gideon Avrahami, Kenneth P. Brooks, Marc H. Brown.
A Two-View Approach To Constructing User Interfaces.
Computer Graphics, 23(3):137-146, July 1989.

[Bal92]
H.E.Bal, M.F.Kaashoek, and A.S.Tanenbaum.
Orca: A Language for Parallel Programming of Distributed Systems.
IEEE Transactions on Software Engineering, 18(3):190-205, March 1992.

[Bharat94]
Krishna Bharat and Marc H. Brown.
Building Distributed, Multi-User Applications By Direct Manipulation.
Proc. of the 7th ACM Symposium on User Interface Software and Technology, pages 71-81, November 1994.

[Bharat95]
Krishna Bharat and Luca Cardelli.
Distributed Applications in a Hypermedia Setting.
Proc. of the 1st Intl. Workshop on Hypermedia Design, Montpelier, France, pages 185-192, June 1995.

[Birrell93]
Andrew D. Birrell, Greg Nelson, Susan Owicki, and Edward P. Wobber.
Network Objects.
Proc. of the 14th ACM Symposium on Operating System Principles, pages 217-230, December 1993.

[Brown84]
Marc H. Brown and Robert Sedgwick.
A System for Algorithm Animation.
Computer Graphics, 18(3):177-186, July 1984.

[Brown94]
Marc H. Brown and Robert A. Shillner.
DeckScape: An Experimental Web Browser.
Computer Networks and ISDN Systems, 27(1995) 1097-1104.

[Brown95]
Marc H. Brown.
Browsing the Web with a Mail/News Reader.
Proc. of the 8th ACM Symposium User Interface Software and Technology, pages 197-198, November 1995.

[Cardelli95]
Luca Cardelli.
A Language with Distributed Scope.
Computing Systems, 8(1):27-59, January 1995.

[Grail]
Grail Home Page.
http://monty.cnri.reston.va.us/grail-0.2/

[HTML3]
HTML3 Linking and Embedding Model.
http://www.w3.org/hypertext/WWW/TR/WD-insert-951221.html

[HORB]
HORB Home Page.
http://ring.etl.go.jp/openlab/horb/

[Java]
Java: Programming for the Internet.
http://java.sun.com/

[Microsoft]
Internet Development Toolbox.
http://www.microsoft.com/INTDEV/

[MMM]
MMM Browser Home page.
http://pauillac.inria.fr/~rouaix/mmm/

[SurfIt!]
SurfIt!
http://pastime.anu.edu.au/SurfIt/

[Telescript]
Telescript.
http://www.genmagic.com/Telescript/index.html

[vanDoorn95]
Matthijs van Doorn and Anton Eliëns.
Integrating Applications and the World-Wide Web.
Computer Networks and ISDN Systems, 27(1995) 1105-1110.