Sunday, June 26, 2011

My impressions of F# after three years

It will be soon 3 years that I have been using F# both professionally and privately.

At work, I have used it to implement the simulator module of Prover iLock. This is a complete rewrite of the first version of the simulator, which was initially written in C#. The rewrite was necessary for a number of reasons. As is often the case with the first version of any software, its design did not age well, leading to bugs, excessive memory use and long execution times. I think the main reason was simply that requirements were not clear when the project was started.

The main challenge of this simulator is to support distributed systems where components use different execution models and link protocols. The term "execution model" is a bit specific to the field, namely railway signalling systems. Historically, these systems were implemented using relays. Their modern counter-parts include relays (they are still popular), software which emulates relays (to take advantage of existing field knowledge and practices) and to a lesser extent procedural languages.
The second category include platforms such as VHLC and Microlok, but there are many other similar yet different technologies. Although similar, they all differ slightly in how they handle communication with remote devices, how timers are handled, in what order instructions are executed...

I am happy to report that so far, most of the objectives for the new implementation have been reached or exceeded:

  • Adding a new platform takes little effort.
  • Memory use has drastically gone down, despite massive use of short-lived arrays to hold state.
  • Run-time efficiency is OK, although a bit worse than the first version in some cases. The main reason here is that I made no attempt to perform some of the optimizations that introduced bugs in the first version (maintaining consistency with respect to time when simulating distributed systems is difficult). 
  • Few known bugs.

Time will tell how this second version ages, but so far, I haven't needed to spend a lot of time extending or fixing it. Which is a bit sad, as it means I am not spending as much time working with F# as I would like :)

Another important F# module I developed was a bridge translating the C# representation of systems from the main program to the simulator module. This other project is also successful. The main lesson learned is not to reuse data between different software modules. This may sound surprising at first, but the gains of designing data structures that do one thing well outweigh the costs of maintaining similar types which appear to duplicate code. The data structures in the main program are designed to make it easy to build and modify them via a scripting API. The data structures in the simulator are designed for efficiency of simulation.

Defining types in F# is easily done thanks to records and discriminated unions. Translating from one type hierarchy to another is facilitated by pattern matching. I'm inclined to think the lack for these constructs in other languages leads to excessively large and complex data-types, as they try solve multiple problems at once. Although the evils of code duplication are well known, there are also risks associated to excessive code sharing. Getting the right balance in the number of data types requires a flexible and rich family of types, and it's now clear to me that C# is too poor in that respect. Classes and enums are not enough.

I have used F# in a range of projects, mostly game-related. Asteroid Sharpshooter was released in January. Although not a commercial success (168 copies sold so far), it showed it was possible to write games with high performance requirements in F#, despite the weaknesses of .Net on the Xbox 360. I have not gotten a single bug report so far, but this may be due to the small amount of users. Its rating of slightly over 3 stars out of 5 seems to indicate users are moderately satisfied with the game.

I have also developed a "new" way of developing game user interfaces which I think blows the "old" way out of the water. The new way I am referring too allows to write reactive UIs over the game update loop in a simple way, allowing for much faster development and more robust software. The old way either leads to unresponsive interfaces or buggy ones that fail to deal with storage management or any other lengthy processing requiring asynchronous programming. I doubt many programmers without a functional background realize the power of computation expressions in F#.

By the way, I often hear and read that "F# is not good for UI". This is total nonsense. I normally try to express myself in a gentle, moderate, non-controversial way on this blog, so just to emphasize how I feel about this:

"F# is not good for UI" is total nonsense.

There are basically two problems with UI.

  1. Lots of boring code to write: widget layout, boiler-plate...
  2. Achieving good responsiveness
Point 1 is addressed by tools and code generation, and is actually language-independent. What do I care if automatically-generated code is in C#, IL or F#? As long as I don't have to write it...

Even in the case when I do write the code myself, I don't find C# and F# to differ significantly in that matter. F#'s supported for nested  variable and function definitions help limit the number of members in a class, which avoids one of C# problems, namely over-blown classes with numerous private fields and methods.

Point 2 is solved by F#'s async. In that respect, I wonder how people have been dealing with the problem in C#? BackgroundWorker and threads are not so fun to use.

