Code

Warning, Contains Assembly Language

C, like an AK-47: when you absolutely, positively gotta kill every last CPU cycle in the room. Slides from Felix von Leitner’s talk on C and compiler optimizations (PDF).

(via Hacker News)

Exporting a Vox Blog

Sunday project!

Export a Vox blog to MTIF (Movable Type Import Format), along with some CSS to style it.

Requires Python, httplib2, Feed Parser and Beautiful Soup.

CSS Images, Sprites, and iPhone WebKit

A few months ago, I was helping a friend troubleshoot an odd iPhone-related visual error on Hunch. The right side of the buttons weren’t lining up vertically with the top or bottom of the rest of the button. Oddly, the problem only manifested itself when viewing the site at certain zoom levels (non-quantized, to be specific). Pinching in/out or zooming into specific parts of the page made the buttons render correctly.

We’d used a similar technique on Domainr, so were curious to see if there was a way to address it cleanly.

It appeared that WebKit for iPhone uses mipmaps to render minimized background images. This makes sense—it has fast texturemapping hardware, and OS X / Quartz has been using OpenGL to render 2D graphics for some time.

The combination of hardware texture filtering of mipmapped background images with (then) imprecise texture coordinates were causing the artifacts we’d been seeing (recent related changes in WebKit).

Domainr’s buttons are styled using a sliding-door technique with a single CSS sprite background image. By this time we were starting to test against Safari 4.0 and Firefox 3.5, which also demonstrated similar visual errors when using their full-page zoom features.

The solution ended up being simple:

Vertically align the left and right background images for the button in the sprite.

It’s a palliative fix, but works. We were able to keep the single sprite image, and not introduce iPhone-specific CSS or hack WebKit. In the end, there were other benefits to the fix. Despite redundant image data, aligning the background slices eased the process of updating the sprite image for new button variations.

Two Quotes

Two friends of mine, both engineers, in separate occasions in the past week:

@rk: “Software is a hypothesis.”

@nk: “The GPL dictated behavior, whereas the authors of the MIT license merely prescribed it, having faith it would succeed on its inherent benefits.”

Refining Superclass Method Calls in JavaScript

Originally posted to ydnar.vox.com in February 2007.

Last week I was revisiting the always fun problem of implementing “classical” inheritance in JavaScript. I’d taken a few stabs at it, and had gotten it to a reasonably good state that borrowed some good ideas from Doug Crockford, Sam Stephenson, and Dean Edwards. Joshua Gertzen wrote a good post about various methods on his blog.

I’ve never been terribly thrilled with the form Class.superClass.method.apply( this, arguments ). It was redundant: replicating both the class and method names. Copy & paste of code could lead to subtle errors, and it’s annoying to type that much. But the alternatives were worse: Recompiling the function to generate a “magic” lexical for the superclass or wrapper methods. So the Class object basically sat untouched for a year and a half.

Back to last week…It occurred to me that in all the JavaScript we’d built for Vox, we almost never shared a method between two objects, except via inheritance. There were a couple exceptions, but they could be rewritten (it turned out to be a good idea anyway). Second, functions are objects like everything else, and can have arbitrary properties. Third, arguments.callee is available in every function call in JavaScript. I realized then that storing the superclass was not as useful as just storing the supermethod.

For any given method in a class, store its supermethod as a property of the method: method.__super. Instead of the unwieldy construct above, any method could simply use arguments.callee.__super.apply( this, arguments ).

The Class constructor from Core.js:

Class = function( sc ) {
var c = function( s ) {
this.constructor = arguments.callee;
if( s === __SUBCLASS__ )
return;
this.init.apply( this, arguments );
};

c.override( Class );
sc = sc || Object;
c.override( sc );
c.__super = sc;
c.superClass = sc.prototype;

c.prototype = sc === Object ? new sc() : new sc( __SUBCLASS__ );
c.prototype.extend( Class.prototype );
var a = arguments;
for( var i = 1; i < a.length; i++ )
c.prototype.override( a[ i ] );

for( var p in c.prototype ) {
var m = c.prototype[ p ];
if( typeof m != "function" || defined( m.__super ) )
continue;
m.__super = null;
var pr = sc.prototype;
while( pr ) {
if( defined( pr[ p ] ) ) {
m.__super = pr[ p ];
break;
}
if( pr === pr.constructor.prototype )
break;
pr = pr.constructor.prototype;
}
}

return c;
}

arguments.callee was useful in the constructor too: Instead of creating a circular reference by overriding the constructor like this: constructor.prototype.constructor = constructor, the constructor itself can just set it on the this object when the constructor is called: this.constructor = arguments.callee.

Calling a supermethod can be simplified further, to arguments.callee.applySuper( this, arguments ) via a little sugar:

Function.prototype.extend( {
applySuper: function( o, args ) {
return this.__super.apply( o, args );
},

callSuper: function( o ) {
var args = [];
for( var i = 1; i < arguments.length; i++ )
args.push( arguments[ i ] );
return this.__super.apply( o, args );
}
} );

Adobe Makes an Open Source Play

Originally posted to ydnar.vox.com in November 2006.

Adobe has given the Flash ActionScript (ECMAScript or JavaScript 2.0) interpreter to the Mozilla foundation as the new open source core of SpiderMonkey, the JavaScript engine for Firefox. It's called Tamarin. Brilliant.

Graphics

Originally posted to ydnar.vox.com in August 2006.

Recently dug up some old photos, er screenshots from the days when I was a graphics geek. I'm supposed to give a presentation about same one of these Thursdays.

Holy War

Originally posted to ydnar.vox.com in July 2006.

This is a brilliant solution to the age-old problem of tabs versus spaces in source code. Instead of treating tabs as indent of a fixed size, treat the source code as tabular data, where the tab character jumps to the next logical column, where the width of said column is determined by the widest point in the document.

(via Slashdot)