John Cromartie's Tumblr

Dec 06

iTunes 11 creates UI color scheme from album art

This is a really awesome touch in iTunes 11. The effect was so seamless and well-done that it took me this long to notice.

Daft Punk Alive automatically-generated color theme in iTunes 11

Buena Vista Social Club automatically-generated color theme in iTunes 11

Brian Eno Ambient 4 automatically-generated color theme in iTunes 11

Boards of Canada Music Has the Right to Children automatically-generated color theme in iTunes 11

Oct 04

Why I’m not Ditching Instapaper for Pocket

I’ve been using Instapaper since 2010. While I really like the service, I’ve always kept and eye out for worthy replacements.

Pocket is Read It Later after a bit of a rebirth, and is undeniably the sexiest of the boomarklet-based reader apps, with a slick iOS app and a great web interface.

When you sign up for Pocket you get all of the features it has to offer, presumably forever. That sounds great, right?

But that’s actually the biggest thing keeping me from Pocket.

Instapaper is supported by paid users, while Pocket is VC-backed. This means that, purely by definition, Pocket will only be around as long as someone other than users thinks it’s a good idea.

Marco could pull the plug on Instapaper for any reason, but at least he has an actual economic incentive to continue the service (for current and subscriber users) and to improve it (to woo future users).

Sep 25

A Poem for LISPers

MUCH madness is divinest sense
To a discerning eye;
Much sense the starkest madness.
’T is the majority
In this, as all, prevails.
Assent, and you are sane;
Demur,—you ’re straightway dangerous,
And handled with a chain.

By Emily Dickinson.

Sep 10

What’s so bad about prefix notation?

One of the common complaints about Lisp is that it forces you to use prefix notation for mathematical expressions. This is a fair complaint, since it’s a pretty big departure from what we learned in Algebra class.

But, exactly how bad is prefix notation, after all? Let’s start with an example:

5 + 6 * 7

When you read this, in English, as “five plus six times seven”, you know exactly what it means assuming you understand the order of operations. It’s totally clear to anybody familiar with basic math.

The equivalent in Lisp would be:

(+ 5 (* 6 7))

If you try to read this like the above infix expression, you get “plus five times six seven”, which doesn’t make much sense. Maybe we can improve on this by changing our reading.

What if, instead, we read it as “the sum of five, and the product of six and seven”. This is more verbose than the simple left-to-right infix reading, but it’s also unambiguous.

Now, let’s say we have a few more symbols in our expression, and we’re using more operations:

(x + y + z + 1) / (b * c * 20)

This is a bit of a tangle compared to our simple expression, but looks a lot like the math you might find in graphics or game code. It’s not bad at all, but I’ll leave the “English” version as an exercise to the reader.

Now Lisp:

(/ (+ x y z 1)
   (* b c 20))

Here, we see that the “operators” in Lisp are actually variadic functions, and eliminate a bunch of infix operators. I’d say this is a win for clarity.

Logic

And what about logic? Most programmers are used to reading logical expression much like algebraic expressions:

if (x < 10 || y > 20) ...

“If x less-than ten, or y greater-than twenty” is nice and clear. The Lisp version doesn’t fare so well:

(or (< x 10) (> y 20))

“Or less-than x ten, greater-than y twenty”.

a bewildered-looking owl stares at us

OK. That sucks.

But what if we alias some of these functions, and rewrite it as:

(either? (ascending? x 10) (descending? y 20))

By phrasing it in the form of predicates, it becomes a bit clearer (I am not suggesting anybody start writing things with aliases like this… it’s just for our example). And, in fact, it might give a hint as the variadic nature of < and > in Lisp. Let’s look at a larger Boolean expression from a curly-brace language:

if (0 < x && x < 10 && 10 < y && y < 20) ...

This expression is already as nicely arranged as it can be, in number-line order. But I wouldn’t recommend trying to read this out (“if zero is less than x, and x is less than ten, and …”). However, in Lisp we can just say:

(< 0 x 10 y 20)

Or, “are zero, x, ten, y, and twenty in ascending order?”. That is much better, and suddenly our code is that much closer to the number line style that infix Boolean expressions strive for.

Is This Just For Lisp?

Of course not! If you are in a language with varargs you can create static methods/functions to implement all of these things. And perhaps you will go ahead and do that now, if these examples have piqued your interest.

But What if We Could Keep Infix After All?

Now, of course, Lisp is nothing if not putty in the hands of programmers. If you find that something fundamental is missing, or you’re inventing something for the first time, then you can just extend the language to do whatever you want.

