NO DUDE YOUR MEDIA CENTER APP IS WRONG

People, wake up! Your media center apps are wrong for me!

They want to bring computing power to the TV. In that, they succeed. But they make that power unavailable to me. Because they’re built wrong!

Apple TV? Built wrong!

Front Row? Built wrong!

Windows Media Center? Awesome! But built wrong!

XBMC, Boxee, Plex… wrong, wrong, wrong.

That’s because they all assume the user is willing to interact with his TV when it’s time to play stuff.

I tried an insane number of media center apps, hoping to find The One. And all this time I’ve been frustrated by the sorry state of consumer video playback on TV. None of them passes my main use case, which is as follows: After five to eight hours spent studying and working, I come back home, get into the living room, turn on the TV and get my sorry ass on the sofa, ready to shut down my brain. I don’t have enough mental strength to get anything but changing a channel on a remote.

Regular TV passes the test: content is right there to be seen and I don’t have to think about it. Except it’s not usually the content I want to look at: I want to see the latest anime on Crunchyroll or my fave podcast much more than I want to see bland, generic TV programming. TV wins on user experience and loses on content quality.

Media center apps surely have the stuff I want. And yet, they lose on user experience, because they INVARIABLY require me to dig into menus and/or organize stuff beforehand.

“NO, DUDE, I’M TOO TIRED. DO IT FOR ME.” goes my head as I throw myself on the sofa after eight hours spent doing something else.

And yet no one does. The computer can and should provide me with the programming I’ve signaled I want. I want to point it into the generic direction of stuff and have it figure out transparently what to do. App! Show me episodes of a series in order. Prepare an hour and an half of programming from what you have. Do not play silly anime back to back with gritty serials; pick by genre, pick stuff I haven’t seen in a while, put the highest-rated stuff first. I want TV channels that are and behave as iTunes smart playlists, except I don’t want to set ‘em up. And when I start you up, do not have me dig stuff and then hit play and then — just start playing right away, dammit! Me interacting with you is an exception, not something I want to do every time I want to play stuff.

I’ll be working on this space in my spare time, believe me.

6 comments so far, add yours

The Way I Do JavaScript.

I borrow from Objective-C. Duh.

No, don’t go away! I promise this post will be worth your time. I’ll be short.

Okay.

With that out of the way, I’ll just say this: I can’t wrap my head around prototype-based inheritance. That is: I can and I do understand it and I would be able to mentally resolve prototype chains easily, but the code is ugly.

Consider the canonical example:

Employee.prototype = new Person();

OMGWTFWHAT?

Why are all Employees referring to a single Person object, whose state is singular? (I know you can redefine state in the Employee objects and the prototype chain for that will work out in the Person methods, but come on!)

Also, how do you get to run the new Person() code in new Employee()? (Answer: you don’t. You have to outsource your constructor call to an initialize method for things to have sense.)

Oh, geeze.

So, what to do? An answer, my friend, is more gun factory methods. By skirting prototype inheritance entirely and using what in the Objective-C world we’d call “swizzling” and in Ruby is called “monkey patching”, not only we can mimic successfully canonical class-based inheritance, but we can even implement trickier stuff like traits. YAY!

Example. Let’s say you’re building a dice-rolling application for yet another certain mobile platform that takes HTML and CSS and JavaScript. RPGistas roll packs of dice of the same kind, where “kind” means “number of faces”: for example, 3d6 means that you roll three six-sided dice (the kind of dice you use in Monopoly — yes, it’s not the only one and the thing can become downright weird. But I disgress).

We want to model that using a class-ish kinda thing in JavaScript. Well, I make a factory method like this:

function Dice(numberOfDice, numberOfFacesPerDie) {
	return {
		roll: function() {
			var i, a = [];
			for (i = 0; i < numberOfDice; i++)
				a.push(Math.floor(Math.random()
				 	* numberOfFacesPerDie + 1));
				// mathematically fair!

			return a;
		},

		numberOfDice: function() { return numberOfDice; },
		numberOfFacesPerDie: function() { return numberOfFacesPerDie; }
	};
}