In all my projects, I think I have noticed two strong differences with developing in a C++-like procedural language:

  1. I spend a lot less time debugging. Modulo trivial bugs, functional code that is correctly typed just works out of the box. Any time I went out of the pure functional path to introduce mutability, direct access to items in arrays... I introduced bugs.
  2. The relatively low verbosity of F# and its high-level constructs make it easier to implement more complex algorithms. For instance, I could never get my head around Runge-Kutta(4) in C++, implementing it in F# was trivial, all while learning F#.
On the negative sides, I found that Visual Studio's debugger can be difficult to use with F#. In other words, it's good you don't spend a lot of times debugging, because it can be hard to understand what's going on in the debugger. Two of the main issues, I think, reside on the one hand in the fact that a debugger is statement and line oriented, where a functional language is expression-oriented, and on the other hand in a somewhat confusing handling of F# closures and lambdas by the debugger. For instance, debugging code in computation expressions is close to impossible.

That's all for now. If you are decision-taker in your company, and .Net is part of the technologies you use, I think you simply cannot afford not looking at F#. I know every time a new language is introduced, productivity gains are claimed by its inventors.

I did not invent F# and don't work for Microsoft, but I can vouch for the alleged productivity gains. Your mileage may vary, but I don't think it will.

Friday, June 10, 2011

Is that a cloud, or is it a storm?

I was recently forced to spend some time at a hospital due to a bowel inflammation. The inflammation is due to a chronic disease whose cause is still unknown. It's also not clear whether there are non-surgical treatments to completely cure the disease. I won't go into details in this post, suffices it to say the event has distracted me a bit from my usual focus on games, Xbox360 and XNA.

Let me start with a few words about nutrition journals. Although there is little scientifically established information about the link between food types and inflammations of the digestive tract, many patients report that specific diets do help. The problem is that there does not seem to be any single diet that fits all.

It is therefore important for each individual to assess the effect of each food type on one's digestive system. Any good programmer knows it: before you optimize, you need to measure. The same goes for nutrition. Before doing changes to one's regime, it is important to keep track of what goes in and, well, what comes out.

The difficulty is that keeping such a journal requires discipline, as it's best to record that information as soon as meals are eaten, and directly after visits to the bathroom.

This is were mobile devices and the net comes into the picture. Smart phones make it easy to fill in the journal. The journal itself is probably best kept on a central server (in the "cloud") in order to be accessible from anywhere at any time through any device.

All of this is a good excuse for me to start having fun with WebSharper and F#, of course. WebSharper makes it possible to design web applications entirely in F#. The client code is compiled into javascript and executed in the browser.

The recent panic about .NET and Silverlight being dropped from Windows 8 is interesting in many aspects. .NET developers are reluctant to switch to javascript, a feeling I share and understand. The current tendency however seems to use javascript as a virtual machine targeted by a range of nicer technologies. Examples include F# through WebSharper, XNA, emulators... I for one rejoice in Microsoft's adoption of open standards.

But do I? I see Windows 8 as an attempt to regain control over the Web. What place will have competing web browsers (Firefox, Google Chrome, Opera...) in the new operating system when it includes it's own browser as a mandatory component? If the web view of Windows 8 succeeds in pushing out other browsers, Microsoft will be free to invent new technologies, forcing others to play catch up. Are we getting back to the Windows 98 and "optimized for IE6" days?

Happily, I don't see that happening. Non-Microsoft smart phones and tablets have conquered large portions of territory once owned by Microsoft and Intel. Hopefully HTML5+js will gain adoption and proper support across all platforms.

Note that the irrelevance of platform-specific technologies such as Silverlight applies to others as well. Why keep making iPhone and Android apps when you can make a web app instead? Are the specificities of GUIs compelling arguments to redevelop client apps multiple times? Will users be willing to pay for apps when free web apps become ubiquitous?

We can turn to the PC platform to find hints of answers. The computing power they offer still has no equivalent in the cloud, and demanding applications such as development tools, CAD and video games will always feel best at home on a PC. I expect those applications to keep being developed using a mix of native and VM-based languages and frameworks.

Is there a similar place on the smart phone? Applications requiring unrestricted access to the mobile's resources come to my mind. This includes media players, games, device management... I expect however that a very large eco-system based on "silly apps" will soon disappear, possibly in a very sudden manner.