I recently enjoyed an article written by Microsoft employee Justin Angel on the cross platform nature of Silverlight.
I have to admit.. I like Silverlight a lot. Or at least I think I do. I like the idea of what I think Silverlight is... (rest assured I will elaborate about that on a separate date).
But something struck me in Justin's article:
"A common trend amongst all the differences we’ve surveyed in this article is that they’re all to do with deep Operating System Integration or Browser Integration. These are either issues with the operating system or the browser itself.
Remember that .Net at it’s core is just a framework abstraction on top of the O/S.
And as anyone who’s ever written a framework knows, some differences cannot be abstracted away. "
I can make no claim of writing a framework the magnitude of .Net, and I am sure there are a number of show stoppers regarding what is exposed to Silverlight outside of Microsoft's home turf of the Windows environment.
But, I do have some experience with cross platform development, and I would have to say that I ran into these same issues under Python and Java.
So what's my boggle?
In those situations, I certainly had to write platform specific code/factories and execute their strategies based on where the application was running. However, I wrote this code as a shared middleware layer. All of my client application code called this middleware layer without worrying about the platform it was sitting on, and the middleware handled the appropriate funneling of platform specific code.
If that isn't abstraction, I don't know what is. So, if I can do this, why can't Silverlight, Python or Java? Justin's assertion that "some differences can't be abstracted away" is true in a "I can right click and you can't" or a "I have to touch/tilt and you have a keyboard" type of way... But what about those things below the surface of user interfaces and interaction?
I think the fuzzy truth here is one of politics and avoidance of religious debate. With my framework, I had the luxury of making a decision about how it should behave. And I also knew that I likely wouldn't have to worry about platforms outside of Windows and Posix flavors.
Often times, OS's have functions that are similar in feature, but behave slightly differently. For example, in Linux, if you attempt to move a file across a hard drive boundary, the operating system would bark at you. It's not legal because a "move" in Linux implies that you're merely changing it's pointer in the file look-up table. Windows is another story, it will change the pointer if it's on the same drive, and do a copy/delete operation if it's not.
In my framework, I had a version of "move" called by all of my client code that made this operation behave like Windows across the board. Clearly, I didn't have a horde of ravenous Linux fanboys to worry about here saying that I was doing it "wrong", or I was trying to mislead anyone into believing Redhat did that operation some other way.
But, you can imagine the type of drama Microsoft would have to deal with if they took it upon themselves to say that some operations on the Mac should be changed to act more like a Windows box? Perhaps the Mono team is running into similar challenges with Moonlight.
So.. I would revise Justin's statement slightly to say that "aside from extreme, unresolvable cases, some differences can't be abstracted away without introducing bias toward one platform"
In a perfect world, I'd like to see cross platform frameworks take the best features of one side or the other. Like a stew of the best functions of each platform they target. Of course, this will never happen, and in some cases isn't always feasible (as Justin's article indicates, there are some Windows OS concepts that simply don't exist on OSX). And it puts the burden of those decisions on the cross-platform framework developers. Probably not a place they would prefer to be.
In closing, I'd like to add another Option to Justin's "What should developers do?"
Option 4 - Know what you want to target, and implement your own abstractions where you can.
The powers behind Silverlight, Java, Python, etc.. They really can't make these command decisions without causing turmoil (whether it's the burden of additional testing around overriding native behavior of a platform, or the danger of a lynching from fans of a particular OS). But nothing stops you from doing it if you own your application. If you want Mac and Windows to both return "INFINITY", thats a trivial abstraction you can do to reduce the burden of code branching in your client code.
Or... if you don't like such hackery, KNOW what you want to target, and go out of your way to avoid the APIs where things are known to behave differently or flaky.
Cross platform development is tricky business and requires a high level view of the app's expectations across all the places it's going to run. But there are a lot of software developers out there that are doing it. Particularly in the game development realm.
Next time you go to the store, see how many of the same titles exist between Playstation 3 and XBox, and see how many common middleware frameworks are credited on the back of the box. (Havok, Bink Video, fMod, etc) This is a prime example of Option 4 in action.
In the end, it all has to behave the same, so the differences are formalities. Or as I like to put it... Cross Plat-formalities...