Saturday, February 9, 2008

Strategies for Success (and other myths)

The writings and thoughts of Karl Marx and Friedrich Engels and orthodox Communism in general date themselves squarely between the Industrial Revolution and Darwin's historic Origins. The revolutionary implementation of Communism was doomed to failure, of course, because by the time it gained critical mass it was already obsolete; groups of humans can't be organized as machines are organized. Top-down mandates of economic equality don't work, because the system will always be more complex than even the most tyrannical police state can enforce. People under duress may provide acceptable manual labor but don't contribute new ideas or new efficiencies to the process when their main concern is not personal investment in work but in following orders; thus micromanaged economies will always underperform freemarket systems.

The lesson of Communism that especially American right-wing capitalists don't want to learn is that micromanagement and monopoly are anathema to the principles of the free market. Applying the principles of Darwinian natural selection to the economic domain, we see that a healthy economic ecosystem is one in which no single player is too dominant (see: super predators), but rather neck-and-neck competition keeps everyone on their toes while allowing smaller players to emerge as competitive with more established ones. Conversely, an economy of monoculture tends toward stagnation. Companies that grow too large become entrenched in a single business model and risk the ire of large partners when proposing innovations in production methods (see: Microsoft and IE).

Government clearly has a role to play in keeping the market competitive by regulating and sometimes smashing large corporations into smaller pieces. But more importantly, ownership of past success is not a guarantor for future success. Top-down institutionalization of past success models is a sure sign that the business is failing to see the next step in its evolution. In this regard, corporate (read: Stalinist) ownership of information and ideas will always fail in the face of bottom-up Darwinian trial-and-error. This is especially true in industries touched by technology, and we're already seeing established media companies, record companies, and television networks collapse under their own weight.

Enter the Internet. To the extent that it remains free, equal, and open, it provides the most fertile soil yet for innovation and progress (of ideas, of creativity, of economic advancement, of democracy). The chaotic hordes of the MySpace/YouTube generation will surely hasten the extinction of the giant record companies and the television networks, as the wisdom of crowds will do a better job determining what the crowds like than any closed, proprietary group of mavens in a boardroom or a laboratory ever will.

The lesson for internet companies trying to attract millions? Release early and often. Keep your coupling loose. Submit to what your users are telling you - investing 10 months in a project you're sure will be a hit is a huge risk; you'd better be basing your decisions on reams of user feedback and research, because your perfect vision for the product will always fail you unless you're playing with rules that have been subjected to the Darwinian rigor of millions of little trial-and-error tests.

Saturday, February 2, 2008

Easy Date Formatter

This should do the trick for most uses:
 * takes a string in form 'd/m/Y'
 * d => day (2 digits, leading 0)
 * D => day (2 digits, no leading)
 * l => day (of week, text, 3 chars)
 * L => day (of week, text, full length)
 * m => month (2 digits, leading 0)
 * M => month (2 digits, no leading 0)
 * f => month (text, 3 chars)
 * F => month (text, full length)
 * y => year (2 digits)
 * Y => year (4 digits)
 * g => hour (12hr, leading 0)
 * G => hour (12hr, no leading)
 * i => minute
 * s => second
 * t => hour (12hr, formatted with am/pm)
 * @param {String} format String for the formatting of this Date object
 * @return {String}
Date.prototype.format = (function () {
    var days = ['Sun', 'Mon', 'Tue',
        'Wed', 'Thu', 'Fri', 'Sat'];
    var fulldays = ['Sunday', 'Monday', 'Tuesday',
        'Wednesday', 'Thursday', 'Friday', 'Saturday'];
    var months = ['Jan', 'Feb', 'Mar',
        'Apr', 'May', 'Jun',
        'Jul', 'Aug', 'Sep',
        'Oct', 'Nov', 'Dec'];
    var fullmonths = ['January', 'February', 'March',
        'April', 'May', 'June',
        'July', 'August', 'September',
        'October', 'November', 'December'];

    function twoDigits(n) {
        return (n<10? '0':'')+n;

    return function formatDate(format) {
        var d = this;

        var matches = this.matches || {
            'd': function () { return twoDigits(d.getDate()); },
                'D': function () { return d.getDate()+''; },
                'l': function () { return days[d.getDay()]; },
                'L': function () { return fulldays[d.getDay()]; },
                'm': function () { return twoDigits(d.getMonth()+1); },
                'M': function () { return d.getMonth()+1; },
                'f': function () { return months[d.getMonth()]; },
                'F': function () { return fullmonths[d.getMonth()]; },
                'y': function () { return (d.getFullYear()+'').slice(2, 4); },
                'Y': function () { return (d.getFullYear()+''); },
                'g': function () { return twoDigits(d.getHours()%12); },
                'G': function () { return d.getHours()%12+''; },
                'i': function () { return twoDigits(d.getMinutes()); },
                's': function () { return twoDigits(d.getSeconds()); },
                't': function () { return (d.getHours() > 11? 'am' : 'pm'); }
        this.matches = matches;

        return format.replace(/[dDlLmMfFyYgGist]/g, function (match) {
            return matches[match]();