Category Archives: Javascript

Strict mode for Javascript – continued

Seems the prior post gathered some response.

To set expectations – this is my personal weblog. What I put here is the bits that (to my mind) might be otherwise missing. I am not interested in repeating material covered elsewhere. If you are already well-read, then I hope these bits will nudge your thinking forward a bit (even if you do not entirely agree with my conclusions).

On the other had, if you are seriously short of clues, I am not going to help you. Spent enough time on USENET News (long ago) to note the point of diminishing returns. Since I write these bits as an entertainment (of sorts), I am not going to invest a lot of time with folk who are too many laps behind.

Javascript is at heart a dynamic, prototype-based sort of object-oriented language. Most folk coming to Javascript are acquainted with static, class-based languages – and have little or no experience with anything different. The natural inclination is to transfer learned habits from the old to the new language – and that is a mistake.

Back in the late-1980′s or early-1990′s one writer came up with a classification scheme for object-oriented languages. There were many variations proposed and explored in that time, so a scheme that enumerated the important aspects was very useful. (Wish I knew how to find the article – it was in an ACM or IEEE publication of that period, I believe.) As a guess, I suspect that most of the current generation of programmers is not aware of the possible variations, and assume all object-oriented languages must be like Java / C++ / C#, and expect the same learned habits to still make sense with Javascript.

Disregarding the usual noise, there is one bit which it is worth responding, as it (quite unintentionally) illustrates my point.

New gives you prototype inheritance, performance benefits, and it’s about language semantics.

That is exactly my point! … only the reality differs from the assumptions of the guy making the comment (and I suspect he has a lot of company). Back in the late 1980′s / early 1990′s the pragmatic consensus was to move forward with object-oriented languages that could be made to run efficiently on the then-current hardware. How to generate optimal code for static class hierarchies was fairly well understood, at that time. More dynamic object-oriented languages were simply too hard to optimize.

The v8 Javascript engine offers a good example. The combined memory and CPU footprint of an efficient Javascript engine was simply impossible on circa-1990 computers. What is practical and reasonable on current-generation computers was – twenty years back – completely not practical.

My reading of the articles on the current-generation Javascript engines was that the toughest problem – and main aim of implementors – was to optimize in the absence of static-class hierarchies, and that quasi-static classes are not particularly optimized.

This makes sense. Writing script for web pages is programming in the small. The number of entities on a web page is small, as are the number of repeated instances. Static classes with efficient support for huge numbers of behavior-identical instances are essentially useless in a web page. If you are creating large numbers of instances for a web page, you are almost certainly doing it wrong. (Note the “flyweight” class pattern is useful here.)

My assumption (from what I have read) is that “static” class hierarchies yield no particular benefit in client-side Javascript.

Assumptions should be checked … so I wrote a micro-benchmark.

Method dispatch – Microbenchmark – Javascript
The aim was to measure method-dispatch for three cases:

  1. The method is bound to the instance.
  2. The method is bound to the “class” (via the __proto__ member).
  3. The method is bound to the “class” (via the function invoked via new).

What I see (in terms of exact results) will likely vary as each browser vendor tweaks their Javascript engine. The point – in the case of the current discussion – is that static class hierarchies yield no significant advantage. It does make perfect sense that static-class languages can deliver bare-hardware performance numbers (which I do expect to use). For web page script, I expect static-like class usage to yield no significant benefit.

For programmers coming from C++/Java/C#, the notions that made sense no longer apply. Thus the emphasis on denying any semblance to static-class languages. This was exactly my point.

Posted in Javascript, Software | Leave a comment

Strict mode for Javascript

A small item…

Javascript is a hash (pun not entirely intended). There are good parts to Javascript, and bad parts. For folk attempting to learn Javascript for the first time, they could use some help avoiding the icky bits.

My first cut at rules for a “strict” mode for Javascript:

  • No use of “function name(){}” declarations
  • No use of “document.write()”
  • No use of “new”

No doubt I could come up with more rules, with a bit more reflection, but this is a start.

No use of “function name(){}” declarations
There are two means of declaring functions, and I strongly prefer the second form. Programmers coming from other languages tend most often to use this form:

function foo() {
}

For an entire collection of reasons I prefer this form:

var foo = function() {
};

The second form is better suited for later refactoring, and offers subtle emphasis to the learning programmer of the difference offered by Javascript. The first form can also lead to subtle bugs (which I do not want to explain) – certainly not what you need when first learning a rather different language.

As a partial hint, I tend to make rather a lot of use of namespaces, so my function declarations most often look like this:

var ZOT = {};
ZOT.foo = function() {
};

Or in the more elaborate use:

var ZOT = (function() {
    var foo = function() {
    };
    return {
        foo: foo
    };
})();

This last form makes full use of closures, and allows for private data and functions.

No use of “document.write()”
Programmers tend to want to generate HTML from program code. This is a huge mistake.

To me this is a classic application of separation of concerns. HTML describes page structure. CSS describes page presentation. Script describes dynamic behaviors. Best to keep each concern separate.

No use of “new”
On this point I am certain others will differ. They might even be right. Certainly the “new” operator is of huge advantage in static languages. But that is not the domain of Javascript – certainly in the web browser, and possibly even for server-side usage.

The “new” operator misleads programmers when first learning Javascript. The pattern of usage most appropriate to a static-class language is not the same as the most appropriate usage in an entirely dynamic language.

Conflicted over Crockford
There is a measure of irony in the last point. Douglas Crockford has consistently served to promote better usage of Javascript. Crockford was hired by Yahoo. The quite elaborate user interface library in Javascript developed by Yahoo, is first invoked with “new YUI()”. YUI obviously represents a substantial body of work, at least partially in what seems the right direction. Yet I cannot yet quite get past the beginning.

Posted in Javascript, Software | Leave a comment

Almost but not quite … server-side JavaScript

Bit over three years back I looked at server-side Javascript, and was not enthused with the available choices.

Three distinct usages I’d like to cover: optimal performance,Windows web server (IIS) interoperable, and webhosting.

In addition, there are three interesting aspects of optimal performance: throughput, scalability, and stability.

For serving static content, I really like the model of a single-threaded non-blocking web server, of which thttpd was an early example, and for which the C10K question clarified the need. A small/simple web server has a much better chance to being very reliable. With the single-threaded non-blocking model, massive scalability is possible.

For serving dynamic content, I really like the isolation and load distribution possible with the FastCGI model (or the like). Dynamic code tends to be complex. Javascript interpreters are complex. Complex code tends to fail more often. Complex code can use more compute throughput than possible on a single box. For intranet applications, a single front-end web server is often preferable, and load distribution via FastCGI offers more headroom. All of which tends to argue for the FastCGI model, with isolation from the front-end web service, and potential distribution of load across more than one machine.

For the widest possible usage, in additional to optimal deployments (when there is no restriction on the front-end web server), the engine on which the application runs should be deployable behind IIS (for Windows-only organizations), and at common web-hosting services (like Dreamhost). Microsoft’s recent support of FastCGI with IIS is a big help.

At that time (three years back), none of the solutions were really optimal – and in fact were pretty far from optimal. The Java-based RhinoJavascript interpreter was easiest to embed, but failed the webhosting case. The C++ based JavaScript interpreters were a pain to embed, and offered good (but not great) performance.

Fast forward to the present, and Google offers the V8 JavaScript Engine that offers great performance, and is easy to embed. (Google as the good guys, riding to the rescue once again … you’d think they have white hats superglued to their brains.) Suddenly we have lots of projects embedding the V8 engine. In addition, seems most all the single-threaded non-blocking web servers have picked up support for FastCGI.

Oh … and I am pretty much fed up with the Java Servlet model. After considerable time with the problem, I am of the opinion that the servlet model chose the wrong abstractions, and this makes for awkward solutions. (Of course, the servlet model appeared very early in the history of web applications, so the mistake is easy to understand.)

Which means the model offered by node.js makes a lot of sense. I like the notion of a naked node (running JavaScript on the V8 engine) performing request dispatch without any extra layers or abstractions. The main lack with node.js is the ability to work via FastCGI (and thus no means to be deployed behind IIS on Windows).

But there are as yet items unresolved and/or unclear.

  • Projects like v8cgi offer the V8 JavaScript Engine connected via FastCGI.
  • The node.js project offers a single-threaded non-blocking web server … but can it work behind FastCGI?
  • Is the environment for server-side JavaScript the same (or sufficiently similar) between node.js and v8cgi?
  • Comet is still a question. Can FastCGI work well with long-outstanding requests from applications?

The good news is that we seem a lot closer to attractive and well-supported server-side JavaScript for web applications … but it seems we are not quite fully there, as yet.

Posted in Javascript, Software | Leave a comment

Elegant distributed applications

“Elegance is the attribute of being unusually effective and simple”

Heard this first applied to theories in Physics. Any not-over-complicated theory that effectively explained the facts was – as I understood – considered an “elegant” theory. (My original interest – and college degree – was in Physics. I wanted to build starships.)

