Developing on Apple Systems

by Miguel de Icaza

Recently Nitesh Dhanjani in a bit of a rude email exchange asked Steve Jobs if he had plans to support something like .NET or Ruby on the Mac.

Update: On a positive note, Nitesh's blog entry has sparked an interesting discussion.

Given the initial confrontational exchange (which can be found here) am not surprised at Steve's immediate comments.

I would like to add some comments to the discussion as we develop a cross platform Common Language Infrastructure (CLI) implementation that also supports the Mac.

On Speed

Steve claims that ".NET with CLI and managed code runs SLOW". It is true that writing code in a managed language or an interpreter is likely going to be slower than the output produced by a C compiler, or the output produced by hand-tuned assembly code.

Lets start with an example: F-Spot is our photo management software which is written in C# and runs on the CLI consistently outperforms iPhoto and scales easily to hundreds of thousands of pictures without the obnoxious pauses that are common in iPhoto for example. F-Spot gets bonus points for being written by a single developer.

F-Spot makes use of a feature in the CLI called "Platform Invoke" (or P/Invoke) which allows code written in a managed language to call into native code easily. In F-Spot's case all the high-level logic is implemented in a managed language and the bits that are performance sensitive (like quickly rendering the image, transforming JPEG images and even the GUI toolkit employed) are implemented in C.

From a productivity stand point this is the best of both worlds: programmers can use a higher-level language to focus on the functionality first. When they identify a performance bottleneck they can easily move this functionality into a C library.

It is possible that Steve has only looked at Microsoft's Rotor implementation of the CLI which merely ships a toy code generator. We encourage them to look at Mono and the various new advanced optimizations that we are introducing in Mono.

On Productivity

Although raw performance is good for some applications they impose a heavy toll on the developer. A professionally written and hand tuned assembly language program will likely perform better than anything else generated by a compiler.

The language and runtime choice is a tradeoff that developers make. A balance between the time available for releasing the product; the budget available for creating and maintaining the application; the target system requirements; any third party libraries and components required; the in-house expertise; availability of developers with knowledge to develop and maintain the code; language learnability; the project life-span and the requirements that it might impose on the project: from languages designed to maintain software over a large period of time to write-once, barely-touch-afterwards software.

There is not a single solution to the problem of course, but we believe that Mono does bring a good mix of elements that make it a good choice for a large body of developers. Some people will continue to be happy with their existing tools and their existing frameworks, but I believe Mono can help Unix developers produce better applications faster.

Mac developers interested in using Mono and its tools on the OSX could use the Cocoa# bindings today. It is not complete, but it has a good foundation on which people can add more bindings to Objective-C libraries.

As a project maintainer, am interested in learning what Cocoa# and Mono are missing for developers on the OSX platform.

I know that OSX developers in the past have asked for Mono integration into X-Code, this is an area where collaboration between Apple and Mono would be useful. Alternatively there is the X-Develop IDE by OmniCore and eventually when the next version of Gtk+ ships with Quartz support we will likely ship MonoDevelop for OSX as well.

Tapping Existing Developers

Another advantage of Mono and the CLI is that it becomes easy for existing developers that have been targeting .NET to target new platforms.

This is just a pragmatic point. Developers can reuse a large body of their expertise, their books, their documentation, their connections to bring their software to Unix. Some things might have to change to work effectively on Unix, but porting an application from Windows to Unix is no longer a multi-month or multi-year project.

Porting an application from .NET to Mono is similar to porting a Unix application from SystemV to BSD: there are a few differences, but they make up only a tiny fraction of the application.

On Languages

The CLI was designed so it could host efficiently any programming languages in use today, but it also contains a strong interoperability layer. I already mentioned P/Invoke which Mono supports, but the framework is complete enough that it is possible to also integrate other object systems easily into the system. Today we have done this with Gtk's GObjects and some volunteers are working into adding COM support to Mono.

The languages story is a powerful one.

The CLI defines a set of language interoperability requirements which every language should adhere to (these guidelines are called the "Common Language Specification"). By following these guidelines once an API is developed in any of the CLI languages the API becomes available to every other language.

Apple has struggled in the past in maintaining two code bases: one for Objective-C programmers to develop GUI applications and another one in Java.

It is understandable that they do not want to support every single one of their APIs for every programming language out there; otherwise their own development would slow down, it is just not possible to do so.

This is where I think the CLI adds tremendous value. Today developers only have to "bind" the API once and it becomes available to all the languages in the CLI ecosystem.

Consider Geoff's effort to bind Cocoa. The Cocoa bindings that Geoff has hand-written are now available to all of the programming languages that target the CLI. Apple developers can use this API and any of the other CLI APIs developed by .NET and Mono developers on their applications with their favorite programming language: Boo, Nemerle, C#, JavaScript, Java and more.

Interoperability

There are a number of ways in which a language can participate in the CLI ecosystem. The most common one is to have the compiler translate the source language into CLI byte codes. This requires the creation of a compiler that targets the CLI.

Examples of some open source compilers in this group include: C#, Python (with the IronPython compiler), Java (with the IKVM compiler), Nemerle and Boo. In addition to this there are several commercial compilers available: Fujitsu's Cobol compiler, ISE's Eiffel, RemObjects, Microsoft's own Managed C/C++ and many more.

In some cases it is easier to write a "bridge" than to write a new compiler. This reuses an existing implementation and merely bridges the calls between the existing language and the CLI universe.

Bridges have been developed for Python (yes, this is a parallel approach), Perl, Ruby and OpenOffice's UNO (this is how we are able to script OpenOffice using Mono). There are more, but I do not keep track of these.

In addition Mono provides an embedding interface which allows developers to embed the virtual machine into an existing application. OpenOffice Mono integration (available in OpenSUSE 10), the game Second Life and the Unity game engine all use this embedding interface.

Collaboration

As I mentioned before, I do not believe that Mono is an ideal solution for every kind of application; Like every other framework Mono also has its own limitations and features missing; Its up to every developer to make this choice. But we believe we got a very solid mix.

One Mono's goals is to work-well-with-others. Working with ISVs to ensure that their software runs with Mono and Unix is one of the things we take pride in doing. We always welcome new collaborations on the Mono universe.

Update: Erik also comments.

Posted on 28 Dec 2005