Ka-zing! Now a (Pythonesque) var threedeesix = Dice(3,6); gives us an object that rolls three six-sided dice when we do var result = threedeesix.roll();. Hurrah! Also note how we exploit the closure to avoid lots of this.’s for private state, also killing the this.numberOfDice = numberOfDice boilerplate code (we still need to define functions to expose this state to the outside world, though).

Two steps further: inheritance and super calls. How do we make an object just like a Dice, but that works differently? Some kind of, say, rigged pack o’ dice? Easy: we make a Dice-built object, then we monkey-patch it to suit us.

function RiggedDice(numberOfDice, numberOfFacesPerDie) {
	var self = Dice(numberOfDice, numberOfFacesPerDie);
	self.roll = function() {
		var i, a = [];
		for (i = 0; i < self.numberOfDice(); i++)
			a.push(self.numberOfFacesPerDie()); // all sixes!
	};

	var super_numberOfDice = self.numberOfDice;
	self.numberOfDice = function() {
		// not too many dice or we'll get caught
		// by the casino guards.
		var x = super_numberOfDice.apply(this);
		return (x < 3)? x : 3;
	};

	return self;
}

Double twistin’ ka-zing! Okay, the super part is not as clean as it could be but, hey, it’s there and it works! Note how this method is organized more or less like an Objective-C init method (down to the return self; at the end). Also note how this takes care of my constructor conundrum above. Also note how this circumvents the other limitation of new — that it must return one object and only one object, which is the one the system just gave us. Enter lots of Flyweight and (in Java) AbstractFactoryFactoryFactories and— well, you don’t have a need to do that anymore, because the “constructor” factory method can return whatever we frickin’ want (again, more or less like an Objective-C init method). We could’ve cached our rigged dice packs by numberOfFacesPerDie, and returned the cached ones rather than making new ones over and over again, for example.

Save the environment!

Ah! Traits! Traits! They’re trivial: just factor out the monkey patching code into a function all its own. For example:

function Comparable(object) {
	// assumes object.lessThan() is implemented:
	object.equalTo = function(x) {
		return !this.lessThan(x) && !x.lessThan(this);
	};
	object.greaterOrEqualTo = function(x) {
		return !this.lessThan(x);
	};
	object.greaterThan = function(x) {
		return object.greaterOrEqualTo(x) && !object.equalTo(x);
	};
	// ... and so on.
}

Ah, the fresh smell of code reuse in the morning. Just define your object, maybe implement that method or two that the trait requires, and a call like Comparable(object); will add the trait. Simple, conceptually clean, not needing any brain twist to understand. Just like coffee. Clean coffee. Not the greatest of metaphors, but you get the point. Not the coffee.

The obvious objection is, “why not skip all o’ this and use the Class or equivalent facility your framework of choice provides”? That I’d recommend, too, in most cases — but say you’re making generic code that must run on a variety of platforms, some of which bundle other frameworks that redefine the same symbols of your favorite one? (And yes, it has happened in real life.) This is 100% vanilla JavaScript. No framework required. And as simple and as powerful as it gets. Which I like.

And that’s all.

One comment so far, add another

Twenty thousand downloads in four days.

Looks like you like Mover.

What else to say?

Thank you.

2 comments so far, add yours

Additional thoughts and considerations upon the design of a certain iPhone application named Mover

Whew, that was hard.

After thirtyfive days of waiting. After countless hours spent tuning the basic interaction of the application. After four solicitation e-mails to Apple and a frantic Saturday evening spent pushing all the big red “PRESS HERE TO LAUNCH” buttons I had prepared for Approval Day and after being incoherent for a whole weekend.

Before I have to go to the dentist tonight (ick).

Er, I was saying — after all of this, Mover’s done.

So, come to the fireside, my readers, and I will tell you its story.

