<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><description>My name is Kenneth and I’m a Swiss transplant in San Francisco. By day, I’m the architect behind Chartboost, and in my off hours you will find me either exploring this magnificent city or hacking away on an ever-changing new side project. This is my personal weblog where I muse about the world of design, software and life.</description><title>Kenneth Ballenegger</title><generator>Tumblr (3.0; @kswizz)</generator><link>http://kswizz.com/</link><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/seoxys" /><feedburner:info uri="seoxys" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://tumblr.superfeedr.com/" /><item><title>From the “this guy is a genius” department: Bret...</title><description>&lt;iframe src="http://player.vimeo.com/video/66085662" width="400" height="225" frameborder="0"&gt;&lt;/iframe&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;From the “this guy is a genius” department: &lt;a href="http://worrydream.com" target="_blank"&gt;Bret Victor&lt;/a&gt; (of &lt;a href="https://vimeo.com/36579366" target="_blank"&gt;Inventing on Principle&lt;/a&gt; fame) presents his latest project. The prototype is at the intersection of data visualization and drawing, and introduces an entirely new approach to the topic. Well worth a watch.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/seoxys/~4/K9uzisUeCUA" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/seoxys/~3/K9uzisUeCUA/51618984830</link><guid isPermaLink="false">http://kswizz.com/post/51618984830</guid><pubDate>Tue, 28 May 2013 21:12:06 -0700</pubDate><feedburner:origLink>http://kswizz.com/post/51618984830</feedburner:origLink></item><item><title>Fibonacci &amp; the Y-Combinator in C</title><description>&lt;p&gt;Be warned, this post describes something you should &lt;em&gt;never&lt;/em&gt; actually use in production code. However, we will get to play with some very cool concepts and techniques: &lt;strong&gt;functional programming in C&lt;/strong&gt;, closures, implementing autorelease pools from scratch, data structures (linked lists and b-trees), bitwise operations, recursivity, memoization, and the Y-Combinator. If this sounds crazy, don&amp;#8217;t be scared. It&amp;#8217;s all fairly simple when broken down.&lt;/p&gt;

&lt;p&gt;Let&amp;#8217;s back up for a second, however. What we&amp;#8217;re going to create here is a program that returns a number in the &lt;a href="https://en.wikipedia.org/wiki/Fibonacci_number" target="_blank"&gt;Fibonacci sequence&lt;/a&gt;. The Fibonacci sequence is a sequence of numbers in which each integer is equal to the previous two integers added: 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, etc.&lt;/p&gt;

