views:

598

answers:

4

I develop mainly line of business applications.No scientific operations. No complex calculations. Just tie User Interface to database. The only reason I use threading is to do some work in background and still keep UI responding.

This may not be the best approach but this is what I follow

1.Create an working application first(without threads) and give it to end user to play for the sake of feedback.
2.Once all requirements are locked, I try to use threads wherever it makes sense to improve performance.

The code for steps 1 & 2 is overwhelmingly different and threading code dominates the actual code.

1.Will F# make my life easier in case of Line of Business applications?
2.Are there any particular UI technologies that will fit best with F#? I mainly work on ASP.NET & Silverlight. WPF now & then.
3.Are there any good examples of Line of business applications/demos with F#?

I am not asking whether it is possible to develop Line of Business application in F#. I am asking whether F# will make my life easier to develop Line of Business applications when compared to C#? My main concern will be threading & UI synchronization.

+7  A: 

That's a very hard question to answer - I think that F# would make some aspects of your life much easier and some a bit harder.

On the plus side, dealing with threading should be relatively painless - F# async workflows are a huge benefit. Also, F# Interactive makes rapidly iterating and exploring code very easy. To me, this is a huge benefit over C#, since I can test out minor code changes without going through a full build.

On the down side, the tooling for F# isn't where it is for C#, which means that you won't have access to GUI-builders, refactoring tools, etc. It's hard to say how big of a productivity hit this would cause you without knowing more about your scenario. One workaround would be to create a multi-language solution which has a thin C# front-end, but again the complexity may not be worth the benefit.

kvb
+18  A: 

I'm in the same boat as you, doing lots and lots of line-of-business type apps, nothing "fun" like games or compilers or search engines.

Your mileage will vary, but at least in my own experience a lot of dev teams are reluctant to jump right into F# because no one else on the team knows or has even heard of it. And right off the bat, you have to fight those questions like "what does it do differently from C#?" If you can convince your boss to let you write a few demo apps with it, go for it!

So with that being said, I find that C# isn't very good at business rules, but it handles GUIs like a champ; F#'s immutability makes GUI development awkward, but business rules and workflows feel natural. So the two languages have their own strengths and compliments one another's weaknesses.

In my own LOB apps, F# runs circles around C# in a few areas:

  • F#'s async workflows and mailbox processors orders of magnitude easier to work with than native threads and even task parallel library. Since using mailbox processors for interthread communication, I don't even remember the last time I've had to lock or thread.join() anything for syncronization at all.

  • Defining business rules engines and DSLs with unions FTW! Every non-trivial LOB app I've ever worked on has its own half-baked rules language and interpreter, and its almost always based on recursively switching on an enum to drill through the rules and find a match. Current project I have now contains 1300+ public classes, 900 or so are simple container classes to represent a rule. I think representing the rules as an F# union would substantially reduce the code bloat and make for a better engine.

  • Immutable code just works better -- if you get a new object with an invalid state, you don't have to search far to find the offending line of code, everything you need to know is on the call stack. If you have a mutable object with an invalid state, sometimes you have to spend a lot of time tracking it down. You can write immutable code in C#, but its really hard not to fall back on mutability, especially when you're modifying an object in a loop.

  • I hate nulls. I can't give an exact estimate, but it feels like half the bugs we get in production are null reference exceptions -- an object is improperly initialized and you don't know about it until you're 30 stack frames deep in code. I think F# would help us write more bug free code the first time around.

C# usually works well when:

  • You're writing GUI code or working with inherently mutable systems.

  • Exposing a DLL or web service to many different clients.

  • Your boss won't let you use the tools you want ;)

So if you can get over the "why would we want to use a new language hurdle", I think F# will indeed make your life easier.

Juliet
Great answer. Only point I'd disagree on is I think F# quite good for GUIs too if you take a DSL apporach à la WebSharper (http://www.intellifactory.com/)
Robert
+1. I'd only add that F# can be compiled into a DLL which can then bet called by a C# program. The best uses I've found is when I mesh the two together.
tzenes
@Juliet, I don't doubt you but I'm not still not sure why it is that developing GUI's would be inherently any more easily done with mutability. Would you please be so kind as to share a concrete example to help me understand your point?
Onorio Catenacci
@Onorio: basically every UI element is a blob of mutable state, as all the properties like its location, size, eventhandlers, text, child controls collections, or other properties can be freely mutated. So it doesn't map very cleanly to an immutable representation of form state. So you either have to jump through hoops trying to update your immutable form state everytime your UI changes, or you end up writing imperative F#. At least that was *my* experience, YMMV.
Juliet
@Juliet, Fabulous! Could you please give explain how F# deals with Initialization without having nulls?
funwithcoding
@funwithcoding: sure! The real problem with nulls in C# is that they look and feel exactly like non-nulls. If you have a class which accepts a `Person` object, you can't guarantee that you have an actual instance, so you have to null-check or risk a NullReference exception. In F#, you can't create null instances of F# classes (at least not without jumping through a lot of hoops), so you represent the non-existence of an object by wrapping it in an `option` type. Since you change the datatype from `Person` to `Person option`, you communicate the null-ness of an object (cont...)
Juliet
(prev...) through its datatype. Using option types, you inform the user of impending nulls, and you force them to use pattern matching to handle both null and non-null instances of your object. Result: dramatically reduced occurrences of NullReferenceExceptions.
Juliet
+6  A: 

@Juliet and @kvb have good answers, I just want to reiterate how useful F# is for making threading easy. In my blog post "An RSS Dashboard in F#, part six (putting it all together with a WPF GUI)", I say

...Note the nifty use of ‘async’ here – I use Async.StartImmediate, which means all the code runs on the UI thread (where the Click handler starts), but I can still do non-blocking sleeps that don’t jam up the UI. This is one way that F# async just blows the doors off everything else.

...

Our “ago” information (“3 minutes ago”) will quickly get stale if we don’t refresh it, so we start a loop that redraws every minute. Once again, F# async kicks butt, as I can just write this as though it were a synchronous loop running on the UI thread, but the non-blocking sleep call ensures that the UI stays live. Awesome. ...

but that blog post is an example of using F# to hand-code the entire UI. That implies trading away all of the great GUI tooling you get with C# or VB. I imagine that a hybrid approach can potentially net almost all of the benefits of both (with the cost of having two projects in the solution where you previous just had one), but I don't (yet) have direct experience of my own to share here.

(Is there a canonical "problem example" of a C# GUI app where you need to add threading to improve perf or keep the app live during some long operation? If so, I should check it out.)

Brian
@Brian Great post! Well examples of 'keep the app live' in Line of Business applications are numerous.For example, Generation of reports on background thread and update the UI with chunks of data processed so far. Improve performance scenarios are like pulling data from different sources(may be for different regions) and show it on UI.Once again thanks for the nice post.
funwithcoding
+1  A: 

Something you might like to see:

The First Substantial Line of Business Application in F#

A big LOB app in F#.

Onorio Catenacci