Came up, long ago, with rules for “elegant” distributed applications. The first significant distributed application I spent time with was the early FileNet system. This was well over twenty years ago. Strong interest in scaling to large (by the standards of the time) deployments, forced careful thought about performance. Pretty much everything I have worked on before and since has had a network in the middle, so I’ve had time and reason to think about the subject. Changing technology does not change the inherent nature of distributed systems, so the relevant set of notions will pretty much always apply.

(What continues to surprise me is that individuals and outfits still get these same bits wrong!)

In the interest of hitting the usual points once….

When building distributed applications, there are some basic principles you should always keep in mind.

Minimize the amount of data crossing the network.
The capacity of the network is always limited. Capacity is large in the usual development setup, when both server and client are on the same segment. In real use the available capacity is almost always less, and sometimes much less.
Minimize the number of round-trips across the network.
Networks always have latency. This has nothing to do with the speed of a network (in terms of bits/second). I have written about this before. For an interactive application the ideal is one round-trip per user action.
Shift computation from the server to the clients, where practical
There are almost always more clients than servers. If you can shift computation to the clients, you will get better overall throughput.

From the above principles, for building web applications you can derive further guidelines.

Code complexity belongs on the server. Code in the client should be simple.
Code to be executed on the client must be shipped across the network. The less you have to ship across the network, the better. If you have an application that calls for code-complexity on the client, you want to ship the code once, and should be looking at solutions like Java WebStart. Otherwise you want to ship as little code as possible across the network. This fits perfectly with the use of compact scripts in the client using Javascript.

The fact that Javascript is interpreted on each and every load (and not compiled) serves only to reinforce this guideline.

Large iterations belong mainly on the server, not the client.
Compiled code is usually much more efficient than interpreted code. The server can (or should) use compiled code. In the case of web applications, the client code is interpreted code.
Large data belongs on the server, not the client.
The (sometimes) narrow network channel, and the relative efficiency of compiled code – both argue for keeping large data on the server.
Use the strengths of the web browser.
Native code is faster than interpreted code. The web browser is smart, and incorporates a large set of behaviors in native code. Use of built-in behaviors can mean smaller Javascript and faster execution.

In the present, Javascript offers an elegant solution to the need for a scripting language in both client and server. Made the mistake(?) of responding to a recent post. Seems that each time something like this comes up, we have an almost fixed set of notions coming back. After a few iterations – just not very interesting.

Some quotes, with names omitted to protect the guilty.

Arrays have no semantics. They are not first-class collections. Do not use them in any public API, regardless of the language you use. Wrap arrays with a public type that exposes semantics.

The semantics of arrays as collections and iterations are simple and perfectly suited for small scripts. For the most part, you do not need anything more. The domain for scripting is small, concise, and hideously flexible code. More elaborate solutions might make sense in large server-side code. Client-side script or structures shipped between client and server should only be as elaborate as is needed – and no more.

