TextMate News

Anything vaguely related to TextMate and macOS.

Open Letter to Wil Shipley

Wil Shipley wrote a great piece on his blog which unfortunately seems to have led to anger and misinterpretation.

Since what he writes rings so clear in my ears I wanted to show my support and give my interpretation of his piece below.

Dear Wil, thanks for a great post!

You put words on something many of us recognize (and are equally frustrated about).

You raise the point that we would use more of the cool APIs if they were simpler / had Cocoa equivalents (which I agree with).

You imply (or at least I interpret) that giving us a Cocoa wrapper with just two functions is really doing us a disservice, because with a Cocoa alternative we won’t look at the underlying Carbon (or whatever) API, and thus not discover what the framework can really do (at least this has been my experience).

You make sure to emphasize that Apple are the ones doing the cool stuff we want to use, and they have already shown us that they master the art of beautiful APIs — so in no way was this piece meant to say that Apple is incompetent, merely that we are many who would appreciate they spend resources on something which seems to be of little priority to them, and they should see a benefit from this: making something easy means it will see far more use (as Apple has already demonstrated in many other contexts).

You post to your blog, which should make it clear that it is an opinionated piece, and often opinions are somewhat ideological, meaning we would be more than happy if Apple would just use your piece for inspiration about future directions, not necessarily halt everything they are currently doing to write Cocoa APIs for all existing non-Cocoa frameworks.

It is a shame that so many did not get these things from your post. Hopefully this won’t discourage you from voicing your valid opinion in the future — what little I know of you, it would not seem that this should be a problem though :)

categories General

23 Comments

I agree but, I don’t think that it will keep Wil from voicing his opinion. I don’t think he really cares what others think of his opinion. Good for him, more people should be that way.

Much ado about nothing really.

Yes, there are many APIs Apple still needs to wrap with Cocoa. Yes, they know that. Yes, they are working on it.

No, ‘C’ APIs (which seem to be Wil’s real hatred - not Carbon) aren’t going away. Both OBJC and plain old ‘C’ both have their places in OSX.

Yes, you can write bad apps in Cocoa. Yes, you can write bad apps in Carbon. Its about using the best mix of tools for the job.

As I said…much ado about nothing.

Wil’s spot on. Thanks for supporting him and clarifying his intent. Many of the comments have digressed into issues that miss the point.

rjt: It’s different to create and deliver object-oriented APIs than it is to wrap procedural APIs in objects. Speaking only for myself, I much prefer object-oriented APIs than wrappers around procedural APIs since they tend to be much better designed for extensibility.

08 October 2006

by Anonymous

chris: Yes, in a perfect world everything would be re-designed to be object-oriented but that just ain’t going to happen with so many APIs in the system. Apple still has deadlines to keep!

08 October 2006

by Anonymous

Sorry that last Anonymous comment was from rjt.

Wil already showcase what the problem is, but just to emphasize, this isn’t as much about procedural versus OO APIs, it’s really just hating the current crop of Carbon APIs.

For example when I have to render text in TextMate, I have to tell the system that I want to render to a Quartz context (basically the only thing which isn’t deprecated), and to do that, I need the following code:

CGContextRef context = …;
ATSUTextLayout layout = …;

ATSUAttributeTag tags[] = { kATSUCGContextTag };
ByteCount sizes[] = { sizeof(context) };
ATSUAttributeValuePtr values[] = { context };
size_t numberOfTags = sizeof(tags) / sizeof(tags[0]);

ATSUSetLayoutControls(layout, numberOfTags, tags, sizes, values);

When you care about readable code, keeping the complexity down, etc. then such code just drives you crazy. And if you want the full code to render a single line of text, that requires ten times as much code as shown above.

Another thing I didn’t mention in my post, but which Wil mentions is that far too often I have wasted my time trying to figure out how to do something following documentation which is not just incomplete, but wrong! Apple has however done a lot with respect to documentation since I’ve had these experiences, so I didn’t feel like I should echo that critique without going through their latest version of the various documents.

Actually “ten times as much code” wouldn’t cut it.

…but why wouldn’t you just wrap up that chunk of code in a method?

rjt: sure, and I can make smart pointers for automated resource management of Carbon handles, var-args functions coupled with macros to provide the tag lists inline, etc.

But none of that changes my view on the situation.

I’m not trying to change your view.

If/when you move to Cocoa you’ll find you still end up wrapping up lots of code into methods to “keep the complexity down and the readability up”. Its no magic bullet.

(Wait until you’ve experienced the readability horror that results from using NSMutableAttributedString!)

rjt: I am using Cocoa, the critique raised by Wil was in essence (direct quote):

_ What’s distressing to Cocoa programmers is that there are still critically important Apple APIs that are only available through the incredibly byzantine and ill-documented Carbon libraries, and some groups at Apple are still generating Carbon code, under the guise of “Core”. _

Interestingly several people chose to strike down on Wil’s mention of FSRefs, as these are good, and TextMate is an example of a Cocoa application which does not use them (which is bad) — and that perfectly illustrates his point: the technology is great, but there is no Cocoa API for this. FSRefs are certainly not among the worse Carbon APIs, but if we want to use them in Cocoa we need to do a lot of wrapping and unwrapping, because all Cocoa APIs return and accept NSStrings.

