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.