2006-06-04
Narrative Javascript
Narrative Javascript extends the Javascript language to include a new operator. That operator allows writing procedural looking code that spans asynchronous operations.
Very much like continuations enable writing web applications such that you don't need to break application flow to model the HTTP protocol, Narrative Javascript enables you to write your code in a sequential style and have it automatically produce the callbacks and handlers for events, XMLHttpRequest, etc.
It consists of a compiler that compiles a Javascript plus the new operator into standard Javascript which can be included in the web page.
Narrative JavaScript consists of a compiler and a runtime library. You write your code code as Narrative JavaScript (using the blocking operator) and the compiler will parse and translate the code into regular (asynchronous) JavaScript. You then deploy the compiled code along with a runtime library. To aid in debugging, the compiler keeps line numbering of the source code intact in the compiled code.
An example from the website shows this code:
function startForm() {
displayPage1();
}
function onPage1Submit() {
var errors = validatePage1Input();
if(errors) {
displayPage1(errors);
} else {
displayPage2();
}
}
function onPage2Submit() {
var errors = validatePage2Input();
if(errors) {
displayPage2(errors);
return;
}
var url = buildUrl();
doHttpRequest(url, handleResponse);
}
function handleResponse(r) {
if (r.page1Errors) {
displayPage1(r.page1Errors);
} else if (r.page2Errors) {
displayPage2(r.page2Errors);
} else {
displaySuccess();
}
}
Written in Narrative Javascript as:
function displayForm() {
var page1Errors = [];
var page2Errors = [];
var success = false;
while (!success) {
while (page1Errors) {
page1Errors = displayPage1->(page1Errors);
}
while (page2Errors) {
page2Errors = displayPage2->(page2Errors);
}
var url = buildUrl();
var response = doHttpRequest->(url);
page1Errors = r.page1Errors;
page2Errors = r.page2Errors;
success = !(page1Errors || page2Errors);
}
displaySuccess();
}
Notice the code in the following line:
var response = doHttpRequest->(url);
This does an XMLHttpRequest which usually requires having a callback function process the request. This is done automatically by Narrative Javascript. From the sounds of it it compiles the code into CPS form and uses the continuation as the callback. This enables the code to continue from where it left off. In this case returning the value of the XMLHttpRequest and continuing the function.
Any operation that requires a callback function is a candidate for blocking. Please note that blocking does not mean that the entire JavaScript runtime locks up waiting for an operation to finish. Instead, Narrative JavaScript makes use of co-operative multitasking. When you use the blocking operator, you are yielding control to the JavaScript runtime to execute other operations until your operation has yielded a return value.
This system looks very nice and I look forward to playing with it.