Continue Reading

Mover, by ∞labs.

You might be wondering where I’ve been.

I was in the back o’ the Labs writing Mover, a new file transfer utility for iPhone.

Enjoy it with your friends! (Owch. That sounded totally inappropriate.)

4 comments so far, add yours

Hot flashes: Prince of Persia & Other Gaming Bits, Slide, other things.

INSTA-ON-MY-MIND-DUMP!

  • Since this is a period where I should have been focused on working and studying and such, I am — of course — entirely engrossed in reading vampire stories (everything is better with vampires!) and playing videogames. Ick. On this note…
  • the ending of the 2008 Prince of Persia is genius. The game has too many little flaws to be good, mind you. But the ending fucks with the player’s mind, realizing too late that the only way to win was not to play (and by that I mean “accept that Elika died and move on with life”).
  • I am too afraid of the dark to start The Path. Really. I want to but I am afraid to do so. Time to grow up, I guess, and face little creepy videogames without all the neurosis.
  • I My brother finished World of Goo. Which I bought twice — once on Steam and once on MacHeist as part o’ the big bundle o’ goodness (which I really bought for The Hit List and Acorn and Espresso). It is every inch as good as it looks like and more.
  • I’m working on a new application called Slide which is what consumes most of my programming mind quantum-of-time. It’s a novel way to share data between iPhones. You can find Slide’s code up on GitHub, still very unpolished.

That’s mostly it. For now.

    Leave the first comment

    The Italian edition of Wired.

    Historic. <3

    Leave the first comment

    Quiet on Sunday Morning

    Leave the first comment

    Wall•E

    Which I think can be summarized by saying that… um…

    Humanity can be found (and can find itself) in unexpected places.

    I think.

    Leave the first comment

    Higher standards.

    I wrote an e-mail tonight. It was about honesty and credibility and accountability. It sent me, as anything does when it impresses me particularly, on a long train of thought.

    It got me back to my graduation day. You see, Italy’s quirky. People who get a degree here can attach a title to their names, but unlike the English “Ph.D.”, it goes to the front of the name — I am Doctor Emanuele Vulcano (Doctor in Engineering in Computer Science, to be precise); and were I to take the associated national exam, I would be referred as Engineer Emanuele Vulcano, not unlike “Sir” denotes knighthood in the United Kingdom.

    And yet, this is no honorific title, not (or not just) a badge of accomplishment. No. On graduation day, a lovely sunny day in March last year, we were gathered in one of the Politecnico’s largest rooms, where the Vice-Director of the Faculty of Information Studies tried and failed, as is customary, to impress us with a speech about the market and the future we would be protagonists of yada yada blah blah. That part I do not regret not recalling. But what followed it, after every name was called and every degree handed, was something I do regret not recalling in detail. It was a standard proclamation, required by the law, and yet it was, yes, formal, but deep and touching, in a way.

    It told us in no uncertain terms that what we earned along with our title was no list of privileges but a list of duties. It reminded us that we’d now be required to perform our Art with honor, with professionality, without letting anyone interfere with the quality of its result.

    It told us a simple truth: that what we got that day, what we have in front of our names, means that we’re held to a higher standard. We must not just be decent human beings; it is our honor-bound duty to be outstanding human beings.

    This it is. And a thought hit me like a little meteor tonight: if I died before I could do any of the things I imagine, I’d still be content if I could be remembered for holding myself up to that standard — for having strived towards being a better person.

    This is not what I believe, in the sense of consciously choosing to believe in something. This is merely what I am; saying this is, to me, no different than saying that I have brown hair. It’s part of what I am, and I cannot escape from it more than I could escape from my own skin. In what’s left of my life, I might not become an exceptional person by any standard; but this side of me will always nag me for it, remind me all the ways in which I could — I should, must — be better. I will never be able to ignore it.

    And on the days I actually happen to listen to it, it hurts less, and I sleep a little better.

    Leave the first comment