You’re right in the sense that JS is “good enough” for most of basic usages, but almost useless for writing bigger software. It’s the reason why there’s been recently a lot of higher level languages that generates JS code. Either Java (GWT) or haXe (http://haxe.org)

You should not be writing large code in Javascript. You must use Javascript in the client (the web browser), but in-browser script should not be large. You should consider Javascript as “glue” code on the server-side – small code, few iterations, with huge flexibility – to allow special-case customization without re-coding. Javascript (as with ELisp in Emacs and AutoLisp in AutoCAD) is a scripting language. You do not want to write the bulk of a large application in Javascript. Large code is a non-goal for a scripting language.

I still dislike JavaScript, and likely always will. It has some pretty fundamental flaws.

Javascript evolved almost as a hack (if not quite). Early versions were less capable. Early examples were uninspired (or worse). The present iteration preserves past mistakes. Ignore the mistakes, and use the good parts. The good parts are … very good, as suits a scripting language.

JavaScript has no place on the server.

Quite the opposite – as the scripting language known to the largest group, and fated to be well-known over a long period – Javascript can serve exceptionally in the role that scripting languages have long met in large, successful applications. Not for large use, but with a valued place. Often when faced with the need to adapt a large application to a specific customer/site needs, there are always cases when a simple list of options is not enough (and rarely-used options serve only to make the application obscure to all customers). There is always a part of the problem space best met by a scripting language deeply integrated with your application.

Historically we have always had a zoo of suitable scripting languages, with insufficient reason to choose between them. In an odd way, the rise of Javascript in the web browser does us a favor, as Javascript is sufficient, and now most widely known of all scripting languages. There are times when a single logical solution is best for all involved.

Javascript is good enough.

Posted in Javascript, Software, Web | Leave a comment

Google’s Chrome: Bet your enterprise on it

Have to credit an article for a bit of insight – though at all not what the author intended.

There is an aspect I had previously missed. The Google Chrome web browser is an excellent platform for company intranet applications.

Lots of companies have internally-used applications. Lots of developer-hours went into those applications, and some of those applications end up being mission critical. The average level of programming talent that went into creating those applications is often less than first rate, and so they tend to be somewhat inefficient, and somewhat unreliable.

Google Chrome is probably the best platform for those not-entirely-performant and not-entirely-reliable internally developed applications. The fast Javascript engine means less efficient applications will run better on Chrome, and isolation of Javascript engines within means less-reliable applications will cause less trouble when run within Chrome.

Is this what the Google-folk expected? My guess is not.

Organizations with a long enough history will almost certainly have had to deal with vendor-forced upgrades that interacted badly with important in-house applications. The fact that Chrome is open source means that companies now have more of a choice – they could choose to opt-out of any changes that disrupt important internal applications.

Google may have accidentally created the ideal platform for large organizations that are looking at deploying internally developed web applications.

Posted in Javascript, Software, Web | Leave a comment

property.import task for Ant

I have Ant build scripts that can be run on either Windows or Linux. There are a few properties that need to be set differently, depending on the platform is use. Been using this little snippet for a while now.

import.js

Array.prototype.map = function(f) {
    var a = [];
    for (var i=0; i<this.length; ++i) {
        a.push(f(this[i],i));
    }
    return a;
};
Array.as = function(v) {
    var a = [];
    for (var i=0; i<v.length; ++i) {
        a.push(v[i]);
    }
    return a;
}

var PROPERTY = (function(){
    var t = {};
    var _get = function(k) {
        return project.getProperty(k);
    };
    t.get = _get;
    t.verbose = function(n) {
        n = 1 * n;
        if (0 < n) {
            t.get = function(k) {
                var v = project.getProperty(k);
                self.log("get " + k + " = " + v);
                return v;
            };
        } else {
            t.get = _get;
        }
    };
    t.low = function(s) { var v = t.get(s); return v && v.toLowerCase(); };
    var os_name = t.low("os.name");
    var user_name = t.low("user.name");
    if (os_name.match(/^windows/)) {
        os_name = "win32";
    }
    t.byUser = function(s) {
        return t.get(s + "." + user_name);
    };
    t.byOS = function(s) {
        return t.get(s + "." + os_name);
    };
    t.byPlatform = function(s) {
        return t.get(s + "." + os_name + "." + user_name);
    };
    t.pick = function() {
        return Array.as(arguments).map(function(k){
            var v = t.get(k) || t.byPlatform(k) || t.byUser(k) || t.byOS(k);
            project.setProperty(k,v);
            self.log("set " + k + " = " + v);
            return v;
        });
    };
    return t;
})();

PROPERTY.verbose(attributes.get("verbose"));
PROPERTY.pick(attributes.get("name"));

Task definition from Ant build file:

    <scriptdef
        name        = "property.import"
        language    = "javascript"
        src         = "import.js"
        >
        <attribute name="name" />
        <attribute name="verbose" />
    </scriptdef>

Example contents of build.properties:

nsis.home.win32=c:/Program Files/NSIS
launch4j.home.win32=c:/tools/launch4j
launch4j.home.linux=${user.home}/tools/launch4j

Usage is simple:

    <property.import
        name        = "launch4j.home"
        verbose     = "0"
    />

The property.import task looks for variants of the named property suffixed with user.name, os.name or both. For the above import of launch4j.home the property.import task when run by user “preston” on Windows gets the value from the first of:

launch4j.home.win32.preston
launch4j.home.win32
launch4j.home.preston

This allows checkin of build.properties while picking up appropriate per-user and per-platform property values when run.

Posted in General, Javascript | Leave a comment

Mapping components – Javascript

Accessing components in the DOM from Javascript using getElementById() is tedious, somewhat verbose, and does nothing to enhance the readability of the code. Generally there are two cases: finding global elements within the page, and finding members within (possibly repeated) components.

There are (of course) many ways to do this, but what I have settled on is using the ID attribute to identify global elements (what ID was meant for), and using the NAME attribute to identify members within a component. This use of the NAME attribute is exactly analogous to standard usage inside forms, just extended for use with non-form objects.

The code to build a map of global objects:

DOM.byId = function() {
    var map = {};
    DOM.asArray(arguments).apply(function(name){
        var v = name.split('.');
        var o = map;
        while (1 < v.length) {
            var s = v.shift();
            o = o[s] = o[s] || {};
        }
        o[v[0]] = document.getElementById(name);
    });
    return map;
};

The code to build a map of a component:

DOM.byName = function(root) {
    var map = {};
    var walk = function(o) {
        var name = o.getAttribute && o.getAttribute('name');
        if (name) {
            var v = name.split('.');
            var m = map;
            while (1 < v.length) {
                var s = v.shift();
                m = m[s] || (m[s] = {});
            }
            m[v[0]] = o;
        }
        for (o = o.firstChild; o; o = o.nextSibling) {
            walk(o);
        }
    };
    walk(root);
    return map;
};

Usage is quite simple:

var named = DOM.byId(
    'grid1',
    'textWidth',
    'textHeight'
);
var grid1 = DOM.byName(named.grid1);

Now named (by ID) global objects in the DOM can be later referred to in the Javascript code simply as named.grid1, named.textWidth, named.textHeight. Named objects within a component (by NAME) can be referred to as grid1.container, grid1.top.container, grid1.top.strip, (etc.).

Note that both DOM.byId() and DOM.byName() map IDs and NAMEs like “foo.bar” into a corresponding structure:

{ foo: { bar: reference to DOM element } }

Code in base.js.

Posted in Javascript, Software | Leave a comment

Auto-adjusting sizer – Javascript

Took a couple years to get reasonably fluent at HTML/CSS/Javascript, and pick out what seems a decent programming model. Reached the point where most of the public examples of Javascript usage (in particular) look to me as very poorly written. Still it seems like every time I turn out another example, I find another useful idiom.

Take sizing of DOM elements. Say you want to put a sizable component within a page. The DOM model for this is a mess. You can set the width and height of an element o with o.style.width and o.style.height (assuming the element is sizable). You can read the width and height of an element with o.offsetWidth and o.offsetHeight. Not exactly symmetric, and in fact – due to the DOM layout model – these are in fact often not quite the same numbers. Yuck.

Looking at a bunch of repetitive code (button handlers to alter a component’s width/height), realized there was an common idiom that could be extracted into a “sizer” object.

grid.sizer = function() {
    var o = { dx: grid1.container.offsetWidth, dy: grid1.container.offsetHeight };
    o.apply = function() {
        grid1.container.style.width  = o.dx + "px";
        grid1.container.style.height = o.dy + "px";
        o.dx = grid1.container.offsetWidth;
        o.dy = grid1.container.offsetHeight;
    }
    return o;
};

(The component has been mapped by functions DOM.byId() and DOM.byName() described here.)

Now either width, height, or both can be set or adjusted using the “sizer”.

sizer.dx = 500;
sizer.apply();
sizer.dx += 100;
sizer.dy = 400;
sizer.apply();

Kind’a like a remote control for a component. But still not quite right, as (depending on the CSS) the actual component size may be a little different than what was set via the style. The difference is not readily deducible from the DOM, and I did not want to kludge in anything browser or style specific. The difference between the actual size and the size wanted can be computed … then it occurred to me that the “sizer” could be made auto-adjusting.

grid.sizer = function() {
    var ddx = 0, ddy = 0;
    var o = { dx: grid1.container.offsetWidth, dy: grid1.container.offsetHeight };
    o.apply = function() {
        grid1.container.style.width  = (ddx + (0 | o.dx)) + "px";
        grid1.container.style.height = (ddy + (0 | o.dy)) + "px";
        var now = { dx: grid1.container.offsetWidth, dy: grid1.container.offsetHeight };
        ddx += o.dx - now.dx;
        ddy += o.dy - now.dy;
        o.dx = now.dx;
        o.dy = now.dy;
    }
    o.adjust = function() {
        var want = grid.sizer();
        o.apply();
        o.dx = want.dx;
        o.dy = want.dy;
        o.apply();
    }
    return o;
};
var sizer = grid.sizer();
sizer.adjust();
grid.layout();

The essential bit here is that the “sizer” remembers the difference between the size as set, and the actual size in ddx and ddy. A single upfront call to sizer.adjust() initializes ddx and ddy. Note that on later changes to the component size, if the actual size differs from what was wanted (due to CSS changes, browsers bugs, whatever), then ddx and ddy are adjusted to match.

Simple, clean, and browser-independent.

Posted in Javascript, Software | Leave a comment