&lt;p&gt;There are many ways of calculating Fibonacci numbers, but the naïve implementation which follows the mathematical definition is this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;unsigned long long fib(int n) {
    if (n &amp;lt; 3) return 1;
    return fib(n-1) + fib(n-2);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So let&amp;#8217;s make a program out of this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;// fib.c

#import &amp;lt;stdlib.h&amp;gt;
#import &amp;lt;stdio.h&amp;gt;

// let's make life easier for ourselves:
typedef unsigned long long ull;

ull fib(int n) {
    if (n &amp;lt; 3) return 1;
    return fib(n-1) + fib(n-2);
}

int main(int argc, char **argv) {
    int upto = 20; // which number to compute
    if (argc &amp;gt;= 2) upto = strtol(argv[1], NULL, 10);
    printf("Calculating fib(%d)...\n", upto);
    ull solution = fib(upto);
    printf("fib(%d) == %llu\n", upto, solution);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We&amp;#8217;re going to be using &lt;a href="http://clang.llvm.org/" target="_blank"&gt;clang&lt;/a&gt; as our compiler. Let&amp;#8217;s compile and run our program:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ clang -o fib -O3 fib.c
$ ./fib 17
Calculating fib(17)...
fib(17) == 1597
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;However, as you&amp;#8217;ll see if you try to compute &lt;code&gt;fib(200)&lt;/code&gt;, this will not scale. In computer science terms, fib is a function which requires exponential time as &lt;code&gt;n&lt;/code&gt; increases. &lt;code&gt;O(2^n)&lt;/code&gt;. For example:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;fib(5) [A] calls fib(4) [B] and fib(3) [C]
fib(4) [B] calls fib(3) [D] and fib(2) [E]
fib(3) [C] calls fib(2) [F] and fib(1) [G]
fib(3) [D] calls fib(2) [H] and fib(1) [I]
fib(2) [E] returns 1
fib(2) [F] returns 1
fib(1) [G] returns 1
fib(2) [H] returns 1
fib(1) [I] returns 1
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;As you can see, the function is called multiple times with the same argument, and for every time &lt;code&gt;n&lt;/code&gt; is decremented (until you reach 1 or 2), the number of function calls increases by a power of two. Imagine how much worse it would be for &lt;code&gt;fib(200)&lt;/code&gt;. The number is so great that even given unlimited memory and energy, your computer would require billions of years to finish the computation.&lt;/p&gt;

&lt;h3&gt;Closures&lt;/h3&gt;

&lt;p&gt;A closure is an anonymous function which may use and capture variables from its parent scope. Imagine this code, in JavaScript:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;function print_element_plus(x) {
    return function(e) {
        console.log("-&amp;gt; " + (x + e));
    }
}
[1, 2, 3].forEach(print_element_plus(2));
// -&amp;gt; 3
// -&amp;gt; 4
// -&amp;gt; 5
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;print_element_plus&lt;/code&gt; returns an anonymous function (aka. a closure) which takes one argument and adds it to &lt;code&gt;x&lt;/code&gt;. The variable &lt;code&gt;x&lt;/code&gt; is captured by the closure, and even though it goes out of scope when &lt;code&gt;print_element_plus&lt;/code&gt; returns, it is still retained by the closure until the closure itself goes out of scope and is freed.&lt;/p&gt;

&lt;p&gt;C does not natively support closures. Although similar functionality can be implemented in pure C fairly easily using a struct containing the environment and a function pointer, we&amp;#8217;re going to instead take advantage of clang&amp;#8217;s built-in support for the blocks extension to the language:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ clang -fblocks -o fib -O3 fib.c -lBlocksRuntime
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In C, a block is simply another name for a closure, and its syntax is very similar to defining a function pointer. So with that in mind, let&amp;#8217;s rewrite our &lt;code&gt;fib&lt;/code&gt; function as a block.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;__block ull(^fib)(int) = ^ull(int n) {
    if (n &amp;lt; 3) return 1;
    return fib(n-1) + fib(n-2);
};
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;em&gt;Note: this should go in &lt;code&gt;main()&lt;/code&gt; and the &lt;code&gt;__block&lt;/code&gt; is necessary to enable explicit recursion, so that the block may reference itself.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;The Y-Combinator&lt;/h3&gt;

&lt;p&gt;Recursion implies that a function has a name by which to refer to itself, so it may call itself. While the example above works, it relies on the block capturing the variable to which it is assigned from the parent scope. This is not super clean, and relies on a implementation detail of the C programming language. Identical code would not work in, for example, lisp.&lt;/p&gt;

&lt;p&gt;Since we are giving ourself the restriction of not explicitly using the &lt;code&gt;fib&lt;/code&gt; variable in order to recur, we will wrap the function in a function whose first and only argument is a function with which to recur. We&amp;#8217;ll call this function the generator, because when called with &lt;code&gt;fib&lt;/code&gt; as its argument, it will return the correct &lt;code&gt;fib&lt;/code&gt; function.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;typedef ull(^fib_f)(int);
fib_f(^fib_generator)(fib_f) = ^fib_f(fib_f recur) {
    return ^ull(int n) {
        if (n &amp;lt; 3) return 1;
        return recur(n-1) + recur(n-2);
    };
};
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is where the Y-Combinator comes in handy. The &lt;a href="http://mvanier.livejournal.com/2897.html" target="_blank"&gt;Y-Combinator&lt;/a&gt; is a function which enables recursion, using only anonymous functions, and without using recursion in its implementation. It looks somewhat like this (in Scheme):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(define Y 
  (lambda (f)
    ((lambda (x) (x x))
     (lambda (x) (f (lambda (y) ((x x) y)))))))
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;a href="http://mvanier.livejournal.com/2897.html" target="_blank"&gt;This article&lt;/a&gt; by Mike Vanier does a far better job of explaining the Y-Combinator than I ever could. Suffice to say that when called with a generator function, as defined above, the Y-Combinator will return the recursive &lt;code&gt;fib&lt;/code&gt; function. With the Y-Combinator, we could say:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;fib_f fib = Y(fib_generator);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Due to C&amp;#8217;s explicit typing, declaring higher-order functions can quickly become cumbersome, even with &lt;code&gt;typedef&lt;/code&gt;s. So in order to get around that, we&amp;#8217;re going to declare a single type to hold every function in our program. We&amp;#8217;re going to call it &lt;code&gt;_l&lt;/code&gt;, short for lambda.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;typedef union _l_t *_l;
typedef union _l_t {
    ull(^function_f)(int);
    _l(^generator_f)(_l);
} _l_t;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Wrapping the type in an union allows it to refer to itself. We&amp;#8217;ll be adding a couple more block types to this union shortly, but for now our only two options are: the signature of the fib function, and the generator which both takes and returns a lambda (containing a fib function, though that is unspecified).&lt;/p&gt;

&lt;p&gt;Since this type is declared as a pointer, it should live on the heap, and therefore we should write initializer functions for it:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;_l function(ull(^f)(int)) {
    _l data = malloc(sizeof(_l_t));
    data-&amp;gt;function_f = Block_copy(f);
    return data;
}
_l generator(_l(^f)(_l)) { /* ... same thing ... */ }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Let&amp;#8217;s ignore the fact that we&amp;#8217;re leaking tons of memory for a moment (we&amp;#8217;ll come back to that), and instead refactor our fib generator to use this new type:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;_l fib_generator = generator(^_l(_l recur) {
    return function(^ull(int n) {
        if (n &amp;lt;= 2) return 1;
        return recur-&amp;gt;function_f(n-1) + recur-&amp;gt;function_f(n-2);
    });
});
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In C, the basic Y-combinator above looks somewhat like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;_l y_combine(_l fn) {
    _l x = combiner(^_l(_l recur) {
        return function(^ull(int n) {
            _l resp = recur-&amp;gt;combiner_f(recur);
            return fn-&amp;gt;generator_f(resp)-&amp;gt;function_f(n);
        });
    });
    return x-&amp;gt;combiner_f(x);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You will also need to add the combiner function type to your union, and create a constructor for it:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;_l(^combiner_f)(_l);

_l combiner(_l(^f)(_l)) { /* ... same as above ... */ }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We now have all the pieces in place to use the Y-combinator to replace our natively recursive implementation of &lt;code&gt;fib&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;_l fibonacci = y_combine(fib_generator);
int upto = 20;
if (argc &amp;gt;= 2) upto = strtol(argv[1], NULL, 10);
ull fib = fibonacci-&amp;gt;function_f(upto);
printf("Fibonacci number %d is %llu.\n", upto, fib);
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Auto-release pools&lt;/h3&gt;

&lt;p&gt;As you have probably noticed, the code above is unfortunately leaking tons of memory. Many of the functions we&amp;#8217;ve written allocate &lt;code&gt;_l&lt;/code&gt; unions, and these are never released. While we could attempt to always correctly release these as soon as they are no longer needed, a more interesting solution is to use an auto-release pool.&lt;/p&gt;

&lt;p&gt;Auto-release pools are a concept familiar to Objective-C programmers, since they are used extensively in all of Apple&amp;#8217;s APIs. They work like this: You can create and flush pools, which nest like a stack. You can auto-release a pointer, which means that it is added to the topmost pool, and is freed when the pool is flushed.&lt;/p&gt;

&lt;p&gt;The simplest way of implementing auto-release pools is with two linked lists: the first to contain the objects that have been auto-released (this is the pool itself), and the second to contain the stack of pools. Lastly we&amp;#8217;re going to need a static variable to refer to the top of the pool stack.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;typedef struct autorelease_pool_t *autorelease_pool;
typedef struct autorelease_pool_t {
    void *p;
    void(*fn)(void*);
    autorelease_pool next;
} autorelease_pool_t;

typedef struct autorelease_pool_stack_t     *autorelease_pool_stack;
typedef struct autorelease_pool_stack_t {
    autorelease_pool head;
    autorelease_pool_stack parent;
} autorelease_pool_stack_t;

static autorelease_pool_stack current_pool = NULL;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Creating a pool is easy, we just allocate a reference and push it to the top of the stack:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;void push_autorelease_pool() {
    autorelease_pool_stack new_pool = malloc(sizeof(autorelease_pool_stack_t));
    new_pool-&amp;gt;parent = current_pool;
    new_pool-&amp;gt;head = NULL;
    current_pool = new_pool;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then we can write a function to add pointers to the pool. Since different types may have different free functions, we will also take a reference to the free function to use on the pointer as the second argument to the autorelease function:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;void autorelease(void *p, void(*fn)(void*)) {
    // If there is no current pool, we leak memory.
    if (current_pool == NULL) return;

    autorelease_pool head = malloc(sizeof(autorelease_pool_t));
    head-&amp;gt;p = p;
    head-&amp;gt;fn = fn;
    head-&amp;gt;next = current_pool-&amp;gt;head;
    current_pool-&amp;gt;head = head;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And finally, the magic happens when we flush the pool. We&amp;#8217;ll simply loop through the current pool, call each element&amp;#8217;s free function, and free the reference, and finally pop the pool off the stack:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;void flush_autorelease_pool() {
    while (current_pool-&amp;gt;head != NULL) {
        (*current_pool-&amp;gt;head-&amp;gt;fn)(current_pool-&amp;gt;head-&amp;gt;p);
        autorelease_pool next = current_pool-&amp;gt;head-&amp;gt;next;
        free(current_pool-&amp;gt;head);
        current_pool-&amp;gt;head = next;
    }
    autorelease_pool_stack parent = current_pool-&amp;gt;parent;
    free(current_pool);
    current_pool = parent;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now, in order to solve our memory leak issues in the code we wrote earlier, we must add code to auto-release the &lt;code&gt;_l&lt;/code&gt; unions we allocate, and wrap &lt;code&gt;main&lt;/code&gt; with an auto-release pool:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;_l function(ull(^f)(int)) {
    _l data = malloc(sizeof(_l_t));
    data-&amp;gt;function_f = Block_copy(f);

    // these two lines have been added:
    autorelease(data-&amp;gt;function_f, (void(*)(void*))&amp;amp;_Block_release);
    autorelease(data, &amp;amp;free);

    return data;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Since both y-combination and final execution allocate lambdas, we&amp;#8217;ll want to wrap both main, and then the final execution itself in an auto-release pool:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;int main(int argc, char **argv) {
    // wrap in pool
    push_autorelease_pool();

    // ...

    _l fibonacci = y_combine(fib_generator);
    // ...

    push_autorelease_pool();
    ull fib = fibonacci-&amp;gt;function_f(upto);
    flush_autorelease_pool();

    printf("Fibonacci number %d is %llu.\n", upto, fib);
    flush_autorelease_pool();
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Memoization: Wrapping&lt;/h3&gt;

&lt;p&gt;While our code is now fully functional (ha, ha, coder pun…), it still is horribly inefficient. That&amp;#8217;s because we still have not solved the inherent problem of the function having a time complexity of &lt;code&gt;O(2^n)&lt;/code&gt;. This can be solved using &lt;a href="https://en.wikipedia.org/wiki/Memoization" target="_blank"&gt;memoization&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Memoization is an optimization technique which consists of storing computations in memory when completed, so that they can be retrieved later on, instead of having to be re-computed. For &lt;code&gt;fib&lt;/code&gt;, using memoization reduces the time complexity down to &lt;code&gt;O(n)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In order to use memoization, we need a way to inject a function that will be executed before executing the &lt;code&gt;fib&lt;/code&gt; function. We&amp;#8217;ll call this wrapping, and as a first example, let&amp;#8217;s just use wrapping to demonstrate how bad &lt;code&gt;O(2^n)&lt;/code&gt; really is.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;_l wrap(_l fn, _l wrap_with) {
    return generator(^_l(_l recur) {
        return function(^ull(int n) {

            _l fn_ = function(^ull(int n) {
                return fn-&amp;gt;generator_f(recur)-&amp;gt;function_f(n);
            });
            _l wrapped = function(^ull(int n) {
                return wrap_with-&amp;gt;wrapper_f(fn_, n);
            });

            return wrapped-&amp;gt;function_f(n);
        });
    });
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Understanding this wrapping function still makes my brain hurt, but suffice to say that it takes a generator and a wrapper as arguments, and returns a generator. The resulting generator can be used in the Y-combinator, and every recursion of the original function will be replaced with a recursion of the wrapper function, which itself calls the original function.&lt;/p&gt;

&lt;p&gt;A simple wrapper function that will log every iteration looks like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;_l log_wrapper = wrapper(^ull(_l f, int n) {
    printf("About to generate # %d\n", n);
    return f-&amp;gt;function_f(n);
});
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And the final code that uses this looks like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;_l wrapped_fibonacci = y_combine(wrap(fib_generator, log_wrapper));
ull fib = wrapped_fibonacci-&amp;gt;function_f(upto);
printf("Fibonacci number %d is %llu.\n", upto, fib);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Your output should look &lt;a href="https://gist.github.com/kballenegger/5566093" target="_blank"&gt;somewhat like this&lt;/a&gt;. As you can see, calling &lt;code&gt;fib(20)&lt;/code&gt; evaluates the function 13,529 times.&lt;/p&gt;

&lt;h3&gt;Memoization: Implementation&lt;/h3&gt;

&lt;p&gt;In order to write a memoization wrapper function, we need a data structure in which to store the results. Most examples of memoization use a hash table, but since the key in our case is an integer, I decided to go for something a little more exotic: a binary tree, based on the bits of the integer key.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;typedef struct cache_node_t *cache_node;
typedef struct cache_node_t {
    bool is_leaf;
    union {
        struct {
            cache_node one;
            cache_node zero;
        } node;
        ull leaf;
    } self;
} cache_node_t;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We&amp;#8217;ll also create some simple methods to create and destroy trees:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cache_node cache_tree_new() {
    return calloc(1, sizeof(cache_node_t));
}
void cache_tree_free(cache_node node) {
    if (!node-&amp;gt;is_leaf) {
        if (node-&amp;gt;self.node.one != NULL) cache_tree_free(node-&amp;gt;self.node.one);
        if (node-&amp;gt;self.node.zero != NULL) cache_tree_free(node-&amp;gt;self.node.zero);
    }
    free(node);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In order to store a value in the tree, we iterate through every bit in the int, traversing either through the &lt;code&gt;one&lt;/code&gt; or &lt;code&gt;zero&lt;/code&gt; node of the tree, and finally setting the &lt;code&gt;leaf&lt;/code&gt; to the value we&amp;#8217;re trying to cache:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;void cache_tree_store(cache_node root, int key, ull value) {
    cache_node node = root;
    for (size_t i = 0; i &amp;lt; sizeof(int) * 8; i++) {
        bool direction = (bool)((key &amp;gt;&amp;gt; i) &amp;amp; (unsigned int)1);
        if (direction == 1) {
            if (node-&amp;gt;self.node.one == NULL) {
                node-&amp;gt;self.node.one = calloc(1, sizeof(cache_node_t));
            }
            node = node-&amp;gt;self.node.one;
        } else {
            if (node-&amp;gt;self.node.zero == NULL) {
                node-&amp;gt;self.node.zero = calloc(1, sizeof(cache_node_t));
            }
            node = node-&amp;gt;self.node.zero;
        }
    }
    // the last node should already be a leaf, if it isn't, we just created it
    if (!node-&amp;gt;is_leaf) {
        node-&amp;gt;is_leaf = true;
    }
    node-&amp;gt;self.leaf = value;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Looking up a value is essentially the same thing, with some additional code to report failures:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ull cache_tree_lookup(cache_node root, int key, bool *found) {
    cache_node node = root;
    for (size_t i = 0; i &amp;lt; sizeof(int) * 8; i++) {
        if (node == NULL || node-&amp;gt;is_leaf) {
            if (found) *found = false;
            return 0;
        }
        bool direction = (bool)((key &amp;gt;&amp;gt; i) &amp;amp; (unsigned int)1);
        if (direction == 1) {
            node = node-&amp;gt;self.node.one;
        } else {
            node = node-&amp;gt;self.node.zero;
        }
    }
    if (node == NULL || !node-&amp;gt;is_leaf) {
        if (found) *found = false;
        return 0;
    }
    if (found) *found = true;
    return node-&amp;gt;self.leaf;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And finally, now that we have a tree in which to store cached results, we can write our memoization function. Here, we&amp;#8217;re actually adding creating a function called &lt;code&gt;new_memoizer&lt;/code&gt; which returns a new instance of the wrapper function with its own (auto-released) cache.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;_l(^new_memoizer)() = ^_l {
    cache_node root = cache_tree_new();
    autorelease(root, (void(*)(void*))&amp;amp;cache_tree_free);

    return wrapper(^ull(_l f, int n) {
        bool found;
        ull cached = cache_tree_lookup(root, n, &amp;amp;found);
        if (found == true) {
            return cached;
        } else {
            ull value = f-&amp;gt;function_f(n);
            cache_tree_store(root, n, value);
            return value;
        }
    });
};
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So, with that, let&amp;#8217;s try our program again, but with memoization:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;_l fibonacci = y_combine(wrap(wrap(fib_generator, log_wrapper), new_memoizer()));

push_autorelease_pool();
ull fib = fibonacci-&amp;gt;function_f(upto);
flush_autorelease_pool();

printf("Fibonacci number %d is %llu.\n", upto, fib);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;As you can see in the output, this runs significantly faster:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Generate up to fib # 20...
About to generate # 20
About to generate # 19
About to generate # 18
About to generate # 17
About to generate # 16
About to generate # 15
About to generate # 14
About to generate # 13
About to generate # 12
About to generate # 11
About to generate # 10
About to generate # 9
About to generate # 8
About to generate # 7
About to generate # 6
About to generate # 5
About to generate # 4
About to generate # 3
About to generate # 2
About to generate # 1
Fibonacci number 20 is 6765.
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;You can peruse the final code used in this article in &lt;a href="https://gist.github.com/kballenegger/5566254" target="_blank"&gt;this gist&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now, that being said, if you ever have a need to implement a function to return a number in the Fibonacci sequence, it would be wise to forget everything I&amp;#8217;ve said above, and just use the following:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ull fib(int n) {
    if (n &amp;lt;= 2) return 1;
    ull first = 1, second = 1, tmp;
    while (--n&amp;gt;1) {
        tmp = first + second;
        first = second;
        second = tmp;
    }
    return second;
}
&lt;/code&gt;&lt;/pre&gt;&lt;img src="http://feeds.feedburner.com/~r/seoxys/~4/G3lb64j3TR8" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/seoxys/~3/G3lb64j3TR8/50429268286</link><guid isPermaLink="false">http://kswizz.com/post/50429268286</guid><pubDate>Tue, 14 May 2013 10:20:08 -0700</pubDate><category>articles</category><category>programming</category><category>development</category><feedburner:origLink>http://kswizz.com/post/50429268286</feedburner:origLink></item><item><title>Liza Long writes about her mentally ill child:


  I am sharing this story because I am Adam...</title><description>&lt;p&gt;Liza Long writes &lt;a href="http://slog.thestranger.com/slog/archives/2012/12/15/i-am-adam-lanzas-mother" target="_blank"&gt;about her mentally ill child&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;I am sharing this story because I am Adam Lanza&amp;#8217;s mother. I am Dylan Klebold&amp;#8217;s and Eric Harris&amp;#8217;s mother. I am Jason Holmes&amp;#8217;s mother. I am Jared Loughner&amp;#8217;s mother. I am Seung-Hui Cho&amp;#8217;s mother. And these boys—and their mothers—need help. In the wake of another horrific national tragedy, it’s easy to talk about guns. But it’s time to talk about mental illness.&lt;/p&gt;
&lt;/blockquote&gt;&lt;img src="http://feeds.feedburner.com/~r/seoxys/~4/BO6GXC9frGs" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/seoxys/~3/BO6GXC9frGs/38081607348</link><guid isPermaLink="false">http://kswizz.com/post/38081607348</guid><pubDate>Sun, 16 Dec 2012 11:18:50 -0800</pubDate><category>politics</category><feedburner:origLink>http://kswizz.com/post/38081607348</feedburner:origLink></item><item><title>Web 3.0 at Chartboost</title><description>&lt;a href="http://blog.chartboost.com/post/36221629171/web-3-0-help-site"&gt;Web 3.0 at Chartboost&lt;/a&gt;: &lt;p&gt;&lt;em&gt;This is an article I originally wrote for the Chartboost blog.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;For the sake of brevity, we’re going to dub the next generation of web app development “Web 3.0.” This entails a collection of new technologies and new ideas, which have become possible only recently with the large advances made by modern browsers.&lt;/p&gt;

&lt;p&gt;What does this mean? This means creating web &lt;em&gt;applications&lt;/em&gt;, not sites. We believe the server side is a web &lt;em&gt;service&lt;/em&gt;, while the client side is the &lt;em&gt;application&lt;/em&gt;. The server provides an API, and the client is a self-contained app which uses this API. A mobile app would be an equal citizen and use the exact same API.&lt;/p&gt;

&lt;p&gt;We think these ideas are the future, and as we grow our team and our capabilities, we are diving into them head first. The first of these projects—and somewhat of a testbed for what our dashboard is going to become—is none other than the new &lt;a href="https://help.chartboost.com" target="_blank"&gt;Chartboost Help site&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img alt="Help Site on an iPhone" src="//chartboost.s3.amazonaws.com/blog_images/desktop.png" class="bleed" style="
"&gt;&lt;/p&gt;

&lt;p style="
font-style: italic;
"&gt;The help site.&lt;/p&gt;

&lt;p&gt;So without further ado, these are some of the cool new things we’re trying with the new help site:&lt;/p&gt;

&lt;h5&gt;Push State&lt;/h5&gt;

&lt;p&gt;Perhaps the first thing you will notice is that navigating the site does not involve any page refreshes. Rather, this is done through a new technology called “Push State.” It lets a web app manipulate the browser history, essentially faking navigation and inserting its own JavaScript callbacks instead of reloads.&lt;/p&gt;

&lt;p&gt;When moving between pages, the HTML is never replaced, which means that elements of the app can stay on screen, and even be animated, while the new content is being loaded. On the help site, a great example of this is the animation in the title part of the content, as well as the bouncing icons on the left.&lt;/p&gt;

&lt;p&gt;This also makes the entire site feel more responsive and faster, since the user can be kept busy with animations, while a request to the server is happening in the background. That, and the requests are much smaller, since all that’s needed is the article content, and none of the layout or supporting files. Routing is done purely in JavaScript, and loading any URL natively from the server simply returns the same HTML file and routing code, which knows how to directly load the requested article.&lt;/p&gt;

&lt;h5&gt;JSON-API driven&lt;/h5&gt;

&lt;p&gt;This goes hand in hand with the above: now that we don’t require fully rendered HTML pages to be returned from the server, the server can now simply provide an elegant REST API. This API uses the full power of HTTP: versioning and authentication is done through headers, input is sent as JSON in the request body, and HTTP verbs are used.&lt;/p&gt;

&lt;h5&gt;Responsive&lt;/h5&gt;

&lt;p&gt;In an ever-connected world, and with the proliferation of mobile devices from smartphones to tablets, we think it’s becoming ever more important for the web to look its best on every device out there. Mobile-optimized sites just don’t cut it; a smartphone deserves to have the same full experience as a widescreen desktop computer.&lt;/p&gt;

&lt;p&gt;&lt;img alt="Help Site on an iPhone" src="//chartboost.s3.amazonaws.com/blog_images/mobile.png" class="bleed" style="
"&gt;&lt;/p&gt;

&lt;p style="
font-style: italic;
"&gt;The help site, on an iPhone.&lt;/p&gt;

&lt;p&gt;The help site, as well as this very blog, are responsive designs. They adjust and are fully functional on all devices from iPhone to Cinema Displays. To achieve that, we make use of CSS &lt;code&gt;@media&lt;/code&gt; queries as well as &lt;code&gt;rem&lt;/code&gt; and percent-based sizing. We used the &lt;a href="http://foundation.zurb.com/" target="_blank"&gt;Foundation&lt;/a&gt; framework for its built-in responsive grid.&lt;/p&gt;

&lt;h5&gt;Vector (Icon Fonts &amp; CSS)&lt;/h5&gt;

&lt;p&gt;Another big recent change is the proliferation of “retina” (high-resolution) screens. They’ve been around for a while on iPhones, and are now expanding to Android devices, tablets, and computers. This is most commonly done by doubling the pixel-to-point ratio, and on iOS it is common to include double resolution assets by suffixing &lt;code&gt;@2x&lt;/code&gt; to the image name.&lt;/p&gt;

&lt;p&gt;We think, however, that for UI work, native rendering and vector are much better options than images. So for the help site, we use a combination of icon fonts and CSS3 properties to build up the entirety of the UI. &lt;strong&gt;There are practically no images in the help site’s UI!&lt;/strong&gt;&lt;/p&gt;

&lt;h5&gt;SCSS&lt;/h5&gt;

&lt;p&gt;Another new technology we’ve made use of is CSS-preprocessing, through &lt;a href="http://sass-lang.com/" target="_blank"&gt;SCSS&lt;/a&gt;. This helps make our CSS code a lot cleaner and re-usable: using mixins (which are kind of like functions) for common prefixed properties, and variable dependencies on colors:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$button-green-one-textcolor : #FFFFFF;
$button-green-one-border : saturate(darken($primary-    color,11%), 1%);
$button-green-one-light-inset : #FFFFFF; /* Will be used inside an RGBA with opacity */
$button-green-bg-gradient-start : darken($primary-color, 1%);
$button-green-bg-gradient-end : saturate(lighten($primary-color, 7%), 7.5%); 
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You might have noticed that this blog and the new help site look similar. They actually share the same SCSS source, with only few differences, like the primary color being changes from blue to green. That, along with some other neat SCSS features like nesting allow for much cleaner and much more reusable CSS code.&lt;/p&gt;

&lt;h5&gt;Markdown&lt;/h5&gt;

&lt;p&gt;We believe the entire team should be able to write and edit help articles. &lt;a href="https://en.wikipedia.org/wiki/Markdown" target="_blank"&gt;Markdown&lt;/a&gt; is a fantastically simple markup language designed around the idea that it should look like plain text. A Markdown source file should be as readable as the output it produces; and indeed, it is far more natural to write in Markdown than HTML. Thus, our help articles are written in &lt;a href="http://github.github.com/github-flavored-markdown/" target="_blank"&gt;GitHub-flavored Markdown&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Since our documentation contains a fair amount of code samples, it was important for us to support GitHub-style code blocks, as well as native syntax highlighting. As a simple example, here is our &lt;a href="https://help.chartboost.com/documentation/ios" target="_blank"&gt;iOS Integration article&lt;/a&gt;, and its &lt;a href="https://raw.github.com/ChartBoost/articles/master/documentation/ios/index.md" target="_blank"&gt;source code&lt;/a&gt;.&lt;/p&gt;

&lt;h5&gt;GitHub&lt;/h5&gt;

&lt;p&gt;Help content, much like source code, is something that multiple people collaborate on, and which can benefit from versioning and branching. Instead of re-inventing the wheel ourselves, we decided to pick a tool we already use every day as a team: git and &lt;a href="https://www.github.com/" target="_blank"&gt;GitHub&lt;/a&gt;. The source code for all of our help articles (and its messy history) is all hosted publicly on our GitHub. &lt;a href="https://www.github.com/ChartBoost/articles" target="_blank"&gt;Check it out!&lt;/a&gt; And who knows, maybe somebody will even send us a Pull Request at some point.&lt;/p&gt;

&lt;h5&gt;Design&lt;/h5&gt;

&lt;p&gt;&lt;img alt="Help Site on an iPhone" src="//chartboost.s3.amazonaws.com/blog_images/sketches.png" class="bleed" style="
"&gt;&lt;/p&gt;

&lt;p style="
font-style: italic;
"&gt;Original paper sketches&lt;/p&gt;

&lt;p&gt;Going into it, we knew design was going to be a crucial part of this. What we had before really sucked, and was not up to our standard.&lt;/p&gt;

&lt;p&gt;&lt;img alt="Help Site on an iPhone" src="//chartboost.s3.amazonaws.com/blog_images/mocks.png" class="bleed" style="
"&gt;&lt;/p&gt;

&lt;p style="
font-style: italic;
"&gt;Alternate directions&lt;/p&gt;

&lt;p&gt;We went through several iterations over a week, before settling on the current design.&lt;/p&gt;

&lt;hr&gt;&lt;p&gt;We believe that the web is finally reaching a tipping point. The culmination of a decade of incremental improvements to web technologies is upon us, and lets us do things in a way that is radically new and better. If this is as exciting to you as it is to us, why don’t you throw us a line? &lt;a href="https://chartboost.com/web/jobs" target="_blank"&gt;We’re hiring!&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/seoxys/~4/P6uco6ipzUI" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/seoxys/~3/P6uco6ipzUI/36222697891</link><guid isPermaLink="false">http://kswizz.com/post/36222697891</guid><pubDate>Wed, 21 Nov 2012 10:48:02 -0800</pubDate><category>release</category><category>articles</category><category>development</category><feedburner:origLink>http://kswizz.com/post/36222697891</feedburner:origLink></item><item><title>"Even as I was watching “Cloud Atlas” the first time, I knew I would need to see it..."</title><description>“Even as I was watching “Cloud Atlas” the first time, I knew I would need to see it again. Now that I’ve seen it the second time, I know I’d like to see it a third time — but I no longer believe repeated viewings will solve anything. To borrow Churchill’s description of Russia, it is a riddle, wrapped in a mystery, inside an enigma.”&lt;br/&gt;&lt;br/&gt; - &lt;em&gt;&lt;a href="http://rogerebert.suntimes.com/apps/pbcs.dll/article?AID=/20121024/REVIEWS/121029991" target="_blank"&gt;Roger Ebert&lt;/a&gt;&lt;/em&gt;&lt;img src="http://feeds.feedburner.com/~r/seoxys/~4/cZ3mbyNg0Zw" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/seoxys/~3/cZ3mbyNg0Zw/35193521663</link><guid isPermaLink="false">http://kswizz.com/post/35193521663</guid><pubDate>Wed, 07 Nov 2012 00:35:00 -0800</pubDate><feedburner:origLink>http://kswizz.com/post/35193521663</feedburner:origLink></item><item><title>I went crabbing for the first time today. Caught, cooked, and...</title><description>&lt;img src="http://24.media.tumblr.com/tumblr_ma2tf259Q41qae51go1_500.png"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;I went crabbing for the first time today. Caught, cooked, and ate this crab, along with eight others. I highly recommend it, it’s a very rewarding experience, and tons of fun!&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/seoxys/~4/sPmCzjSWfYs" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/seoxys/~3/sPmCzjSWfYs/31188891966</link><guid isPermaLink="false">http://kswizz.com/post/31188891966</guid><pubDate>Sun, 09 Sep 2012 02:37:00 -0700</pubDate><category>photography</category><feedburner:origLink>http://kswizz.com/post/31188891966</feedburner:origLink></item><item><title>Richard Muller for the Wall Street Journal on the Fukushima incident:


  But over the following...</title><description>&lt;p&gt;Richard Muller for the Wall Street Journal &lt;a href="http://online.wsj.com/article/SB10000872396390444772404577589270444059332.html?mod=WSJ_hps_LEFTTopStories" target="_blank"&gt;on the Fukushima incident&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;But over the following weeks and months, the fear grew that the ultimate victims of this damaged nuke would number in the thousands or tens of thousands. The &amp;#8220;hot spots&amp;#8221; in Japan that frightened many people showed radiation at the level of .1 rem, a number quite small compared with the average excess dose that people happily live with in Denver.&lt;/p&gt;
  
  &lt;p&gt;What explains the disparity? Why this enormous difference in what is considered an acceptable level of exposure to radiation?&lt;/p&gt;
  
  &lt;p&gt;In hindsight, it is hard to resist the conclusion that the policies enacted in the wake of the disaster in Japan—particularly the long-term evacuation of large areas and the virtual termination of the Japanese nuclear power industry—were expressions of panic. I would go further and suggest that these well-intended measures did far more harm than good, not least in limiting the prospects of a source of energy that is safe, abundant and (as compared with its rivals) relatively benign for the environmental health of our planet.&lt;/p&gt;
  
  &lt;p&gt;The reactor at Fukushima wasn&amp;#8217;t designed to withstand a 9.0 earthquake or a 50-foot tsunami. Surrounding land was contaminated, and it will take years to recover. But it is remarkable how small the nuclear damage is compared with that of the earthquake and tsunami. The backup systems of the nuclear reactors in Japan (and in the U.S.) should be bolstered to make sure this never happens again. We should always learn from tragedy. But should the Fukushima accident be used as a reason for putting an end to nuclear power?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I think it&amp;#8217;s clear at this point that the answer is a resounding &amp;#8220;No!&amp;#8221; It&amp;#8217;s a real shame that our world&amp;#8217;s populace is so misinformed and afraid that we are essentially putting an end to nuclear power. Nuclear energy as a large-scale clean power source has no practical alternative; so shutting it down essentially means reverting to burning coal, which is quickly destroying our planet.&lt;/p&gt;

&lt;p&gt;If anything, Fukushima should have shown us that it&amp;#8217;s time to double down on nuclear, and use it to replace our planet-burning coal and gas plants.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/seoxys/~4/XEElc7ji6Og" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/seoxys/~3/XEElc7ji6Og/29710575030</link><guid isPermaLink="false">http://kswizz.com/post/29710575030</guid><pubDate>Sat, 18 Aug 2012 13:51:00 -0700</pubDate><category>politics</category><feedburner:origLink>http://kswizz.com/post/29710575030</feedburner:origLink></item><item><title>A critique of the Apple indie developer community</title><description>&lt;p&gt;The Apple developer community has bred some of the most skilled engineers I know. Specifically, I&amp;#8217;m talking about those who, like me, were writing Objective-C code before the iPhone and before there was any money in it.&lt;/p&gt;

&lt;p&gt;Objective-C is a hard language to learn. It&amp;#8217;s unsafe, manually memory managed, and full of easy mistakes. But once learnt, it&amp;#8217;s one of the most rewarding programming languages to know. It will teach you about fundamental concepts like memory, pointers, and object-orientation. Indie developers also have Apple&amp;#8217;s mostly exemplary lead when it comes to crafting easy to use software. It&amp;#8217;s no wonder, then, that skilled independent Mac and iPhone developers make some of the best software I&amp;#8217;ve had the pleasure of using.&lt;/p&gt;

&lt;p&gt;And yet, for all of their application-crafting prowesses, they fail to understand the internet. They look at every problem as a nail for their Cocoa hammer. We&amp;#8217;ve moved beyond the point where software is downloaded and installed, and simply runs on the host computer. Today, software is social, cloud-hosted, and continuously updated. When&amp;#8217;s the last time you updated Chrome? Right… Never, because it updates itself transparently. Even apps that would traditionally have been perfect candidates for a desktop application, such as a &lt;a href="http://culturedcode.com/things/" target="_blank"&gt;todo manager&lt;/a&gt;, are moving onto the cloud.&lt;/p&gt;

&lt;p&gt;We have many computing devices; Macs, iPhones, and iPads, and we want to be able to pick up any of them and have access to our data. They need to sync instantly and effortlessly. This means that they require a backend web software component. This means running and maintaining servers. Writing code in a foreign programming language and dealing with a wholly new class of problems. (How do you scale your backend software? Which language / platform / framework do you use? At which point do you re-architect for a distributed system? Wait, this shit runs on &lt;em&gt;Linux&lt;/em&gt;?)&lt;/p&gt;

&lt;p&gt;Your average indie Mac developer is wholly unprepared for this. He&amp;#8217;s been living in a perfect and comfortable little bubble, shielded from the ugliness of web programming, and the cloud just popped it.&lt;/p&gt;

&lt;p&gt;Take Panic&amp;#8217;s &lt;a href="http://www.panic.com/Coda/" target="_blank"&gt;Coda&lt;/a&gt;, for example. I really hate to criticize Panic, because they&amp;#8217;re probably one of the best development shop out there. But Coda is an example of this mentality; it&amp;#8217;s built for a world where web development meant throwing a website together with Apache, PHP, and MySQL. And when it came to interacting with software, the &lt;a href="http://weblog.rogueamoeba.com/2012/06/30/the-developer-news-window/" target="_blank"&gt;backend for Mac software&lt;/a&gt; would simply be a &lt;code&gt;.php&lt;/code&gt; file that generated a &lt;a href="https://en.wikipedia.org/wiki/Plist" target="_blank"&gt;property list&lt;/a&gt;. But that world died back in the mid-&amp;#8217;00s. Today, web development involves MVC, newer NoSQL data stores, caching layers, load balancing, message queues, background job processing, service-oriented architectures, version control (git), code deployment systems, and so on. These make the Coda approach of editing PHP files on a live server and checking the output in a preview tab completely obsolete.&lt;sup id="fnref:p28710957277-1"&gt;&lt;a href="#fn:p28710957277-1" rel="footnote" target="_blank"&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;Independent developers wanting to get in on the cloud action have been avoiding the problem, by taking the approach of building third-party clients for first-party providers. Witness the inundation of the app stores with client apps for Twitter, Instagram, or Google Reader. There&amp;#8217;s even a series of app that use a Dropbox folder as an alternative to a web backend. That&amp;#8217;s all well and good, and the community makes some fantastic client software that I use daily, but that approach can backfire when the first-party provider changes its mind. When Twitter decides to kill access to its API, or when Apple decides to throw you off their store for a bullshit reason.&lt;/p&gt;

&lt;p&gt;I grew up writing Mac applications, and I used to be very involved in the Apple developer community. To this day, Objective-C remains my favorite programming language for its speed, power, and elegance. And yet, I&amp;#8217;ve lost touch with the community as I moved beyond just Cocoa software. I realized that there&amp;#8217;s more to be done. I didn&amp;#8217;t want to spend the rest of my life writing client software, I wanted to write the next world-changing service that spawns countless clients. And that was never going to happen writing just Cocoa software.&lt;/p&gt;

&lt;p&gt;There&amp;#8217;s a ton of smart people doing great things in the wider software development community that Apple developers could learn from. And inversely, the rest of the software development community could greatly benefit from an influx of smart and quality-driven Cocoa developers. My hope is that Cocoa developers will come to embrace polyglotism and web software and make software that truly makes a difference.&lt;/p&gt;

&lt;div class="footnotes"&gt;
&lt;hr&gt;&lt;ol&gt;&lt;li id="fn:p28710957277-1"&gt;
&lt;p&gt;It could be said that Coda is just not meant for web developers, it&amp;#8217;s meant for making restaurant websites… &lt;a href="#fnref:p28710957277-1" rev="footnote" target="_blank"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;

&lt;/ol&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/seoxys/~4/3tibTnRudjc" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/seoxys/~3/3tibTnRudjc/28710957277</link><guid isPermaLink="false">http://kswizz.com/post/28710957277</guid><pubDate>Sat, 04 Aug 2012 11:43:00 -0700</pubDate><category>articles</category><category>development</category><feedburner:origLink>http://kswizz.com/post/28710957277</feedburner:origLink></item><item><title>I have the best job in the world.

Every day, I show up to work and create something awesome....</title><description>&lt;p&gt;I have the best job in the world.&lt;/p&gt;

&lt;p&gt;Every day, I show up to work and create something awesome. It&amp;#8217;s like being a kid again except this time, instead of Lego bricks, the building blocks are Objective-C blocks, WebSockets and ØMQ. Clojure, Ruby, and Assembly. I make things that I want to use. I solve problems for the sake of curiosity. I&amp;#8217;m like a child in Disneyland, having the time of my life, and I&amp;#8217;m being paid to do it.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;m not doing it because it will make me a bajillionaire. It will, eventually, but that&amp;#8217;s besides the point. I do it because I absolutely love being a programmer. I&amp;#8217;d spend my time hacking even if it wasn&amp;#8217;t my day job. Until recently, actually, it wasn&amp;#8217;t. I was three years into a degree in graphic design when I decided that I really wanted to spend my days working on making cool stuff and solving hard problems.&lt;/p&gt;

&lt;p&gt;Sure, it&amp;#8217;s stressful sometimes. Meetings can eat into your productivity and Mongo can wake you up at two in the morning when an onslaught of asian traffic brings it to its knees. But at the end of the day, these are good problems to have.&lt;/p&gt;

&lt;p&gt;If you don&amp;#8217;t love your job; if you don&amp;#8217;t think it&amp;#8217;s the most interesting thing you could be doing right now; if you don&amp;#8217;t feel immensely grateful at the universe for having such an awesome gig… quit! Right fucking now. Money, mortgages, degrees, social expectations and obligations are just distractions. A waste of time. Humans are incredibly resilient creatures; we can figure pretty much anything out on the fly. The world is a fantastic place to be, and right now is probably the best time yet to be in it, so why waste your time selling sugared water?&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/seoxys/~4/fDJPqC_70lw" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/seoxys/~3/fDJPqC_70lw/24615424676</link><guid isPermaLink="false">http://kswizz.com/post/24615424676</guid><pubDate>Thu, 07 Jun 2012 09:38:12 -0700</pubDate><category>articles</category><feedburner:origLink>http://kswizz.com/post/24615424676</feedburner:origLink></item><item><title>





As final project for my Advanced Motion Graphics class, I produced the above set of 3 personal...</title><description>&lt;p class="embed"&gt;&lt;iframe src="http://player.vimeo.com/video/41453548?title=0&amp;amp;byline=0&amp;amp;portrait=0&amp;amp;color=ffffff" width="600" height="338" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen&gt;&lt;/iframe&gt;&lt;/p&gt;

&lt;p class="embed"&gt;&lt;iframe src="http://player.vimeo.com/video/41454053?title=0&amp;amp;byline=0&amp;amp;portrait=0&amp;amp;color=ffffff" width="600" height="338" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen&gt;&lt;/iframe&gt;&lt;/p&gt;

&lt;p class="embed"&gt;&lt;iframe src="http://player.vimeo.com/video/41456664?title=0&amp;amp;byline=0&amp;amp;portrait=0&amp;amp;color=ffffff" width="600" height="338" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen&gt;&lt;/iframe&gt;&lt;/p&gt;

&lt;p&gt;As final project for my Advanced Motion Graphics class, I produced the above set of 3 personal idents.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/seoxys/~4/pm7tn2yRT4M" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/seoxys/~3/pm7tn2yRT4M/24273779061</link><guid isPermaLink="false">http://kswizz.com/post/24273779061</guid><pubDate>Sat, 02 Jun 2012 11:13:00 -0700</pubDate><category>schoolwork</category><feedburner:origLink>http://kswizz.com/post/24273779061</feedburner:origLink></item><item><title>Stones</title><description>&lt;p class="embed"&gt;&lt;iframe src="http://player.vimeo.com/video/39797597?title=0&amp;amp;byline=0&amp;amp;portrait=0&amp;amp;color=ffffff" width="600" height="338" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen&gt;&lt;/iframe&gt;&lt;/p&gt;

&lt;p&gt;This was an exercise in synchronizing motion to audio. As a school project this past semester, we were all assignments parts of Anon Day&amp;#8217;s song Stones to produce a piece of video for. This was the intro.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/seoxys/~4/Dfv4nWyAPjU" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/seoxys/~3/Dfv4nWyAPjU/24273615778</link><guid isPermaLink="false">http://kswizz.com/post/24273615778</guid><pubDate>Sat, 02 Jun 2012 11:11:00 -0700</pubDate><category>schoolwork</category><feedburner:origLink>http://kswizz.com/post/24273615778</feedburner:origLink></item><item><title>Scylla Absinthe</title><description>&lt;p&gt;&lt;a href="http://akhun.com/seo/skitch/IMG_2137-20120526-153051.png" target="_blank"&gt;&lt;img src="http://akhun.com/seo/skitch/IMG_2137-20120526-152110.png"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This was a project for my packaging design class, this past semester. Starting from scratch, I designed the entire story and identity. Illustration was done by the incredibly talented &lt;a href="http://www.brianmutschler.com/" target="_blank"&gt;Brian Mutschler&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Scylla is said to once have been a nymph so beautiful that Poseidon, the great god of the seas, fell madly in love with her. Scylla, not reciprocating the feeling, fled to the dry land, where he could not follow. Angry at her betrayal, Poseidon cursed her and transformed her into a monster, to forever haunt the sea. Eons later, a mercenary of the crusades from Couvet, Switzerland got caught at sea in a terrible storm and wrecked onto Scylla&amp;#8217;s reef. Scylla rescued and nurtured him and they fell in love. When another ship finally came to the rescue, Scylla gave him the recipe to an elixir which, when ingested, would instantly bring her image to life in his mind. To this day, his great great grand children distill this very same elixir.&lt;/p&gt;
&lt;/blockquote&gt;&lt;img src="http://feeds.feedburner.com/~r/seoxys/~4/aocSouQitXM" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/seoxys/~3/aocSouQitXM/23823046210</link><guid isPermaLink="false">http://kswizz.com/post/23823046210</guid><pubDate>Sat, 26 May 2012 15:32:02 -0700</pubDate><category>schoolwork</category><category>photography</category><feedburner:origLink>http://kswizz.com/post/23823046210</feedburner:origLink></item><item><title>WWDC</title><description>&lt;p&gt;This story will sound familiar to a lot of people this morning, I fear: I woke up to a handful of text messages, emails and IM messages saying Apple had opened sales for WWDC tickets at 5:30 am. I frantically jumped out of bed and to my computer, to try and buy one immediately. Of course, as it were, all tickets were sold out.&lt;/p&gt;

&lt;p&gt;The rules this year around state that a personal Apple developer account can only get one ticket, and a company account can get five. Tickets are non-transferable to and non-refundable prevent scalping.&lt;/p&gt;

&lt;p&gt;I appreciate the fact that Apple is trying to prevent scalping, and tickets going on sale for double the price on Ebay and Craigslist, but I think they&amp;#8217;ve only exacerbated the problem. Now, legitimate developers such as myself do not even have a third-party recourse to buy a ticket at a premium.&lt;/p&gt;

&lt;p&gt;Here are some things Apple could have done instead:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;&lt;p&gt;If first-come first-served is really the approach they wanted, a better way would have been to announce when the tickets go on sale in advance, and let everybody set their alarm and fairly race for the ticket.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;They could have staggered the ticket sales over the course of the day; making 500 new tickets available every hour.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;They could have used a criteria other than luck to decide who gets a ticket. Perhaps limit it to developers that have apps in the store, developers who can solve a programming puzzle. Even an application where developers have to state what they hope to get out of the conference.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;They could have solved the supply / demand problem by making the price proportional to the amount of tickets left. Every ticket sold augments the value of the remaining tickets. The 1000th ticket could have been worth $2250, the 2000th $3000, and so on, going up in price as the supply dwindles.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;I don&amp;#8217;t think any of these solutions are perfect. But I think any of them would have been better than the way Apple chose to go, screwing legitimate west-coast developers out of the most important conference and learning experience of the year.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/seoxys/~4/74U1Uzh8n7o" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/seoxys/~3/74U1Uzh8n7o/21793314740</link><guid isPermaLink="false">http://kswizz.com/post/21793314740</guid><pubDate>Wed, 25 Apr 2012 11:44:00 -0700</pubDate><category>rant</category><category>development</category><feedburner:origLink>http://kswizz.com/post/21793314740</feedburner:origLink></item><item><title>Human stupidity in all of its beautiful glory.</title><description>&lt;iframe width="400" height="225" src="http://www.youtube.com/embed/lUZ-e2SkeMI?wmode=transparent&amp;autohide=1&amp;egm=0&amp;hd=1&amp;iv_load_policy=3&amp;modestbranding=1&amp;rel=0&amp;showinfo=0&amp;showsearch=0" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;Human stupidity in all of its beautiful glory.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/seoxys/~4/8BaT0qOqmug" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/seoxys/~3/8BaT0qOqmug/21401142393</link><guid isPermaLink="false">http://kswizz.com/post/21401142393</guid><pubDate>Thu, 19 Apr 2012 15:25:46 -0700</pubDate><feedburner:origLink>http://kswizz.com/post/21401142393</feedburner:origLink></item><item><title>Sexism</title><description>&lt;p&gt;It&amp;#8217;s often claimed that we are creating a negative environment for women in tech, through the way we like to have fun and blow off steam. A startup is an intensely stressful environment, and staying sane is crucial. In-jokes, brogramming, and good-natured debauchery is a way to do that. If somebody cannot handle some crudeness, I&amp;#8217;d postulate that he or she does not belong at a startup, regardless of gender. Because, when shit hits the fan, as it invariably does, we need people who can take it.&lt;/p&gt;

&lt;p&gt;Recently, a developer was forced to &lt;a href="https://github.com/whit537/assertEquals/blob/master/ANNOUNCEMENT.rst#readme" target="_blank"&gt;rename his open source project&lt;/a&gt;, because &amp;#8220;testosterone&amp;#8221; wasn&amp;#8217;t politically correct enough. I&amp;#8217;ve talked before about the &lt;a href="http://kswizz.com/post/8275502957/hypocrisy" target="_blank"&gt;hypocrisy&lt;/a&gt; of our constant striving for political correctness—but that&amp;#8217;s an entirely different argument altogether. My goal in life is not to please everybody. Sometimes I&amp;#8217;m vulgar. If I call something &amp;#8220;retarded&amp;#8221; or &amp;#8220;idiotic,&amp;#8221; it should be obvious that it has nothing to do with people afflicted with Down&amp;#8217;s syndrome. In my opinion, when people call it out, the correct response really &lt;em&gt;should be&lt;/em&gt; &lt;a href="http://therealkatie.net/blog/2012/mar/21/lighten-up/" target="_blank"&gt;lighten up&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We cannot beat sexism until gender is no longer an issue. Keeping up the current level of discourse is making things &lt;em&gt;worse&lt;/em&gt;. Subsidizing women in tech with money, like Etsy &lt;a href="http://www.etsy.com/hacker-grants" target="_blank"&gt;is doing&lt;/a&gt;, is widening the gap between men and women. By doing this, you&amp;#8217;re not only admitting that women cannot make it in tech without some extra help, you&amp;#8217;re also effectively creating inequality, affirmative-action style.&lt;/p&gt;

&lt;p&gt;Equality, by the way, does not mean gender balance. It means equal opportunity. It means that a woman will not be passed over for a job because of her gender. It means that she has as much of a shot at becoming the next Zuckerberg as I do. It does not mean her company will never produce sexy ads, or use booth babes, or have a tightly knit group of programmers who like to drink beer and jokingly call themselves &amp;#8220;brogrammers.&amp;#8221;&lt;/p&gt;

&lt;p&gt;I&amp;#8217;m tired of being told, over and over again, that I&amp;#8217;m a sexist pig because I&amp;#8217;m not in favor of achieving an artificial gender balance. I&amp;#8217;m tired of being called a homophobe, or a racist, sexist, or even a nazi because I said something that&amp;#8217;s technically not politically correct—even though my statement had absolutely nothing to do with any of the groups offended.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Again, these are my own controversial opinions, and in no way reflect my employer&amp;#8217;s.&lt;/em&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/seoxys/~4/zvPcjc9Iknc" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/seoxys/~3/zvPcjc9Iknc/21280005474</link><guid isPermaLink="false">http://kswizz.com/post/21280005474</guid><pubDate>Tue, 17 Apr 2012 12:51:00 -0700</pubDate><category>rant</category><category>politics</category><feedburner:origLink>http://kswizz.com/post/21280005474</feedburner:origLink></item><item><title>A fractal of bad design</title><description>&lt;a href="http://me.veekun.com/blog/2012/04/09/php-a-fractal-of-bad-design/"&gt;A fractal of bad design&lt;/a&gt;: &lt;p&gt;Alex Munroe:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;I can’t even say what’s wrong with PHP, because— okay. Imagine you have uh, a toolbox. A set of tools. Looks okay, standard stuff in there.&lt;/p&gt;
  
  &lt;p&gt;You pull out a screwdriver, and you see it’s one of those weird tri-headed things. Okay, well, that’s not very useful to you, but you guess it comes in handy sometimes.&lt;/p&gt;
  
  &lt;p&gt;You pull out the hammer, but to your dismay, it has the claw part on both sides. Still serviceable though, I mean, you can hit nails with the middle of the head holding it sideways.&lt;/p&gt;
  
  &lt;p&gt;You pull out the pliers, but they don’t have those serrated surfaces; it’s flat and smooth. That’s less useful, but it still turns bolts well enough, so whatever.&lt;/p&gt;
  
  &lt;p&gt;And on you go. Everything in the box is kind of weird and quirky, but maybe not enough to make it completely worthless. And there’s no clear problem with the set as a whole; it still has all the tools.&lt;/p&gt;
  
  &lt;p&gt;Now imagine you meet millions of carpenters using this toolbox who tell you “well hey what’s the problem with these tools? They’re all I’ve ever used and they work fine!” And the carpenters show you the houses they’ve built, where every room is a pentagon and the roof is upside-down. And you knock on the front door and it just collapses inwards and they all yell at you for breaking their door.&lt;/p&gt;
  
  &lt;p&gt;That’s what’s wrong with PHP.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;PHP can be used to build some awesome stuff (Facebook is living proof!), but it’s important to realize that it’s also a fundamentally awful language.  It’s like crack. It’s useful enough that it keeps us using it over and over again, while systematically destroying our productivity with its quirks.&lt;/p&gt;

&lt;p&gt;When I complain about PHP at work, some like to remind me that I’m a hypocrite, since I wrote a blog post &lt;a href="http://kswizz.com/post/4616115078/php-agile-development" target="_blank"&gt;praising PHP&lt;/a&gt;. Or, rather, claiming that it’s possible to code PHP smartly and avoid its pitfalls. I’m not sure if I still agree with it today, but I sure do feel my brain turning to Jell-O whenever PHP fucks me over with one of its silly, silly idiosyncrasies.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/seoxys/~4/KEI-o99SOGo" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/seoxys/~3/KEI-o99SOGo/20853612338</link><guid isPermaLink="false">http://kswizz.com/post/20853612338</guid><pubDate>Tue, 10 Apr 2012 12:07:00 -0700</pubDate><category>rant</category><category>development</category><feedburner:origLink>http://kswizz.com/post/20853612338</feedburner:origLink></item><item><title>Over the past week, I’ve quietly redesigned this blog to...</title><description>&lt;img src="http://25.media.tumblr.com/tumblr_m24lbvAFcj1qae51go1_500.png"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;Over the past week, I’ve quietly redesigned this blog to be somewhat up to my current standards. Before, I was using a customized version of Jake Paul’s theme, &lt;a href="http://solsticetheme.tumblr.com/post/294405565/solstice-theme" target="_blank"&gt;Solstice&lt;/a&gt;, which while attractive, was not my own work.&lt;/p&gt;

&lt;p&gt;There were quite a few things I wanted to achieve with this redesign:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;&lt;p&gt;Most importantly, I wanted to have clear and easily legible typography on articles. This is, after all, a blog, and must serve its primary function above all. I also wanted to give myself a unique and somewhat more consistent personal brand, which I think this succeeds in doing.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I wanted the header to be a window into a photographic snapshot. It will be either selected randomly from a selection of my best shots, or updated on a semi-regular schedule. The end goal being: to push myself to take more and better photos, more often.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Lastly, I wanted to try to use some cool modern technologies and ideas. The header uses subtle parallax scrolling, which I think looks gorgeous. The styles is done in a LESS stylesheet, which makes coding CSS a breeze. I’m using semantic HTML 5 tags, like &lt;code&gt;header&lt;/code&gt; and &lt;code&gt;article&lt;/code&gt;, and using a few CSS3 animations. All in all, this was a fun and light coding exercise.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;em&gt;For a fun easter egg, click the little expand icon at the very top-left of any page.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Overall, I’m very satisfied with the result, but will no doubt keep tweaking it over time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Credit where credit is due&lt;/strong&gt;: I’ve drawn inspiration from many places, including: &lt;a href="http://dewith.com/" target="_blank"&gt;Sebastiaan de With&lt;/a&gt;, &lt;a href="http://dcurt.is/" target="_blank"&gt;Dustin Curtis&lt;/a&gt;, and &lt;a href="http://themetrust.com/demos/hero/" target="_blank"&gt;Hero&lt;/a&gt;’s parallax header. I also used Andy Davies’ pattern, &lt;a href="http://subtlepatterns.com/?p=1153" target="_blank"&gt;light wool&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/seoxys/~4/MuBeYQzDlEU" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/seoxys/~3/MuBeYQzDlEU/20668660473</link><guid isPermaLink="false">http://kswizz.com/post/20668660473</guid><pubDate>Sat, 07 Apr 2012 13:09:00 -0700</pubDate><category>design</category><category>release</category><feedburner:origLink>http://kswizz.com/post/20668660473</feedburner:origLink></item><item><title>App Store Retrospective</title><description>&lt;p&gt;Three years ago, I wrote a summary of the major problems with Apple&amp;#8217;s App Store as an email on the &lt;a href="https://groups.google.com/forum/?fromgroups#!forum/iphonesb" target="_blank"&gt;iphonesb&lt;/a&gt; mailing list. Three years later, I think it&amp;#8217;s a good time to look back and see how Apple has handled the situation, and assess whether we&amp;#8217;re better off.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;h3&gt;App Store:&lt;/h3&gt;
  
  &lt;p&gt;&lt;em&gt;Junk Apps&lt;/em&gt;: The App Store is filled with junk apps made in, at most, ten minutes. The proliferation of iPhone success stories has given rise to an epidemic of hopeful developers taking shortcuts hoping to make a quick buck. These apps make up 98% of the App Store&amp;#8217;s 50k apps. This creates needless clutter that makes it hard for the real apps that real developer spent real time and real money on to get noticed.&lt;/p&gt;
  
  &lt;p&gt;&lt;em&gt;App Store Reviews&lt;/em&gt;: There are plenty of problems with the reviews on the store: they&amp;#8217;re nearly always of terrible quality. There&amp;#8217;s no way to contest or respond to an erroneous review. There&amp;#8217;s not even a way to respond to a review saying there&amp;#8217;s a problem with the app with a solution, or a &amp;#8220;that&amp;#8217;s coming in the next update—hang tight.&amp;#8221;&lt;/p&gt;
  
  &lt;p&gt;&lt;em&gt;Rate On Delete&lt;/em&gt;: Apple is artificially creating needless bad ratings by asking users to rate an app when they delete it, which quite obviously only creates 1-star ratings. For example: iLaugh Lite 1.0 had over a third of a million users, and many of them were happy and kept coming back to the application, I could see from the analytics. Yet, my rating was 2 stars, because a couple thousands (out of a quarter of a million) users didn&amp;#8217;t like the app and deleted it and rated it 1 star. The hundreds of thousands of happy users, though, didn&amp;#8217;t delete the app and therefore were not asked to rate the app. This creates artificially low ratings.&lt;/p&gt;
  
  &lt;p&gt;&lt;em&gt;Search is broken&lt;/em&gt;. Either you&amp;#8217;ve got to put a whole lot of keywords in your application name, which sucks for plenty of reasons, or you&amp;#8217;ll fall behind the ones who do. Often, you just won&amp;#8217;t show up in search that should totally return you first. Advanced search is useless and impractical.&lt;/p&gt;
  
  &lt;p&gt;&lt;em&gt;Top Apps Charts&lt;/em&gt;: These charts have so much effect on whether an application gets noticed and downloaded that whether you show up on these charts can decide the fate of your application. Which also causes the next point. &lt;/p&gt;
  
  &lt;p&gt;&lt;em&gt;Ringtone ($0.99) Apps&lt;/em&gt;: As has been very &lt;a href="http://furbo.org/2008/12/09/ring-tone-apps/" target="_blank"&gt;well discussed&lt;/a&gt; by Craig Hockenberry on his furbo.org blog, app prices have become a race to $0.99. Since the charts are counted by downloads, no matter the price of the app, it means that a lower price which causes more downloads will make your app more likely to succeed.&lt;/p&gt;
  
  &lt;p&gt;&lt;em&gt;Upgrades, Promotions, Variable Pricing&lt;/em&gt;: No way to offer paid upgrades, which is a HUGE problem. There&amp;#8217;s still no way to give out copies of your app over the 50 promo codes limit, which only work in the US. You can&amp;#8217;t do bundle promotions, discounts or anything of the sort either.&lt;/p&gt;
  
  &lt;p&gt;&lt;em&gt;Customer Data&lt;/em&gt;: Your customer data is hidden. There&amp;#8217;s no way you can promote another app by you or a paid 2.0 upgrade (since you&amp;#8217;ll have to create a new app for that). There&amp;#8217;s no way you can switch an app to another iTunes Connect account if it gets acquired, without losing all customers and not giving them any further updates. (Check out futuretap.com&amp;#8217;s &lt;a href="http://www.futuretap.com/blog/transferring-an-iphone-app-last-episode/" target="_blank"&gt;blog post&lt;/a&gt;.)&lt;/p&gt;
  
  &lt;h3&gt;App Review:&lt;/h3&gt;
  
  &lt;p&gt;&lt;em&gt;Lack of Transparency&lt;/em&gt;: There is no communication between us and Apple. Apple doesn&amp;#8217;t want communication. They specifically block communications. Emails to their support never get answered, and phone calls just tell us to email. Often, they reject apps on no grounds, or simply obscurely and vaguely referring to some TOS article that only partly applies to the situation, leaving you no way to communicate back and contest the decision.&lt;/p&gt;
  
  &lt;p&gt;&lt;em&gt;Updates&lt;/em&gt;: Updates take ages to get approved. They sometimes get rejected while being only a bug-fix update to an app that got approved. (This has happened to me.) And even when they get approved, it takes forever, possibly leaving some critical bug or crash in your application and costing you tons of negative reviews and ratings. (Has also happened to me.) Garrett Murray posted a couple interesting &lt;a href="http://log.maniacalrage.net/post/98510137/" target="_blank"&gt;articles on the topic&lt;/a&gt;.&lt;/p&gt;
  
  &lt;p&gt;&lt;em&gt;Review Time&lt;/em&gt;: Apple often takes many weeks to review anything posted to them. Some of my reviews took up to three months. (No kidding!) This is just not viable. Period.&lt;/p&gt;
  
  &lt;p&gt;&lt;em&gt;Arbitrary Rejections&lt;/em&gt;: There have been countless examples of arbitrary and unwarranted rejection. &lt;a href="http://www.seoxys.com/apples-increasingly-ridiculous-rejections/" target="_blank"&gt;I have my very own&lt;/a&gt;. There have been countless more examples reported.&lt;/p&gt;
  
  &lt;p&gt;&lt;em&gt;iTunes Connect&lt;/em&gt;: It is a piece of garbage. There is simply no other polite way to put it. It is painfully slow. It is awfully designed. For example, not too long ago I was editing the description for my application, iLaugh. I had opened iTunes Connect&amp;#8217;s page for my application in one tab and in another tab I opened another of my application&amp;#8217;s info for reference. When I was done, I submitted the changes and, to my horror, instead of updating the description as it should have it overwrote the info of the other application I had open in the other tab with what I had submitted in the first tab. This is just an example, but there are plenty more ways in which iTunes Connect constantly screws up. There&amp;#8217;s no way to delete an application, or change an update&amp;#8217;s version number. It also gave me erroneous sales reports a few days back. Overall, it easily wins as the worst web app I have ever used. Period.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If this list of complaints sounds oddly familiar, it should, because it&amp;#8217;s surprisingly still relevant today. While Apple has made a few steps forward—for example, by getting rid of rate-on-delete—it has made an equal number of steps back. An example is the recent UDID fiasco.&lt;/p&gt;

&lt;p&gt;But what&amp;#8217;s even more scary, to me, than a mistake Apple might have made recently (such as its deprecation of UDIDs) is how relevant this old list of complaints remains. Remember, when I wrote this, the App Store was just one year old. I figured, they might just not have had time to get to these items, and that they&amp;#8217;d improve as time went by. But, since then, they&amp;#8217;ve had time to replay the entire life of the App Store thrice more, and for the most part, nothing has changed.&lt;/p&gt;

&lt;p&gt;This indicates apathy. Apple just &lt;em&gt;doesn&amp;#8217;t care&lt;/em&gt; about its third-party developers. Their business, at the end of the day, is in selling hardware. They have no motivation to make it easy for developers to build a business on top of their platform. They don&amp;#8217;t even care, it seems, about fostering innovation.&lt;/p&gt;

&lt;p&gt;The App Store&amp;#8217;s biggest flaw, at the end of the day, is that it is not a free market. It is not a meritocracy, and app success is slave to the whim of a corporate overlord that changes it mind without explanation more often than a 5 year old.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Disclaimer: this is my own opinion and in no way reflects my employer&amp;#8217;s.&lt;/em&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/seoxys/~4/afGT1h6YDqQ" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/seoxys/~3/afGT1h6YDqQ/20535041240</link><guid isPermaLink="false">http://kswizz.com/post/20535041240</guid><pubDate>Thu, 05 Apr 2012 10:43:00 -0700</pubDate><category>rant</category><category>articles</category><feedburner:origLink>http://kswizz.com/post/20535041240</feedburner:origLink></item><item><title>Rolling Stone&amp;#8217;s Matt Taibbi:


  At least Bank of America got its name right. The ultimate Too...</title><description>&lt;p&gt;Rolling Stone&amp;#8217;s &lt;a href="http://www.rollingstone.com/politics/news/bank-of-america-too-crooked-to-fail-20120314" target="_blank"&gt;Matt Taibbi&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;At least Bank of America got its name right. The ultimate Too Big to Fail bank really is America, a hypergluttonous ward of the state whose limitless fraud and criminal conspiracies we&amp;#8217;ll all be paying for until the end of time. Did you hear about the plot to rig global interest rates? The $137 million fine for bilking needy schools and cities? The ingenious plan to suck multiple fees out of the unemployment checks of jobless workers? Take your eyes off them for 10 seconds and guaranteed, they&amp;#8217;ll be into some shit again: This bank is like the world&amp;#8217;s worst-behaved teenager, taking your car and running over kittens and fire hydrants on the way to Vegas for the weekend, maxing out your credit cards in the three days you spend at your aunt&amp;#8217;s funeral. They&amp;#8217;re out of control, yet they&amp;#8217;ll never do time or go out of business, because the government remains creepily committed to their survival, like overindulgent parents who refuse to believe their 40-year-old live-at-home son could possibly be responsible for those dead hookers in the backyard.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is the one article that explains the motivation behind the Occupy Wall Street &amp;#8220;movement&amp;#8221; rationally and sensibly enough to not be an immediate turn off. On the contrary, this fantastic piece of journalism made me realize just how massive of a mess we have gotten ourselves into.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/seoxys/~4/QQV0xQ_U88s" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/seoxys/~3/QQV0xQ_U88s/20513521119</link><guid isPermaLink="false">http://kswizz.com/post/20513521119</guid><pubDate>Wed, 04 Apr 2012 22:15:00 -0700</pubDate><feedburner:origLink>http://kswizz.com/post/20513521119</feedburner:origLink></item><item><title>America is one of the most hospitable countries. The American people are genuinely nice: they give a...</title><description>&lt;p&gt;America is one of the most hospitable countries. The American people are genuinely nice: they give a lot to charity, they like to have fun, they &lt;em&gt;smile&lt;/em&gt;. It&amp;#8217;s hard to realize how much of a difference this makes until you spend some time living somewhere else. In Russia, for example, people seem sad and distant, while in South Africa the pleasantries feel much forced and status-driven, as if you were talking to a butler or a panhandler.&lt;/p&gt;

&lt;p&gt;Only in America do tellers ask you if you&amp;#8217;ve had a good experience finding what you needed, say &amp;#8220;please&amp;#8221; and &amp;#8220;thank you,&amp;#8221; and strike up conversations while scanning in your purchases. Only in America is it not inconceivable to share a cab or an umbrella with a perfect stranger—in fact, I did both of those things just yesterday.&lt;/p&gt;

&lt;p&gt;What surprises me, then, is the disparity between that and the experience of actually getting here. The United States is notorious for its extremely paranoid and unfriendly security practices when it comes to travel and immigration control. Of all the countries I have travelled to or lived in (the list is quite large), the process for the United States has been and continues to be hands down the most painful I have experienced.&lt;/p&gt;

&lt;p&gt;This realization came to me when reading Mark Vanhoenacker&amp;#8217;s &lt;a href="http://nty" target="_blank"&gt;New York Times op-ed&lt;/a&gt;, in which he writes:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;No country’s border staff is perfect, as every traveler knows. But America — a land where strangers greet one another in elevators, waiters act as if they like you, stores deploy professional greeters and government serves the people — should aim to be the best. That means a smile or “hello” as we approach every agent, a “please” and “thank you” to bookend every official request and an occasional “welcome” as we cross a secure border.&lt;/p&gt;
&lt;/blockquote&gt;&lt;img src="http://feeds.feedburner.com/~r/seoxys/~4/LW-TvOEoPrw" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/seoxys/~3/LW-TvOEoPrw/19480586195</link><guid isPermaLink="false">http://kswizz.com/post/19480586195</guid><pubDate>Sat, 17 Mar 2012 16:58:00 -0700</pubDate><category>politics</category><category>rant</category><category>articles</category><feedburner:origLink>http://kswizz.com/post/19480586195</feedburner:origLink></item></channel></rss>