We also do not resolve alias files (in Cocoa) basically because Apple did not give us an abstraction for this.

For me one of the appeals with developing for the Mac platform was and still is the Cocoa framework. If I didn’t care about the tools to get the job done, I probably would not be a Mac user in the first place.

I was just reminded that another problem with some of the Carbon APIs is that they are not using an abstracted string type, but instead a character buffer (sometimes even a Pascal string) and thus treat this as using the “current” encoding of the system, which for most users would be MacRoman (but doesn’t have to).

MacRoman however only has 256 code points (including those for control characters) meaning that providing a string to these functions can require a lossy conversion. Worse are those APIs which return a string, for example ask for the name of a Finder label where the user used characters outside his “current” locale, and nothing is returned.

Most Carbon APIs were updated to support CFString rather than Str255 by CarbonLib 1.6 and Mac OS X 10.0, so except for a few outliers

The longer transition was from FSSpec to FSRef. This meant that if you wanted to both support long Unicode file names and use QuickTime, you had to do a bit of a dance in using FSRefs and converting them to FSSpecs to pass to QuickTime. But I think that’s over now too…

Hi Alan, Yes, it is a pain that there isn’t a Cocoa wrapper for the Alias Manager but really, it aint difficult to write the small amount of code required to resolve them. It isn’t rocket science. Write yourself a nice little wrapper (or use one of the open source ones) and you’ll never need to worry about them again. The same goes for FSRefs. I’ve got a Cocoa app that uses FSRefs for lots of things and writting the code is trivial.

As for the old APIs that still use MacRoman - I couldn’t agree more - they suck. Log bugs on those old API calls whenever you find them.

Just to re-interate - I 100% agree with Wil’s points. I just don’t see some of these things as issues large enough to stop you from shipping a product.

Chris, yeah I think NewMovieFromFile only took an FSSpec. I haven’t looked at QT for years but I think there are a bunch of ways to create a Movie now. Plus lets not forget the tasty goodness of QTKit…

rjt wrote: it is a pain that there isn’t a Cocoa wrapper for the Alias Manager but really, it aint difficult to write the small amount of code required to resolve them. It isn’t rocket science. Write yourself a nice little wrapper (or use one of the open source ones) and you’ll never need to worry about them again.

Well, you will need to worry. Especially when a user contacts you when the Finder locks up on them.

The Alias Manager is another example of necessary Carbon code that hasn’t and should’ve been brought over to Cocoa. And the available open source wrappers don’t cut it. Why? They make the same mistake that Apple did bringing QT, Speech, etc to Cocoa - they only implement some of the required Alias Manager functions.

Mac users can create alias files, and the actual files pointed to by the alias can be located on or moved to a server. At some point this server will be offline. Guess what happens when you go to resolve the alias file using the Apple supplied code in the Low-Level File Management documentation, or any of the open source wrappers? Your app can block the Finder with the wait cursor putting in an appearance for up to a minute or more waiting for the code to time out. There’s a different Alias Manager function that’s needed to avoid this, but it’s not part of Cocoa, it’s not noted in the Low-Level File Management documentation, and it’s not implemented in the open source wrappers. In addition, how would a Cocoa developer even know this is an issue given Apple’s supplied them appropriate code?

InternetConfig is another old Carbon library that comes to mind. It’s deprecated in Carbon, but hasn’t been fully replaced by LaunchServices. But I suppose it’s a bit much to expect a Cocoa API for it when there isn’t even a solid Carbon API on offer!

I’m well aware of how badly the Finder can behavior when it is asked to mount a server which isn’t available (trust me).

I’m simply saying it is possible to do your own wrapper (or enhance an existing one) while we’re waiting for Apple to supply one.

BTW, you should log a bug on Apple’s sample code pointing out the problems with it…..

doh, “behave” not “behavior”….

I even doubt may Cocoa developers know of BDAlias or NDAlias! But would be a good starting point for an Apple solution. No?

26 October 2006

by orangekay

Why do you need an OOP abstraction for every single legacy toolbox call out there? I can’t really think of a single reason aside from laziness. Yes, Cocoa makes doing certain fancy things incredibly difficult and that’s why really big apps don’t use it. Some of these areas need to be addressed pretty badly, but if you just blindly wrap every single Carbon function out there for the sake of doing it then you’re just contributing to code bloat, compromising execution speed by forcing more and more calls through the Obj-C message sending bottleneck and trivializing the purpose of the framework. Wil Shipley is certainly a marketing genius, but I wouldn’t take any programming advice from him.

Why do you need an OOP abstraction for every single legacy toolbox call out there?

As an example, how long would you think I spent on rendering tab triggers in the menu? 30 minutes? Well, that part took around a week. When you remember there are only 52 weeks in a year, that is far too much time to spend on such little thing.

Why did it take this long? Well, the thing being more complex than necessary and lack of documentation is not a good combination. Sprinkle that with what I can only assume are system bugs, and you have a nice cocktail.

The consequence of that is that I reserve very little time to working on things which involve Carbon, because it is a bad investment seen from a cost/benefit perspective, and it is frustrating having to work not only with things that appear needlessly complex, but also to some degree lack documentation.

Thanks for the open letter… contrary to my rep, I do feel bad when I’m criticized, and I love to be praised. I’m kind of like a puppy, except I’m on the internet, so nobody knows I’m a dog.