WWDC Wednesday: Fire and Motion
August 9th, 2006, at 2:35 p.m.
As you may or may not be aware, one of the features of Mac OS X Leopard is called iChat Theater. iChat Theater allows you to share arbitrary sound and video via AIM. The feature is great for end-users; showing a friend a funny movie clip, or your parents a photo album of your kid, has become wonderfully trivial. In what for Apple qualifies as a rare nod for developers, they have publicly exposed a clean API to allow your applications to hook into this framework. Basically, all an application must do is draw both to its window’s contentRect and to a contentRect provided by the framework. That’s it. All the other voodoo (NAT, quality scaling, firewall, and so on) is taken care of by the OS X IMService framework.
Unfortunately for us, one of the standard applications that Apple has hooked in is Remote Desktop, which means that users simply need to click a button and they can see another user’s screen. Again, because this uses IMService, Apple’s solution plows through NATs and firewalls and automatically rate-limits. When I first saw this on Monday, a friend of mine who is intimately involved with Leopard simply said, “Sorry. What can I say? It was a good idea.”
A couple of days sleep has helped me to distance myself a bit from the situation. Firstly, Leopard won’t come out until Spring next year, and the people who need help are the ones least likely to upgrade. So today, I went to the iChat Theater session to learn how this new system works.
The good and bad news is that Leopard’s remote assistance doesn’t actually use IMService. The reason that’s good is that, currently, remote control requires both parties have exposed public IP addresses with dropped firewalls, meaning that it has the same problems as MSN’s remote control. Although the developers have said that they intend to fix these problems by the final build, the fact that they’re not going through IMService, and that IMService took about three years to get it right, means that I’m not too worried they’ll actually get everything properly working. So that’s good.
The bad is that it means we won’t be able to hook into iChat the same way that they do. The public API is called IMAVService. IMAVService has no mechanism whatsoever to return input from the remote end. That makes it a complete nonstarter not only for us, but for many innovative ideas.
Despite Apple’s strong emphasis on resolution independence, the IMAVService framework caps presentation video at 320x240. The smallest display Apple sells right now is 1152x720—10 times as many pixels. The ratio they chose is also just bizarre; 320x240 is a 4:3 ratio, whereas all Apple displays are between 8:5 and 16:9, meaning that an awful lot of content has been optimized for letterbox-like displays while iChat Theater expects TV-like displays. Further, the entire thing ties into CoreVideo’s CVPixelBuffer in such a way that I seriously doubt they ever intend to support sending vector commands over the client. Combine all of these observations and it seems to me that iChat Theater is condemned to permanent blur-hell.
For the moment, I think it makes good sense not only to finish, but to continue work on Aardvark Mac. We’re cross-platform, we’ll work in situations where iChat probably won’t, and we’ll run on all Mac versions—not just Leopard. I still think it would be very wise to keep a very close eye on this technology in the future.
Objective-C 2.0: the Bad, the Horrible, and the Ugly
August 9th, 2006, at 1:48 a.m.
Apple announced Objective-C 2.0, the first major change to the language ever. The features should all be great—support for properties, inbuilt iterator syntax, much higher abstraction in the runtime, and more—but ultimately, though many of these modifications attempt to solve real problems in Objective-C, they nearly universally solve them inelegantly and inconsistently.
One of my biggest complaints comes with the iterator extension. In Objective-C 1.0, to iterate over a collection, you had to use the Java 1.4 method: you got an NSEnumerator object, then repeatedly called -[NSEnumerator nextObject] until there were no elements left in the collection. Objective-C 2.0 introduces a new iterator object, NSFastIterator, and modifies the for iterator in C so that you can iterate over Cocoa collections using NSFastIterator, basically using the same general concept as Java 5 for its implementation.
I find this solution fundamentally flawed. Objective-C, until now, has always been extremely good about not modifying the C core at all. Objective-C syntax extensions were always deliberately alien to C so that there could be no confusion. Keywords were prefixed with @ (e.g., @selector(objectEnumerator), @interface, @implementation), method calls [lookLike this], and so on, so the logical way to add iteration to the language, if you’re going to do it that way, would be to add an @foreach keyword. Instead, Objective-C 2.0 overrides the for operator, so that you can now write
for (NSString *string in anArray) {}
This needlessly confuses ObjC and C features, and sets a very bad precedent: Objective-C features can be now intermingled with classical C.
This complaint, though, sidesteps an even bigger complaint: iterators are, at their core, trying to be a special, niche version of generic lambda blocks—in this case, a block that takes one argument and does something with it. The “proper” solution then, rather than adding a @foreach keyword, would be to add blocks/lambda methods to Objective-C.
Currently, Objective-C and .NET basically take the same tack for callbacks: you can pass around a method, but that method must exist and be named. So, for example, in ObjC we have
[[NSNotificationCenter defaultCenter] addObserver: self
selector: @selector(fooDidHappen:)
name: NSSomeNotification
object: nil]
which, if .NET had NotificationCenter, would be equivalent to
NotificationCenter.defaultCenter.addObserver(this,
delegate(fooDidHappen),
SomeNotification,
null)
We see the same idiom anywhere that we require a callback. What I want, instead of passing an object and a method, is to be able to pass an inline function. If I had that, then the for modification would be unnecessary; I could simply add a method -[NSCollection eachObjectDo:] that took a block and passed it each element of the collection in sequence. Sadly, not only is this not the path Apple took, but there’s no indication that it even almost made the cut. Surprisingly, Microsoft will be adding this feature to .NET 3.0, and so .NET 3.0 will be superior to Objective-C 2 in this regard.
Objective-C 2.0 also adds properties. This has me fundamentally irked. Joel has complained of the problems with leaky abstractions. To be honest, though I agree with most of his individual points, I disagree that abstractions are dragging us down; every single abstraction in the computer except raw wires are abstractions, all are at least somewhat leaky, and all that are properly designed, in my opinion, help much more than they hurt.
Properties at first seem like a good abstraction, one that helps more than hurts. Objective-C rigidly adheres to Smalltalk’s concept of how visibility should work: using Java terminology, all instance variables are protected, all methods are public. This has clear implications in how you think about your program. Historically, the inconvenience of getting instance variables has strongly encouraged a tell-don’t-ask design philosophy. When you do ask or assign, it’s clear that what you’re doing may have side-effects: [foo setBar: baz] is clearly a method invocation, and I should expect that side-effects may result.
With Objective-C 2.0, we gain .NET-style properties, and have assigned foo.bar = baz as the syntax. This is another example of Objective-C now modifying C syntax, only this modification is not simply inconsistent; it’s deadly. Firstly, the above code implies to any decent C programmer that foo is a struct. Just from the above code snippet, though, we actually have no idea. It could either be a struct or a class. Or, hell, it could be a union. Now we have three radically different concepts sharing exactly the same syntax. Worse, though, to most programmers, the above syntax implies a lack of side-effects beyond the value of foo.bar changing. After all, that’s the behavior of both struct and union (and classes in C++, for that matter). But since, as in .NET, Objective-C properties are actually full-blown methods, we have no guarantee that further side-effects won’t occur, and in fact we see this happen in Apple code. One of the demos they have for Core Animation shows how easy it is to make an object fade out. All you do is
someObject.opacity = 1;
This doesn’t simply set the value of some opacity variable, but actually begins an animation of that object’s fade-out in a new thread. Not only is this not what I would consider the expected behavior, but it also means that, for example, you can throw one of NSThread‘s exceptions within a variable assignment. This is a leaky abstraction that, in my opinion, does far more harm than good.
These complaints aren’t specific to Objective-C 2.0; they apply equally well to Java 5, .NET, Delphi, and other similar systems. So these mistakes aren’t new, and I’m actually somewhat in the minority for considering them mistakes to begin with, but I’m sticking to my guns: these are horribly leaky abstractions solving a non-problem. I would rather have seen any of three alternatives:
- Emphasize that you can access ivars directly by allowing
foo.barin addition tofoo->bar. I don’t like this solution, but at least it makesfoo.bar = bazdo what I’d expect it to. - Assign a different syntax to properties, perhaps
someObject!xCoordinate = foo,[someObject xCoordinate = foo], or any syntax other than dot notation so that programmers have at least an inkling that this is not their daddy’s dot operator. - Implement
@propertyso that it only generates-[MyObject setFoo:]and-[MyObject foo]methods and nothing else. Shelve the whole dot syntax. This cuts down how much code we have to write, but doesn’t provide us with a false view of how things actually work. In my opinion, this is the best of both worlds.
Sadly, Objective-C seems content to repeat the mistakes of its predecessors. This does not herald the wonderful new direction for Objective-C that Apple would like to have you believe; it heralds the beginning of the end of Objective-C’s uniqueness.
The Greater Good
August 9th, 2006, at 1:13 a.m.
I had always assumed that I’d love San Francisco. San Francisco is a big city, but not as large as New York or Chicago; big enough to always have something to do, small enough that you stand a good chance of being able to do it without standing in line for five hours. San Francisco’s got nearly perfect weather. It’s got a solid mass-transit system. It’s near all of the major computer companies. It has tons of outdoor activities. It’s near ocean. In every way, it seemed as if it ought to be perfect for me.
The reality has hit me much harder than I anticipated. The city is just about the right size, it is pretty, and it does have great transit and a wonderful selection of activities. My problem with San Francisco is the weather.
Complaining about the weather in San Francisco at first seems bizarre. It barely ever rains, the sky’s gorgeous, and most noticeably, the city’s always slightly cool and never too hot or too cold. What you miss at first is that the weather has an unexpected side-effect: there are a ridiculous number of homeless people.
Superb weather every day means that beggars can easily sleep on the street; they never have to worry about being roasted alive, as in Phoenix, or frozen to death, as in New York. Suddenly, and very unfortunately, classic supply-demand economics kicks in: a high supply of beggars leads to high demand for handouts, which vastly surpasses the supply of “loose” change available, so the homeless end up having to be very aggressive in order to get enough cash.
“Being aggressive” actually can take many forms. One, of course, is literally being extremely pushy. I’m no stranger to homeless people; New York has more than its share of beggars wandering the street. New York beggars, though, basically hold still with a cup out; they rarely approach you, and when they do, they’re actually almost always relatively polite. The subway beggars, for example, usually give a speech similar to this one, which I actually heard just a few days ago:
Excuse me, ladies and gentlemen, if I could have a minute of your time. I normally play the congo drum, but at the moment I have lent my drum to a musician in greater need than me. I could use your help to get by. If you could please find it in your heart to help me in this difficult time, I would greatly appreciate. May the L-rd be with you.
Following the speech, the person will walk up and down the subway car, then leave. Now, you can say that she’s full of it, and I’ll of course agree with you, but the point is that, though she may be annoying, she’s easy to ignore and relatively polite about things.
San Francisco is an entirely different matter. I have been here all of two days, and I’ve had two different guys unleash a stream of invectives when I deliberately ignored them, one of whom actually started walking after me for about fifty feet before I stared him down. Beggars here do not like to be ignored. My treatment, unfortunately, did not seem to be unusual; I’ve seen maybe five or six other people hounded in the same manner.
Even when you give a beggar a coin, they complain, sometimes forcefully, that you didn’t give them enough. I heard one exchange in particular that was at once both hilarious and unspeakably pathetic:
Man: Can’t anyone spare a nickel?
Woman: [Gives him a nickel]
Man: All you got’s a fucking nickel?
Aggressive begging goes beyond merely being forceful verbally and physically. Many beggars around here are in wheelchairs and claim to be disabled, but if you keep walking by the same spot, you will soon spot the “disabled” beggars using their feet to pedal around in their wheelchair, or even stand up and walk around for a stretch. It’s insulting and degrading for everyone involved.
I’d be somewhat more willing to put up with all of the above if the economy in San Francisco had gone to hell and these people were truly desperate. The problem is, San Francisco’s economy isn’t that bad, and very, very few beggars look like they’re even in troubled times. Many are wearing perfectly fine T-shirts and pants; quite a few have nice tennis shoes, and at least one I saw, a 200-pound man who was cussing me out for not helping him “get a bite to eat” (“I’m fucking hungry, yo” he elaborated) was wearing what had to be week-old Nikes.
When I was little in Indiana, it used to be common for beggars to sit by the freeway exits with cardboard signs begging for money for their three kids (it was always three kids; never two, never four, always three). My dad made a habit of offering these beggars jobs, which they inevitably declined. “I don’t want a job, man,” one man begging near my dad’s old office told him. I strongly believe that this sentiment encapsulates the minds of many beggars whom I have seen over the last couple of days. They could work; they find begging for money easier.
I am unsure how to solve this problem. Clearly, supporting these beggars financially is good neither for them nor for society. If everyone stopped giving, they would vanish, because they do need to eat. If we could all be disciplined to not give any more handouts, though, we’d also cut off those people who truly are too incapacitated to work and truly have run out of options. The “fake” beggars would be forced to find work; the “real” beggars would starve and die. Sadly, the mere fact that these people are also in the street begging means that we are currently being utterly unsuccessful reaching them through charities, shelters, and soup kitchens.
I wish with all my heart that I knew some magical solution to the homeless/beggar problem, but I’m human; I don’t. Greater minds than mine have fought with the problem and failed, either in effectiveness or in motivation. But I find it incredibly disheartening that the problem has deteriorated so badly in San Francisco that it becomes the most prominent feature I notice.
San Francisco has the potential to be one of my favorite cities, and maybe some day it will be, but at the moment, I’m looking forward to returning to New York.
WWDC Monday: Meeting the Savior
August 8th, 2006, at 4:52 p.m.
Amazingly, the woman at registration was right. I fell onto the floor got up at 5:30 AM, groggily showered, grabbed a bagel and some OJ at a patisserie that was apparently run by the bitter sister of Soup Nazi, was politely asked for “loose” change about forty-two times by people who admittedly were wearing pretty beat-up Nikes, and then went to Moscone to find a line that already arced its way around the convention center.
Apple let us approach the Presidio in steps. First, at seven, they let us into the lobby of Moscone. When they finally let us in, we immediately filled up most of the lobby. There, I met Allen (a student from some place in Canadia, a suburb of Bismarck), Michael (a youngish developer who somehow already manages to provide the aura of the bitter old-timer who longs for The Good Old Days), and David (a student from the People’s Republic of Berkeley), all of whom were smart, friendly, very fun to talk to, and who were in the rare majority of attendees who knew how to use mouthwash and shampoo. Then, at about eight, they herded us to the second level, where we requeued and spent the next hour next to some food trays that had been carefully selected to only contain comically strong coffee and foods that were at least 87% raw cane sugar. Thenataboutninethirtywewereallowedupstairsyay OMG I AM GOING TO MEET STEVE JObS I AM SO PUMPED!!!!!!!!!1111one!
Just about the time that my sugar high was beginning to quietly wander off in exactly the way a hangover doesn’t, Steve Jobs Himself walked onto the stage. Thus began the keynote.
The keynote had a four-part agenda, broken down roughly as follows:
- 40% showing side-by-side pictures of Vista ripping off Tiger
- 30% repeating the phrase, “So that’s iFoo. We’re very excited about it, and really looking forward to seeing how you can integrate it into your products.” I began to wonder whether there was an implicit “because quite frankly we have absolutely no idea” they weren’t adding to this sentence.
- 28% introducing features of Leopard that are great for end users, but that duplicate functionality already written by third parties, thereby using the Developer’s Conference to announce features competing with developers
- 2% discussing new features that impact developers
Once He was done speaking, we all organized ourselves into a high-velocity stampede outside, where we viewed the new hardware, and from there basically fell en masse down the escalator into the lunch room, where we refueled on high-starch foods and your choice of lemonade, lemon tea, or regular Dr. Pepper. During lunch, as people stopped being so incredibly focused on Steve Jobs, I also made the discovery that, if I’m not famous, I’m at least very well-known. This is not that surprising to me, since my lovers apparently advertise my name so often that numerous companies contact me with offers for Viagra, but it was kind of cool to get a ton of people saying, “What’s it like to work at Fog Creek?”, “What was it like to be in the documentary?”, “Are you really as sexy in real life as you appear in the movie?”, etc. One person, in a mildly surreal echo of a conversation I had with Eric last week, even took the time to explain to me that the equations we had on the board to figure out whether you’d make it to the other building neglected to factor in air resistance.
In the afternoon, we began the NDA sessions. I unfortunately am not legally allowed to post my thoughts on these sessions, but I will continue to blog about parts of Leopard that are public and about my time in San Francisco. For now, though, signing off.
WWDC Sunday: Preparing to Wait
August 6th, 2006, at 10:41 p.m.
Today was…long. The fun started when I got a call at 7:20 AM reminding me that my car was coming at 8. For some reason, I’d had in my head it was coming at nine, and so decided that I’d wake up at about 7:30, spend 45 minutes packing, take a quick shower, and be ready to go. Instead, I pretty much literally just dumped a wad of clothes into a suitcase, jumped into the shower, and proved that you can easily run with a 35-pound suitcase if you have enough adrenaline and don’t really care about who you hit.
On the bright side, first-class transcontinental is just…awesome. The meal they served for lunch was vastly superior to any dinner I’ve had recently, the seats had plenty of legroom, and for the first time in my life, I actually didn’t mind a long flight all that much (although for true comfort, I eagerly await the day that hard liquor counts as a business expense). By 6 PM EST, I arrived, grabbed a cab whose driver was trying to impersonate Shaft in dress, behavior, and music selection, quickly verified I hadn’t accidentally time-warped back to the 70s by counting the number of tie-die shirts (12), and then rode into the city.
Once I was checked into the hotel, who helpfully verified the credit limit on my MasterCard, I went to register for the conference. As you may or may not know, Jobs’ keynotes are generally very well-attended, by which I mean that Mecca got nothing on developers trying to bump and grind their laptops into the Presidio at Moscone so that they can see His stubble and sweat in person. This year, the keynote is supposed to start at 10 AM PDT. I’d like to share my conversation with the woman who helped me register:
Me: So, the keynote’s at 10, right?
Woman: Yeah.
Me: So when should I be here?
Woman: Well, the doors open at 7, so you probably want to get here before then.
Me: …
So, I am now diligently going to bed early. I’ve got my alarm set, I’ve got my clothes laid out, and I am ready to run out and wait.
