Saturday, November 17, 2012

Serious Mono Development on the Mac: Why Not?

I've had Mono installed on my Macs for years now.  Mostly it was a novelty--occasionally I'd test some CLI or trivial Windows Forms app I'd written at work, just to see if it would run.  I wrote one quick image stitching program on the Mac for a friend's wife's blog (using GDI+, which actually worked, which in hindsight I realize is pretty impressive), but I've never done any "real" C# development on the Mac, for a few reasons:
  1. That's just wrong.
  2. I didn't have a good IDE (more on that in a bit).
  3. Compiling and running from the command line is gross.  (Yes, I know, MonoDevelop, getting to that...)
  4. I mostly wanted to do GUI stuff, the Windows Forms support was only partial, GTK sounds gross because it's not native to either .NET *or* the Mac, I didn't know any Cocoa, and Cocoa# sounded like a pretty experimental hack when I first read about it anyway.

Not So Wrong Anymore

I think I've gotten past point 1.  It comforts me somehow that Mono is now something of a commercial product thanks to Xamarin's work on MonoTouch, which presumably has positive implications for the desktop Cocoa bindings, etc.

When Mono on the Mac felt like an unsupported hack (I don't really know what kind of support Novell provided), I wouldn't have thought to use C# for anything but personal tinkering.  In particular, the thought of distributing a Mono app was out of the question, not because it was technically impossible, but because of point 4 and the whole packaging problem.  You can't distribute a Windows Forms app to Mac users; they'll hate and shame you.  The same probably goes for a GTK# app, with the possible exception of MonoDevelop.  So you had to develop a Cocoa# app, which felt both unsafe and unappealing.  And even if you completed one of those funky Cocoa# apps, you'd either have to somehow package it together with Mono or tell your users to go download this weird experimental Windowsy runtime platform to run your app.  Since very few users would have Mono installed by default, that would mean a huge download either way, even if your application itself were trivial.

But Mono on the Mac doesn't seem nearly so wrong now.  Even without Xamarin, C# on the Mac is probably here to stay thanks to the Unity folks.  For GUI development, MonoMac is ostensibly a decent set of Cocoa bindings that is well supported or at least has the interest of Miguel de Icaza, which goes a long way.  There's a MonoDevelop plugin with MonoMac project types, a packaging system for bundling only the assemblies used by your app, and even support for deploying to the Mac App Store.  Combine that with MonoTouch gaining traction as a real solution for iOS development, and MonoMac really doesn't sound too scary anymore.

A Real IDE

Realistically, I'm not going to do any serious coding without an IDE.  One of the things that makes .NET such a productive platform is its discoverability via IDE tools.  In C, how do you learn what you can do with a string?  Get a book?  Google "string manipulation?"  In C#, how do you learn what you can do with a string?  Type a period after the variable name or string literal.  I'm productive in typed, object-oriented, garbage-collected languages not just because of the high-level abstractions provided by the languages but because the typing system, object-orientation, and garbage collection all lend themselves to library design where all functionality pertinent to an object can be accessed via a method on that object.  This means I don't need to know an entire library before I start working with it or interrupt my workflow for an internet search every time I need to call a new method.  I do a quick Google search for a "starting point"--the main class of interest--and Intellisense my way to a working program.  This is huge.

There are other perks of an IDE, of course, like automatic syntax checking (love those red squigglies), GUI access to the file structure, streamlined builds,  and so on.  These are all things provided by IDEs like Visual Studio on Windows and XCode on the Mac.  If I'm going to do C# development on the Mac, I'm going to do it in an IDE.  And that's partly why, to date, I haven't done C# development on the Mac.

When I wrote that quick C# app on my Mac for a friend, it took longer than it should have because I was editing my program in a text editor with no syntax checking or Intellisense and compiling from the command line.  I don't remember if MonoDevelop existed at the time, but if it did, I was probably turned off for the following reasons:

  1. It's GTK.  Ugh.  Nothing against GTK *on Linux*, but this is my Mac and you're making it ugly.  Not even because GTK is especially ugly, but because you're clashing with the rest of my system.
  2. The non-native L&F leads me to expect non-native behaviors (awkward keyboard shortcuts, swapped button order in dialogs, etc.).  Basically I expect the developers to make it Mac-like only as a half-hearted afterthought.  Seriously, if you expect me to Ctrl-C for Copy on my Mac, we're done.
  3. I've used enough OSS GUI apps to keep my expectations really low.
Well, tonight I needed to script some command-line work, and I very nearly used Perl.  But I thought to myself, "Why am I doing this?  I'm going to have to go re-learn all the basics like I do every time I write a Perl script, and yes, it will be terse, but even if it takes me twice as many lines in C#, it'll take me half the time because I know C# and what I don't know or don't remember is discoverable with a good IDE, and I have this MonoDevelop thing sitting on my Mac for the Xamarin contest that I will never complete now that I'm distracted by silly code riddles (and would never have completed anyway), so let's give it a shot!

I fired up MonoDevelop and created a Console solution.  Aesthetically un-awesome, but behaviorally not unlike Visual Studio project setup.  I started typing and got some lovely code completion, with a few gotchas:
  1. Code completion is case sensitive.  Gah!  I can't tell you how many times in an evening I typed "System.io<TAB>" and ended up with "System.IndexOutOfRangeException."  Hopefully there's a setting to configure this.  If not I may submit a feature request.  They'll probably just tell me I'm spoiled by VS.
  2. In general it appears pickier than Visual Studio, especially VS 2010+, which match any text within a suggestion, not just the first word.
The syntax checking appears to be less than awesome too.  I frequently had to build before discovering I had a typo or other syntactical problem.

All that said, I think it's good enough.  Here are some things it does right:
  1. Project creation and organization is nice.
  2. Build and run works as expected, with configurable "Custom Execution Modes" for saving lists of command-line arguments and whatnot.
  3. The keyboard shortcuts are correct!  It behaves like a native Mac app for the shortcuts I use frequently, and that's enough.
Okay, that's a short list, but this is from one evening's use.  Basically, it's a real IDE that isn't so horribly un-Mac-like as to be unusable, and it lets you develop C# code on your Mac.

Better Than the Alternatives

What I realized tonight was that developing a quick C# console app in MonoDevelop was my best choice for the task at hand.  I had lots of scripting languages to choose from, but I know C# better and I have a decent environment for writing and running it, so why not?  I'm thinking about how this logic extends to real Mac GUI development.  If the Cocoa bindings are decent, MonoDevelop is an acceptable IDE (XCode is certainly nothing to write home about anyway), and C# beats the pants off of Objective-C.  There's a real developer community around the iOS stuff, and presumably there's some trickle-up to the Mac.  I don't have the time or interest to get good at Objective-C, but I could see learning enough of the Cocoa API to string a GUI to some good, sensible C# model/controller code.  Mono might actually get me developing for the Mac.

No comments:

Post a Comment