EN FR
Homepage Inria website


Section: New Results

Web programming

Participants : Cédric Duminy, Vincent Prunet, Bernard Serpette, Manuel Serrano [correspondant] , Colin Vidal.

Hop.js [20], [22] is a new platform for web applications, potentially involving interconnected servers. The server-side execution is compatible with Node.js. Programmers then benefit from numerous existing libraries and applications. Hop.js also introduces distinctive programming features that are expressed in the HopScript programming language, a multitier extension of JavaScript. The Hop.js runtime embeds a multi-backends HopScript compiler.

The HopScript language extends JavaScript to consistently define the server and client part of a web application. HopScript supports syntactic forms that help creating HTML elements. It supports services that enable function calls over HTTP. Being at higher level than traditional Ajax programming, Hop.js services avoid the burden and pitfalls of URL management and explicit data marshalling. They combine the benefits of a high level RPC mechanism and low level HTTP compatibility.

Hop.js supports server-side and client-side parallelism. On the server, it first relies on its built-in pipelining architecture that automatically decodes HTTP requests in parallel. It also relies on server-side web workers that programs may explicitly launch to perform background tasks (functions and services). Each worker runs its own system thread. The service invocation and execution API fully integrates with the JavaScript execution flow, allowing synchronous and asynchronous operations on both client and server processes. The asynchronous response API can be combined with the worker API, allowing processing and asynchronous service responses to be delegated between workers. On the browser client-side parallelism relies on standard web workers.

Although Hop.js can be used to develop traditional web servers, it is particularly adapted to the development of web applications embedded into devices, where the server and client part of the application are intimately interoperating with each other. The programing model of Hop.js fosters the joint specification of server and client code, and allows the rapid development of web user interfaces, on the client, controlling the execution of the distributed application. By defining a single data model, providing functions that can run indifferently on both sides, and almost forgetting about client-server protocols, Hop.js seems well suited for agile development of web applications for this class of applications.

As an example, Hop.js has already been successfully used as the core framework to develop embedded and cloud applications for connected robots and IoT devices. In the context of a European industrial collaborative project, it has been used by various categories of programmers (mostly undergraduate internships, robotic experts, and professional engineers familiar with web development techniques) to build complex distributed applications, where various sort of digital equipments (computers, robots, small devices) communicate with each other, discover themselves, and collaborate. In all cases we have observed an easy adoption from everyone. The tons of JavaScript resources and examples available on the web helped internship students to rapidly become productive. Robotic experts were instantly able to start implementing Hop.js applications. Web experts seemed to feel at home with Hop.js as it let them build working applications with Hop.js core features and then extend them with existing JavaScript third party modules, typically npm modules.

In 2016, we first version of Hop.js as been completed and released. It is available from the Web site http://hop.inria.fr.

Web Reactive Programming

Web UI interfaces are specified as HTML documents. When instantiated in a browser these documents are accessible from JavaScript as abstract data structures conforming to the Document Object Model (aka the DOM). Modifying these structures, for instance for applying updates, involves fine surgery for isolating the concerned elements and for applying the intended modifications. As these operations are generally triggered after asynchronous events that may come in response to earlier network requests or a user actions, the programming is complex and error prone. Improving on that situation has been the subject of many previous studies that propose alternative models for helping programming Web UI. Our work constitutes yet another contribution to that problem. It differs from the other solutions by the followings.

  • It addresses exclusively the problem of programming the Web UI updates.

  • It does not introduce a new programming model and it is fully compatible with traditional JavaScript programming.

  • On the client, it only requires a very thin implementation layer whose weight is almost unnoticed in a Web browser.

  • It does not impact the rest of the execution, leaving the performances unchanged.

Our proposal consists in introducing a zest of reactive programming used only for denoting the parts of the DOM that need updates. For that, we introduce two new constructs: i) reactive values, called reactors, that have the appearance of any regular JavaScript value, and ii) reactive nodes, which are DOM nodes that are automatically updated upon reactors changes. Reactors and reactive nodes can be used in pure JavaScript programs but that have been designed to complement other facilities Hop.js. To justify their design and to advocate their benefit, we show how they simplify the programming of classical Web patterns. Let us consider a classical example already detailed in the literature, a timer example, which consists in a simple Web page defined by:

var elapsedTime = 0;

 

function doEverySecond() {

   elapsedTime++;

   document.getElementById( "curTime" )

           .innerHTML = elapsedTime; }

 

<html>

  <script>setInterval( doEverySecond, 1000 )</script>

  <button onclick="elapsedTime = 0">reset</button>

  <div id="curTime"></div>

</html>