It turns out that infix notation is just a library in Lisp. Compare this to adding prefix notation to C#, or adding postfix notation to Java.

Jun 08

bcrypt is Not the Answer

bcrypt and other adaptive hash algoritms are a good idea. It’s comforting to know that your password hash time can be scaled up as computing power available for brute force cracking increases.

However, this is an arms race. It’s reasonable to assume that the power available to crack passwords will increase faster than the power available to initially hash passwords. It’s better to just avoid this race if possible.

If bcrypt is widely adopted, and services fail to update bcrypt parameters, then in 10 years those who are still using 2012-CPU-speed-based recommendations will be in exactly the same place as those who use plain SHA1 today: subject to brute force cracking relatively quickly.

What we need is a hashing algorithm that takes 1 second to compute on 2012 hardware, and 1 second on 2022 hardware. The algorithm should be dependent on time passing, rather than time spent computing.

If we could decouple password hash strength from computing power, and instead make it temporally bound, then we’d achieve real password hash security.

There are probably not a lot of good ways to do this, and I’ll leave the details up to people who are way smarter than me. But it seems to me that this is a way to avoid a brute-force-cracking arms race and a colossal waste of computing power in the future.

May 31

jQuery plugin for XML namespaces

If you’ve ever tried parsing RSS or other XML content using jQuery, you know that it’s impossible to select elements with a specific namespace. On top of jQuery’s own selector engine, the browser’s own selector engine is broken in certain cases, too! So, I rolled a quick solution for this in the form of a plugin: $.fn.findNS.

This lets you find, for instance, a <media:description> element, like this:

$(item).findNS("media", "description")

You can find the code in this gist.

May 15

Memoized Blocks in Smalltalk

I came across this post on memoization in Smalltalk by way of James Rober’s blog, but it was lacking in actual code!

So, without delay, I fired up Pharo and whipped up an implementation.

It’s very simple, in typical Smalltalk fashion. It’s just a method of BlockClosure:

memoized
    "returns memoized version of an unary function"
    | cache |
    cache := Dictionary new.
    ^ [ :x | cache at: x ifAbsentPut: [ self value: x ] ]

And it’s used like this:

#(1 2 3 1 2 3) collect: [:x | Transcript show: x asString; cr. x + 1] memoized.

That will only display “1 2 3” once in the Transcript, thanks to memoization, and returns the correct result.

Apr 19

What kind of idiot…

…accidentally buys DDR3-1066 (PC3-8500) when he meant to buy PC3-10600 (DDR3-1333)!?

This is why I am not a “hardware guy”. I have no patience for figuring out some rather obtuse and arcane combinations of numbers and letters that mean the difference between a computer working correctly or not working at all. Oh wait. That sounds like code.

Mar 13

Yahoo! Goes Nuclear

Well, we can say without a doubt that Yahoo! is done now. They are resorting to leveraging patents like this:

wireframe of every website ever

This is what anybody developing an ad display system would do. How could any moderately serious site not order ads by their click-through rate or price-per-click? That would be silly to omit, and it’s completely obvious to anybody who has spent any time on the Internet.

Feb 27

What Happened to TileStack?

Every once in a while, a blog post or some article will ignite a HyperCard nostalgia trip among the programming community. Everybody remembers how awesome it was, what was possible with it, and how Apple pulled the plug. Then people start prognosticating on how to build a new and more modern HyperCard, that would be like the original but even more awesome, with features X, Y, and Z, and everybody would love it and be transported back to that magical time again.

Well, I never used TileStack, but it’s gone now. It looks like they tried earnestly to pull it off. Only an insider could offer the real story on why they shut down.

Based on YouTube videos, it looks like TileStack tried to implement HyperCard’s vocabulary of stacks, cards, buttons, fields, scripts, handlers, and functions. They even implemented the HyperTalk programming language, and could even import actual HyperCard stacks.

At the same time, the UI lacks the stripped-down elegance of the original HyperCard, where viewing a card is a no-frills affair, and the card is presented by itself with no fanfare. Editing the card means opening a menu (optionally tearing off a tool palette) and descending, hierarchically, into different levels of detail for the selected element. You go from the card itself, to a button or field’s properties, to the script

TileStack appears to have taken the smartly modal/hierarchical interface of HyperCard and “flattened” it, enshrining modelessness. In HyperCard you open an object’s Info dialog to edit it. In TileStack you simply focus it and use the large dynamic toolbar area above the stack. It is a staggering array of options, where everything is visible all the time, but only a few options are actually available.

Just some thoughts.