I don’t much like Google’s new Closure library and compiler. Here’s why…
I have a vivid memory of watching the David Lynch movie Eraserhead where towards the end I finally turned to the person next to me and we both slowly voiced the phrase “what was that?”
I had déjà vu recently when I waded through the announcement on Google’s Closure compiler and library for JavaScript. Had I just walked into a David Lynch movie set on planet Google? Had somebody just pulled a Gordian knot tight around me? If so, with what razor could I cut it apart?
Some smart people have chimed in on the side of Google and spoken poorly of a number of common coding techniques for JavaScript programmers with Crockford’s module pattern being one example. Their complaint? That modern techniques employed by JavaScript coders were inefficient…
Dmitry then had a look at some of the Closure source code and pointed out that compilers aside, some of the coding techniques used in Closure are inefficient for JavaScript.. and that some others are just plain silly. Borrowing a phrase from Dmitry… I don’t know what they call that in Java, but I call it irony.
For the record, and to clear up any potential ambiguity caused by my often circuitous writing style. I agree with Dmitry. Other libraries such as jquery may have their issues but the design of the part that people interact with (you know, the API) is overall something other libraries would, for the most part, do good to emulate.
I had a look through the source for closure myself and whilst there’s some useful stuff in there it feels a bit like a bag of nails and is about as inspiring as one. Slider examples that use 44 different individual scripts (I’m sure the compiler fixes that right?), a unit testing framework apparently from 2009 shoehorned into code apparently written in 2004 (better late than never) and a bunch of things that really don’t seem like they belong in a decent general purpose library such as pretend constants like the one for the default size of a popup window and finally some stuff that really shouldn’t be in any JavaScript code anywhere, such as != 0. Now, there may be good reasons for these and I’m not questioning the coding ability of the people who wrote it. Instead, I’m questioning the extent to which they might still (if they ever did) consider themselves JavaScript natives. Most people coding in JavaScript stopped writing code the way suggested by the proponents of the closure compiler years ago because we were sick of fighting the language. Dmitry is one of those people and library authors should pay attention.
What bothered me about Closure more than anything though was the (apparent) accompanying mentality that they know the right way to do things and that other JavaScript programmers are living in the dark ages banging rocks together. Still, I shouldn’t be that offended that somebody has a different idea about how to write good code… and yet, there I was…
What was it that bothered me so much?
The real thing that pissed me off is a suggestion that I should write worse code to optimise for their compiler. Last I checked it was 2009 and I gladly wrote my last malloc more than ten years ago. If the interpreter or compiler wants to run better then somebody ought to fix the compiler. I’ve had enough IE6 for the last eight years to know that having to tailor my development approach to a computer, instead of to a human is nothing but pain from start to finish and that worse… spending all my time looking inwards to the computer instead of outwards invariably results in a crap user experience for the people that really matter - my users - whether that’s coders I work with or who inherit my code or users of the UI that I’m writing.
Some of us who work in JavaScript every day are trying to improve JavaScript and the coding environment to make it better. We all want to make JavaScript suck less… these other guys (yes, I’m deliberately phrasing this divisively), they’re trying to make the language suck more by making JavaScript developers kowtow to their compiler. Or worse, by making people write Java that compiles to JavaScript… but that’s a story for another day.
Pseudo-classical inheritance simply doesn’t make sense in JavaScript. JavaScript works better with object cloning, mixins, shallow (think wading pool) hierarchies, literal notation, and closures. Trying to do elaborate inheritance in JavaScript generally ends up in dog shit. I know because I’ve stepped in it.
It would be nice to get some more of Self into JavaScript… in other words, it would be nice to have a better prototypal system with dynamic inheritance and traits. I would need to see the associated complexity tax tested first though as I’m not sure if the language can float those but perhaps… and perhaps multi-methods, perhaps macros… I’m not sure, I’ll leave that to the language designers.
Anyway, it would not be better to get more of C++ into JavaScript. People absolutely need to remember that. The world has moved on.
Yes, personal preference but… Friends of Closure, please stop telling people they’re doing things wrong because based on your development style and using your compiler your way works better for you.
Finally… just to really nitpick, the name really blows. Both because the library doesn’t feel especially functional and because it sounds too much like the completely awesome Clojure language…
I’m writing this one down because despite being burned by it before I still haven’t learned my lesson and got caught out once again. I thought that perhaps posting it up here would finally prompt me to remember it.
String.prototype.split with a regular expression has for a long time generally been stuffed across the major browsers. This has been documented before, Steven Levithan even has a nice replacement available.
Whilst there are issues in several browsers, the biggest pain-in-the-butt award though has to go to… wait for it… IE.
Why does "...".split(/\./) not produce the same result as "...".split(".")?
I know the old ES3 spec had some issues but really… aneurysm inducing stuff.
A while ago I started experimenting with Dmitry’s handy Raphaël SVG/VML library for doing some charting.
The charting work has not yet seen the light-of-day but during some spare moments I had a look at implementing an old arcade game using Raphaël. A very rough, incomplete and buggy approximation of the original Space Invaders.
Given that this is an “alpha release” of something on my blog and also that I don’t really like IE, despite Raphaël supporting IE I never tested this game in IE and hence, in that browser you probably can’t currently get beyond the intro screen because I didn’t wire up the keyboard controls. I may get it to “work” in that browser if somebody eventually guilts me into it. I probably should get it working in IE because, well, otherwise I’m partly wasting the benefits of Raphaël over pure SVG? Anyway…
It does work in Firefox, Chrome and Opera… possiby Safari, though again… untested so far.
I used Raphaël for the graphics, SoundManager2 for the sounds and implememented the top scores over on AppJet which unfortunately seems to be having occasional problems so I might have to move that to an install of couchdb I have.
Some observations
JavaScript in the browser is probably fast enough right now for games of this type though you would have to do some optimisation. Apart from some time shift corrections my game code got no speed optimisations. That said, setTimeout and setInterval seem fairly inadequate and difficult to work with. I didn’t use a global/world clock but that is probably going to be necessary for decent synchronisation.
I didn’t spend much time on polishing the game and it shows.To make a highly playable game a huge amount time is going to be tweaking the UI, playability, difficulty progression and generally getting it polished. If web developers consider the amount of effort put into the final polishing stages for a website and multiply it by… ten… they might get an idea of how much time would go into polishing something as interactive as a game like Space Invaders.
I used a boatload of closures and prototypal inheritence via object cloning and didn’t care about doing any memory cleanup. I don’t typically use Chrome but V8 really handled that unoptimised code really well. I would expect Tracemonkey to be as good whereas the release of FF3 I’m using seems to struggle a little.
Raphaël worked nicely but in order to get the two animation states for the invaders I ended up doing them as sprites and constantly changing the sprite source for all the invaders. Without spending more than thirty seconds looking at Raphaël’s internals I suspect my code would perform better to do them as actual SVG and just change the path for each state instead of constantly adding and removing sprites.
I don’t really think it matter but the code for this Space Invaders version is not MVC. All the objects are responsible for calling the draw and sound API’s directly based on their own state. I used what is probably more of a morphic style which seemed much more natural for what I was writing.
For the game, no guarantees given as to whether or not it will crash any browser at any time. There’s a bunch of timeouts still running when you die so try to not leave your browser sitting on the high score page for any length of time just yet.
Anyway, here it is: Space Invaders.
Be warned that it has sound, the sound is a bit crap… and you can’t (yet) disable it. Also, I’m well aware that the second level is basically impossible at the moment. I’ll look at some improvements in the coming days and weeks.
If anybody wants to see the game code, without having to view source the game itself you can see that over here.
Most Perl programmers would be familiar with the Schwartzian transform which derives from the lisp decorate-sort-undecorate idiom. If you’re not familiar with it then reading the wikipedia article should be a sufficient introduction. Essentially it avoids recalculating the comparisons for each call to sort.
In 1994, Randal Schwartz replied to a question in comp.unix.shell asking how to sort on the last name for a list like this:
adjn:Joshua Ng adktk:KaLap Timothy Kwong admg:Mahalingam Gobieramanan admln:Martha L. Nangalama admrp:Michael R. Pearson adshl:Siu Lung Henry Lee adsyh:So Yi Ho adtkk:Tariq K. Khan adtkl:Terence K. H. Leung advld:Vickie L. Dwyer alaen:Alfred E. Neuman anedp:Erin D. Picard
The answer:
#!/usr/bin/perl
require 5; # new features, new bugs!
print
map { $_->[0] }
sort { $a->[1] cmp $b->[1] }
map { [$_, /(\S+)$/] }
<>;
Map, sort, map.
Anyway, here’s a version in JavaScript 1.6†. If we have the following array:
var myArray = ["adjn:Joshua Ng", "adktk:KaLap Timothy Kwong", "admg:Mahalingam Gobieramanan", "admln:Martha L. Nangalama", "admrp:Michael R. Pearson", "adshl:Siu Lung Henry Lee", "adsyh:So Yi Ho", "adtkk:Tariq K. Khan", "adtkl:Terence K. H. Leung", "advld:Vickie L. Dwyer", "alaen:Alfred E. Neuman", "anedp:Erin D. Picard"];
We can sort on the last name like so:
var sorted = myArray.map( function (e) {
return {o: e, s: e.split(/[\s]/gi).pop()};
}).sort( function (a, b) {
return a.s> b.s;
}).map( function (e) {
return e.o;
});
Note that the value used to sort is calculated in the map().
I’d be interested in further examination into how well this works in current JavaScript implementations (and any map provided for older implementations); and whether there are more appropriate ways to code it up in JavaScript.
—
† Map isn’t in until 1.6.
Optimising delivery to the client is an important step in improving user experience on a website. Unfortunately, it generally falls under the domain of technical people tasked with fixing either their own problems or server problems, not normally user problems in any direct way. As such, despite tools such as YSlow it’s still all too common for people to be delivering web sites in a sub-optimal fashion in terms of delivery to users.
I’m going to be exploring some cacheability optimisations for JavaScript files using a reverse proxy called Varnish, though you could extend these to other resources as well. As a primer for what I’m talking about here, it may be a good idea to bone up on web caches and what they do.
Anyway… to the point at hand. I’m using Varnish to handle versioned URL’s for JavaScript files such that I only ever need a single copy of those files on the server but am able to get a far-future expires version out on the web purely by changing the path I use to refer to the resource. For example, let’s say I have a JavaScript resource that normally lives at http://sand.boundvariable.com.au/js/core.js. Using this Varnish setup I can get long lived versions of this file onto the web by referencing it at a URL like http://sand.boundvariable.com.au/js/v.1.core.js. Note that I change the file path instead of adding a query parameter as query parameters tend to prevent caches from keeping a copy.
The point here is to maximise the time for which particular resources are kept in client-side caches. Instead of trying to get URL’s to expire as often as I expect them to change I would instead start referencing the same resource on a new URL.
I’ve got an example setup on a Gentoo box running Varnish in front of Cherokee lighttpd. Apart from the Varnish config subs listed below, both Varnish and Cherokee lighttpd are in default setup with Varnish on port 80 proxying to Cherokee lighttpd on port 8080.
So, the Varnish config…
Here’s the receive:
sub vcl_recv {
set req.backend = default;
if (req.url ~ "\.v\.[0-9]*") {
set req.url = regsub(req.url, ".v.[0-9]*", "");
set req.http.magicmarker = "1";
remove req.http.cookie;
}
}
This tests for the presence of a version in a file path, sets a marker for the backend and removes the version.
Here’s the fetch:
sub vcl_fetch {
if (req.http.magicmarker == "1") {
unset obj.http.magicmarker;
set obj.http.expires = "Mon, 1 Jan 2018 20:00:00 GMT";
unset obj.http.cache-control;
unset obj.http.etag;
}
}
This checks for the marker and on finding it removes it and sets some header optimisations with a far future Expires.
You can see an example at http://sand.boundvariable.com/js/core.v.106022009.js. Open it up and check out the headers. For comparison, have a look at the headers on http://sand.boundvariable.com/js/core.js which is doing a straight pass to Cherokee.
You can also check out the cacheability of the file via a report on ircache.
The danger in this approach served as-is, is that somebody could fill the cache and downstream proxies with stale copies of files. Also, this setup in the current state is not appropriate for making sure that every user getting a resource at a particular URL is getting the same result.
Determining if those two points are problems for particular cases and the solutions for them is left as an exercise for the reader.
The ECMAScript discussion list (es-discuss) has a thread(s) running on future proposals for lambda syntax with several hundred posts. A similar thread on class syntax has, by comparison, gone largely ignored.
Some others have noted the potential significance of this. Does it demonstrate a trend in JavaScript? Is it indicative of where programming languages in general are headed?
As Guy Steele has put it:
A closure is an object that supports exactly one method: “apply”.
On the other hand, there’s this, usually attributed to Norman Adams:
Objects are a poor man’s closures.
Still, there really isn’t that much distance from one to the other… granted, that is relative to context.
From my point of view, classical OO has sometimes trended towards being overbearing, particularly for UI development. This is probably why everybody is excited about finding a more elegant lambda syntax for JavaScript and less interested in class syntax, which simultaneously feels more like bookkeeping and also is likely to have a mental association with an heavy-feeling ontology that many JavaScript coders would want to avoid.
Sun Microsystems have just announced the 1.0 version of JavaFX, one of the main components being JavaFX Script.
Let me get this straight. After twelve years Sun have finally admitted that writing UI’s in Swing blows goats and their solution is to release something that lets you create a swing UI using code that borrows heavily from JavaScript.
What’s it got? First-class functions, declarative syntax, list-comprehensions…
I’m going to repeat the name because I think it bears repeating. JavaFX Script. I guess the only name bad enough was already taken so they threw an FX in the middle.
If it weren’t for my horse… I wouldn’t have spent that year in college.
Here’s a JavaFX Script code sample (excuse the code formatter from getting confused with the indenting):
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.shape.Rectangle;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
Stage {
title: "Declaring Is Easy!"
width: 249
height: 251
visible: true
scene: Scene {
content: [
Rectangle {
x: 45
y: 35
width: 150
height: 150
arcWidth: 15
arcHeight: 15
fill: Color.GREEN
},
Circle {
centerX: 118
centerY: 110
radius: 83
fill: Color.WHITE
stroke: Color.RED
}
]
}
}
Looking at it, I don’t think I need to talk about where the inspiration for that comes from. Still… haven’t the GWT proponents been telling everybody for a long time that scripting languages are evil? Will GWT one day allow people to write JavaFX Script and have it compile to JavaScript? I don’t know and honestly I don’t care.
JavaScript is far from perfect but I think the current Ajax “stack” works for (at least) three reasons:
1 - Some of the constraints have, by accident, improved many UI’s. I mentioned that before.
2 - The open web.
3 - JavaScript actually has some features that are really good for creating UI’s. Homoiconicity (to some degree), lambda and a prototypal object oriented system.
JavaScript won’t last forever but I haven’t seen anything yet that is better on those three points.
Update: I notice some people have come here looking for some demistification of this JavaFX error:
com.sun.javafx.runtime.AssignToBoundException: Cannot assign to bound variable
I can’t help you. Hey, at least you’re not looking at this compile error huh?
Expected type int * int -> int, got type int * (int -> int)
There is a short text written by Poul Anderson entitled Uncleftish Beholding which shows, to some extent, what English would have looked like in the absence of loanwords. It’s interesting to see the number of phrasings that somebody speaking English now would find awkward. English is something of a mixed-breed.
If we multiply the number of language speakers by the number of documents on the web in that language then English is far-and-away the winner in those popularity rankings. I don’t know how important that is but I don’t think English is emerging as the single human language of the web.
How about programming languages? Peter Van Roy thinks that there is evidence that one true programming language is emerging. Some disagree. Esperanto anyone?
Programming languages have something resembling native speakers at least from a “how many users do we have” aspect because, as Yegge points out, most programmers only know one language. In other words, secondary languages are rare… at least for a substantial proportion of the community.
There are plenty of programmers who know how to do the same thing in several languages and try to impose that where they can. JavaScript consistently fell victim to that where people were constantly conceiving ways of doing things that didn’t suit the language. Many people did that when they moved from a training in Java to JavaScript, jumping through hoops to get JavaScript to work like Java because, you know, it looks like it can.
There’s a difference between trying to impose unsuitable syntactic sugar on a language (classes in JavaScript) and liberating the language by demonstrating how patterns from other languages might translate more naturally (Crockford’s module pattern.) It’s good to bring ideas and techniques to a language, not so good to try hammering in conventions.
Of course, programming languages are not like-for-like comparable with human languages. Still, in the way that it has taken influence from other languages - for better or worse - JavaScript is kinda like English.
Guy Steele talks about growing a language (video, pdf) indicating a desire to make a language flexible enough so that the people using it can build on the language provided. The programming language provides the rules - and hence limitations - around which programs can be created. The things people do in a programming language creates the dialogue.
Java has been successful on that level at least partly because it makes it easy for those one language people to create a dialogue or use an existing dialogue.
The thing is, a programming language can be restrictive in a way that a human language typically can not.
Programming languages are used by world builders and the type of language determines the effectiveness with which people can construct universes. Programming languages have philosophical ramifications because the construction of the programming language impacts on the types of dialogue that can happen. A human working in the regular world can invent new rules of discourse and moreover may actually invent a new language (with words or symbols) with which to describe or talk about the world.
The can be achieved in a programming language but the restrictiveness of a programming language can make constructing a new domain-specific language difficult enough that it’s almost never attempted in that language. On the JVM the rigidness of Java and an understandable resilience to change looks like it will lead to increased popularity of new languages running on the JVM at the expense of the Java programming language. As the language of discourse, Java looks like it will soon fade instead of grow.
Languages need to evolve, JavaScript managed to do that mostly by accident and in a different sense to that in which Java grew. The point though is that if JavaScript had not been able to grow at all then despite any luck it would probably now be dead.
Still, as Eich and Crockford both say, popularity doesn’t usually have much to do with the design of the language except perhaps where the design seems familiar… though familiarity itself is a double-edged sword.
In the end though JavaScript like all languages needs to evolve or die… with care.
An infinitely flexible programming language would be infinitely extensible and, most likely, infinitely useless. On the other hand, a language too heavy on restrictions will be useful… but for a sufficiently small problem set that it too would ultimately be useless.
The growth of a language really happens in the community.
Just like HTML, many of the programming languages already in existence today are trying to evolve inside the constraints of standards committees… occasionally this may prove midly successful but I think the best you can hope for when doing that is a Bonsai.
There’s been a bit of interest in a time picker control from Maxime Haineault. Nice piece of work but I for one hope this particular interaction style doesn’t catch on.
As a user I have to move my mouse halfway across the screen aiming at little boxes in order to input the time. If I decide to change that time then I need to go back across the screen aiming at other boxes. Hello carpal tunnel. Further, I could be alone in this but I don’t find the control simple or intuitive at all. I’d probably rather be typing.
Not wanting to simply disagree with the merit of that format for a time picker and leave it there, I thought it would be sensible to provide something of an alternative. So, in the spirit of shamelessly ripping-off a UI convention from elsewhere I’ve coded up the standard OS time selector (with the exception of the little up/down arrows on the right-hand-side.)
Have a look at the example time picker. Click on the hours, minutes, seconds or AM/PM and use your scroll wheel.
Sure, I could probably get roughly the same result using four select boxes (scroll wheel worked on a select box last time I checked) but what would be the fun in that?
In the physical world designs are bound by the constraints of space, time, money and the laws of physics.
The impact of the physical laws on creating an object is inversely proportional to the technological advancements available to the designer. Leonardo may have been able to conceive of a flying machine but the actual flying machine, that people could use, took some four-hundred years to appear.
In some ways this is a good thing.The required investment and risks associated with the physical world means that, for example, most people will not try to fly a helicopter with no training. It also used to mean that objects were made by people who knew how to make those objects because they did that for a living. You know, cobblers, carpenters, tailors… engineers. Now though, we live in an age of empowerment where any monkey can go to the local hardware store and purchase the means to create a real disaster. We also live in a time where the requirements on the things we create can sometimes have little bearing on their intended use so we end up with things like beer with added vitamins and a nine button mouse. Luckily, the constraints of space, time, money and the laws of physics still prevent Average Joe from going ot the local hardware store and purchasing the means to destroy the solar system.
These physical constraints do not not apply to software… well, they do (things such as memory and processor limits), but not with anything near the same degree of impact. This adds a degree of importance to the training that professional programmers require. Most people would fear for their lives if attempting to fly a helicopter without adequate training. If somebody is writing software for the helicopter though, that connection is not so easy to make.
It’s also easy for anybody to design the user interface for software without knowing anything about user interface design. Visual development environments made it easier to create ridiculously complicated desktop applications. The investment in creating a user interface is small and often the thinking is that easy-to-do equates to should-do.
Java Swing provides an environment for creating a user interface that is intended to make sense to Java programmers. As it turns out, Java programmers (and indeed Java language designers) are not the best people to be deciding on the design of the user interface and moreover are probably not the best people to be deciding on the programming model for writing them at all.
Java failed on the client. Instead the ragamuffin collection of HTML, CSS and JavaScript used for the web succeeded. There were good reasons for this.
The web as HTML over HTTP has always been strong for document delivery and interlinking between those documents. It is good for text content delivery, albeit in a paged, one-large-chunk-of-text-at-a-time, manner. With JavaScript, the content chunking can be controlled so that content delivery can be more finely controlled and more reactive (or proactive) to the needs of the user.
I think the content-oriented nature of the web is leading us to better user interfaces.
Programmers who do not know JavaScript complain that the language sucks. Programmers who do know JavaScript compain that whilst the language is elegant and powerful (warts aside) the API for controlling the UI (the DOM) sucks.
Yes, the DOM sucks. However, the suckiness of the DOM has actually imposed a useful constraint on programmers. If the web had from the start been really good for creating applications then there’s a good chance we would have had more applications and less content. Further, despite its shortcomings, CSS has helped to shift custodianship of the presentation layer away from application programmers and GUI toolkit developers.
So… much as I might bemoan the weaknesses of the DOM I actually think that the difficulties that it has imposed may have actually played a part in reducing the amount of administrative debris attributable to JavaScript on many websites.
With that said, as the emphasis on good usability on the web increases I think we’re all about due for some unshackling. My only request would be that people actually learn how to fly before jumping into that helicopter.