Tuesday, December 21, 2010

On The Need for MonoMac

I continue to listen to the Dot Net Rocks podcast even though I've yet to write a line of C#. It is a well done and even handed podcast, and one of these days I shall write a post about how the hosts demonstrate weekly how one can advocate a technology while maintaining credibility. But this post is about MonoMac, which I haven't used but someone at my company is, and I go to the meetings. If this means I'm writing without enough facts, then this might be a blog.

[Update: I've been informed that what I've written below is not possible in MonoMac. Apparently, the MonoMac developer community cannot imagine the concept that C# isn't the solution for every programming situation. I am not a publicly profane person, but I'm tempted here. But please keep on reading about an alternate universe where programmers don't fall in love with a language at the expense of reason.]

Tireless advocate for all things Mono, Miguel de Icaza was on the show this week and he got me thinking about why anyone would use MonoMac. And I do think many people will use MonoMac, but (I hope) not for the reasons Mr. de Icaza gave on the podcast.

To summarize de Icaza's pitch for using MonoMac. If you love C# and managed code, then you can use your favorite language to write Mac applications. You'll have to do at least some work outside your beloved Visual Studio, and you'll have to use completely unfamiliar APIs but at least it'll be in C#. And you'll get to use the whole Cocoa API, plus various other OS X technologies like Core Audio, Core Animation, etc., but they'll be wrapped in C# shims. Oh, and you'll get a strongly typed language instead of the horrors of dealing with the chaos of loose typing.

As someone who's spent his professional life writing cross-platform code, this is a really bad and limiting sales pitch. It is pitched at people who just don't want to learn another language for whatever reason, but would be willing to learn the entire OS X API, except trapped in a language for which it's calling syntax becomes cumbersome.

First, of all, you have to realize that the Objective-C language is small. It is not C++, which even a professional coder might never learn in its entirety. It is a elegant little language which adds object oriented extensions to C. The fact that you spend most of your time using those extensions doesn't make them any more verbose. It has had some further extensions in recent years, but it is still reasonably compact.

Also realize that the OS X APIs are huge, composed of literally thousands of messages, methods, structures, enumerations and constants in dozens of frameworks. I've been programming on OS X for a decade, and Apple adds APIs at a rate faster than I can learn them.

So, MonoMac saves you the trouble of learning a small language, while expecting you to master a large API which has been transmogrified to make sense to C# programmers. And the vast majority of the documentation and forum postings for that API assume it is in another language. That's not much of a pitch.

I used to work on a karyotyping application when I was living in suburban Chicago. It was Mac/PC and was written in C++. 90% of our code was shared between the platforms. We used standard application frameworks, at the time PowerPlant and MFC which relieved us of maintaing code every application uses, and gave us a lightweight entry into native appearances and behaviors. Almost all the document data structure and rendering code was cross-platform. So 10% of the code was dealing with the user facing part of the application or calling into native operating system services and the rest was vanilla C++ dealing with an abstract environment.

Consider a typical Model-View-Controller design. If one has a shared language like C# running in Mono, then we can factor our code such that all or almost all of the Model code is in shared vanilla C#, some or even most of the Controller code can be written in C#, although I'd prefer that Objective-C be used for Controllers on the Mac, and the bulk of the View code is no code at all, but what you get from the framework by using standard widgets, windows and other classes using the provided GUI tools. Basically, you want the framework to handle everything outside your document frame in your window. Depending on the application, you can have very high code reuse, or less if you need high performance access to operating system services, such as the example de Icaza gave of using the Audio Units API for sound processing. Regardless, this should be abstracted away and created with factories to make it callable from vanilla code.

So you'd end up with 4 kinds of code:
Vanilla C# that doesn't do much beyond manipulate vanilla objects and simple types, and implement various abstract interfaces or protocols.
Windows specific C# that makes use of Windows frameworks
MonoMac specific C# that makes use of native Mac services
Objective-C for Mac specific GUI code and isn't as awkward as C# would be.

For a lot of applications the first kind can be the bulk of code.

This takes discipline but it results in a more maintainable, focused code base.

I think that's a better pitch.

Not that I'm advocating it, I haven't tried to see if my decade old experiences with cross-platform design are transferable to the Mono runtime environment. Nor do I think Mono has proven itself enough for risking a project on it. I was floored that such a well known project only has 200 or so active users.

And I like Objective-C, it's a lot of fun.