Even six and a half years after the debut of Mac OS X, this programming API debate continues to draw
flames passionate cries of outrage from both camps: the classic Mac OS developers versus the NeXTish developers. [Carbon viewpoint][Cocoa rebuttal] And while Apple does officially intend for Carbon and Cocoa to be both native, first-class APIs, I always got the feeling that the ultimate target was Cocoa. This is unsurprising, considering that Cocoa, derived from NEXTSTEP, is therefore sort of Steve Jobs’ baby.
Now, as I’ve stated before, I am not a developer. But as an end-user, there do seem to be differences. Cocoa apps seem better integrated, and you get a lot of system-level niceties across the board, like integrated spell-checking, deep undos, consistent keyboard shortcuts. But this is largely an illusion. If a Carbon developer were so inclined, these features could likewise be implemented in their app using the available API. It would just take more code.
Mostly, this is a flame-war based on errant perceptions. With OS X 10.0, the main purpose of Carbon was to provide a library that would allow an app to run on both Classic and OS X, and to which a legacy Classic app could be easily ported (effectively porting it to OS X), similar to Win32s, a Windows compatibility library that allowed programs to be written for both Windows 3.11 and Windows 95 and NT4.
But Carbon is no evolutionary dead-end. While Cocoa tends to get the spotlight, Carbon has grown as well. On the system-level, Carbon has always implemented a lot of the lower level functions that are more amenable to being coded in a procedural language (i.e., C) and which most/all Cocoa apps depend on. On an API level, the library has been extended to keep up with Cocoa, so much so that at this point, it would be possible to write a Carbon app that was essentially identical to a Cocoa app (except for the number of lines of code.)
The major difference between Carbon and Cocoa seem to be the language of choice. Carbon contains much of the legacy of the Mac Toolbox API, and even the Lisa API (originally written in Pascal!) and it is grounded in a procedural programming style. C is its native language, although like all APIs, there are plenty of language bindings (including Objective C!) Cocoa is descended from NEXTSTEP—a newer codebase than Carbon’s, but still pretty old (now pushing 20 years—and, really, much older than that, considering that, ultimately, NEXTSTEP is based in UNIX.) Much of the elegance of using Cocoa for development is the fact that it is based on Objective C—a superset of C that implements object-oriented programming quite differently from C++. Obj C incorporates a lot of features from Smalltalk, an object-oriented language developed by Xerox PARC in the 1970s. (A lot of these features have likewise been adopted by Ruby as well.) Key to Objective C (and Smalltalk, and missing entirely from C++) is the idea of message passing, which allows one to leverage existing base classes without having to create subclasses, reducing a lot of code complexity, and allowing maximal code re-use.
The separate existence of Carbon and Cocoa is largely an accident of history, reflecting the return of Steve Jobs to Apple, and also the fact that the Classic OS had reached the limits of viability (which explains why Copland and stand-alone Rhapsody failed) and that they needed to embrace modern OS techniques (like pre-emptive multitasking!) It could’ve been completely different, and Apple could’ve started from scratch a la Windows NT, with compatibility libraries to leverage the existing Mac OS Classic and NEXTSTEP code bases, but instead they deigned to use tried-and-true technologies. This decision to not reinvent the wheel seems to be reflected all the way down to the fact that the kernel is a Mach microkernel, and the low level subsystems are essentially run by a flavor of BSD.
But the separate identities of Cocoa and Carbon will likely blur with time. According to the wikipedia article on Carbon, there are ways to access Cocoa objects in C/C++, and many Carbon functions (many of which are essential to a functioning app) are wrapped in Cocoa objects.
The existence of Carbon apps that don’t feel as polished as Cocoa apps are largely due to the fact that (1) Classic apps can only be ported via Carbon, unless you really want to rewrite thousands of lines of code, translating it to Objective C, and things like Adobe’s line of DTP software and MS Office are venerable, very popular, complex pieces of code that harbor a lot of legacy baggage, and (2) in C, you have to manually integrate a lot of the features that you would automatically get for free by using Cocoa objects, and this work may simply not be worth it to the developer.
But be that as it may, there is no real reason why a Carbon app can’t be as nice as a Cocoa app since, ultimately, they are APIs to the same OS, and there is no rule saying you can’t mix C and Objective C or Carbon functions and Cocoa objects. Like Apple is always saying, it looks like it’s time to “Think different.”