Although simple and innocuous at first glance, this program suffers from two major problems. First, the lack of modularity. The function doEverySecond , that implements the timer, increments the wall clock and updates the UI (via innterHTML attribute assignment). Hence, it must be aware of all the elements that needs update. This is problematic as a UI may evolve over time with some elements removed and new elements added. Each evolution of the specification will then impact doEverySecond implementation. The second problem we address is the plumbing needed for extracting and modifying the curTime element. In the pure JavaScript this involves assigning and looking up unique identifiers (curTime identifier). The reactors and reactive nodes we propose solve these two problems.

<html> ~{

     const T = hop.reactProxy( { elapsedTime: 0 } );

     setInterval( () => { T.elapsedTime++ }, 1000 );

  }

  <button onclick=~{T.elapsedTime=0}>reset</button>

  <div><react>~{T.elapsedTime}</react></div>

</html>

This Hop.js program solves the two problems previously mentioned. It is modular as new reactive elements depending on the elapsedTime can be added without modifying existing code. It avoids tedious surgery of the HTML DOM as the react node designates the node that need updates and its positioning in the UI.

We have built a first operational prototypes of reactors and reactive nodes. This work will be pursued in 2017. We will complete the implementation in Hop.js by including them in Hop-3.1.0. We will write a scientific paper describing their design and implementation.

Hiphop.js

Modern Web applications are rich in interactions between users and servers. Those interactions are from different nature: search and play music, book train or airplane tickets, query database or use an interactive map. From the programmer point-of-view, those interactions are handled by asynchronous events from multiple sources. Management of those events, which is called orchestration, is done by using event handlers. It is a mechanism that will call a specific function when a specific event raises. This kind of orchestration doesn't scale well since the behavior of the application has to be deduced by the programmer. Synchronous languages like Esterel, which are used in the industrial area, provides syntactic constructs that allow ordering the temporal behavior of the application. Then, reading the program source gives a precise idea of the behavior of the program at runtime.

The HipHop.js contribution is to adapt the reactive constructs of Esterel to the Web. The goal is to design a high-level tool that simplifies the orchestration of Web applications. In the traditional Esterel setting, the reactive program is written in a different source file of the host program. It is compiled independently of the host program. Therefore, the programmer must make explicit bindings between the reactive program and the host program in order to allow both of them to interact. This is inadequate for Web developments. So, HipHop.js adopts a radically different point of view: the reactive program is written in the same source code with the host program and the interaction between the reactive program and the host program is direct, thanks to a JavaScript API which is offered by the compilation output of the reactive program. HipHop.js uses a XML syntax, where each node corresponds to an Esterel instruction. This syntax has pros and cons but we think its advantages dominate. First, it is familiar to all Web developers, which do not have to learn a new syntax. Second, it is overly simple to implement as Hop.js natively supports XML parsing. Third, it gives macros for free as the XML syntax can be mixed with standard JavaScript that can create and return XML objects.

The classical Esterel example of the synchronous community is “ABRO”: a program which is waiting for two events in parallel. When both events are raised, the host program is notified (here it pops a window up). At any moment, the reactive program state can be reset, in which case, the reactive program waits again for both events. For the sake of illustration, we show here how to implement ABRO in HipHop.js inside a Web page:

<html> ~{

     var abro =

         <hh.module A B R O>

           <hh.loopeach R>

             <hh.parallel>

                 <hh.await A/>

                 <hh.await B/>

             </hh.parallel>

             <hh.atom apply=${function() {alert("ABRO")}}/>

           </hh.loopeach>

         </hh.module>

 

     var m = new hh.ReactiveMachine(abro);

  }

  <button onclick=~{m.inputAndReact("A")}>A</button>

  <button onclick=~{m.inputAndReact("B")}>B</button>

  <button onclick=~{m.inputAndReact("R")}>R</button>

</html>

Pushing the buttons “A” and “B” triggers the popup message which contains "ABRO" in the browser page. In spite of its simplicity, the ABRO example is representative of a wide class of real programs. For instance, a program behaviorally similar to ABRO can be used to download a file in several parts of different sources, and merge them when all downloads are completed.

The first HipHop.js version has been released this year. It is available at the following URL http://www-sop.inria.fr/members/Colin.Vidal/hiphop/.

Garbage Collection with non ambiguous roots

Hop uses lot of objets with short time life.

Some Hop programs allocate many temporary objects whose lifetimes are very short. These objects are unefficiently handled by this Mark&Sweep garbage collector that Hop currently uses. We expect a speed-up by switching from a Mark&Sweep garbage collector to a generational Stop&Copy one. Stop&Copy collectors demand that all roots of the accessibility graph have to be precisely known (non ambiguous root). We have changed the code generation of the compiler in order to maintain a precise map of the pointers living in the stack.

Event calculus

We have studied functions over streams of events (timed values) and more precisely those which have a temporal causality property: at every instant, current outputs only depends on inputs that have already been received [24]. We have found a clear characterization of causal functions and made some proofs with the Coq system [21].