Monday, September 7, 2009

Admittedly, I like JavaScript

Call me pervert, but I find writing JavaScript enjoyable. The aspect that I like most about it is its dynamicism. Certainly, the syntax is ugly, but the js2-mode for Emacs makes writing JavaScript much less painful.

My addiction for JavaScript made me accept a project to create an artists' portfolio website that has no commercial value, but gave me lots of opportunity to play around with client-side coding. I decided that I want to put all data into a JSON encoded data structure and use a client-side content management system to edit and update the database. I originally intended to write the required server-side components for the CMS in JavaScript, too, but that idea went down the drain as it made deployment of the whole thing a lot harder. Thus, the server-side components are now reduced to the bare minimum and are written in perl, so that a cheap web host can be used both for deploying both the web site and the CMS.

One common problem with client-side JavaScript is flow control with long-running operations. JavaScript is single threaded, so in order to maintain UI responsiveness, functions may not block waiting for network responses. Thus, whenever a UI wants to interact with the server and then resume operating, things get tricky. There are libraries like jwacs, which is a preprocessor which implements first-class continuations, and Arrows, which is a "generalization of Monads", but these either make debugging hard through the use of a preprocessor or are incomplete.

My approach to the problem is to use closures to manually establish the continuation, and callbacks to invoke these continuations when appropriate. While being dissatisfying in the intellectual sense, the approach works for the applications that I'm using them in.

Sure, I'd rather have macros instead of having to control evaluation through closures. But then, this is still better than any old static language that requires me to cram everything into classes and objects, forcing me to either make all design changes upfront or to use sophisticated refactoring wizardry to get dynamicism on the source code level. Oh well, or maybe I should rather give up on Emacs :)