Monday, November 13, 2006

Inria's Hop

I finally got to read both technical papers on Hop (found in Hop Home page), and I can now make a reasonable comparison between their approach and Termite's.

First let's describe Hop's in a few sentences. Being aimed at Web applications development, Hop is mainly a programming language that separates the application logic from the interface definition, while maintaining a single coding artifact for the application. The language is built upon Bigloo Scheme, so that servers may import several useful libraries. The core features of Hop are:

  • server services - defined just like a regular function, with the macro 'define-service', can do basically anything on the server.
  • interface - created with macros that resemble the HTML tags, interfaces are a declaratively constructed HTML tree. They can contain scripts with Scheme code of two different natures:

    • Client-side code, translated automatically from to JavaScript;
    • Server-side code, mixed within client-side scripts but prefixed with a special character. This code is translated to the appropriate asynchronous server calls, and every exchanged object is automatically mangled/de-mangled (JSON can be used to read server responses on the client).
One of the things that pops out when you see a Hop application is it's elegance, as everything is written in a single file using the same programming language, despite addressing the two important application "strata" (server logic and user interface). The continuous bidirectional communication (and data exchange) between the client and servers is accomplished via asynchronous remote function calls to the server and by setting events on the client that are triggered upon a server's reply - enabling both push and pull communication models.

Another interesting fact is the execution model Hop uses. It is based on several engines running for a single application: One for the UI processing, and other(s) to the application logic. The URL start-point loads the UI engine, and henceforth it is responsible for calling other engines as other functionality is needed.

But Hop isn't perfect. Let's take a closer look at the service model. As it is, Hop creates an URL for each server call needed in the UI strata. Each URL is stored in a server-side table, that is never cleansed - even temporary URL's used for anonymous services are kept indefinitely. This could be resolved (as the authors briefly point out) by exchanging closures (both the server function identifier and all the necessary variables in the environment) with the client.

By now, we can understand another weakness of Hop. Hop uses SCM2JS, which translates Scheme code into JavaScript and allows both languages to work seamlessly within the same memory space. However, as technically close as the languages may be, the translation fails in some key aspects, such as the Scheme support for continuations. The authors state that this could be done whether by the use of trampolines or by the translation into Continuation Passing Style (as specified by Henry Baker's paper), but would always create performance penalties. However, with support for continuations, Hop could easily get all Termite's mobile code functionality, like replication or execution migration between processes.

In my opinion, even if Hop can do such code migration with continuations, it's still weaker than Termite, as it's goals are (currently) too low. They want to build simple Web applications based on interactive operations. They wouldn't be able to build a peer-to-peer application with a Web Interface using code migration between clients, as the concept of client is mangled in the Scheme code as being the UI strata. Termite's approach, on the other hand, clearly considers processes, and that seems to make sense to me, as both clients and servers can currently play the same roles, with bidirectional client-server communication.

Before I wrap-up this Hop analysis, it's relevant to point out other weaknesses of the SCM2JS:

  • exact Scheme numbers are currently mapped to floating-point JavaScript numbers;
  • Errors in Scheme are not necessarily errors in JavaScript, as the translation leaves erroneous Scheme code in executable JavaScript code (like the concatenation of two objects, (+ "a" 2) is translated to "a"+2, which yields "a2" and not an error);
  • features like call/cc and eval constructs are not translatable, yet.

I hope Hop evolves into a great tool. Also, Bigloo Scheme, as well as Hop, need to be executable on Windows boxes, to gain the deserved popularity!