Moving from C# to F# is much less politically difficult than moving to Haskell. For a start the framework they're on is the same, and actually, you can write object oriented F# that looks almost the same as C# (not that I would advise that, I prefer to use the OO side of F# as a last resort).
I'm the CTO at my place of work, and our primary app is C#. I wanted to tame some of the excesses of the language, and started looking at Haskell - I knocked up a few small projects with it; got it talking to the C# app through RabbitMQ, all happy days. But a few months later I came back to the projects to find they had rotted because of cabal. Some projects I found it next to impossible to recover. That left a pretty sour taste, which was gutting because I loved the language.
Then I took a look at F#. It's not as impressive as Haskell as a language, but it really does sit in that sweet spot for 'fitting in' to a big project environment. I've found that creating satellite projects to our core app in F# has been the perfect way to go. It's moved the team into that mindset slowly without having to force the issue.
> I've found that creating satellite projects to our core app in F# has been the perfect way to go
Can you elaborate on how that is laid out? I've identified some existing C# code in various of our current projects that could benefit from conversion to F#, but I'm not sure how the resulting projects should be structured.
Some things are just projects in the main VS solution. So for example I wanted to create a document search system. So I created an F# project in the main solution, brought in Lucene.NET from nuget. Half an hour later, done. You can call the functions in F# directly from C#. There are sometimes some type interop issues to deal with, but mostly it's painless.
Other projects are separate microservices that talk to our main app through my messaging framework [1]. It's an actor-model that I built a C# and F# API for, and they communicate via Redis. But tbh you can use anything you like: make it RESTful, use WebServices, RabbitMQ, etc. The great thing is you have access to the same libraries on both languages.
If you're thinking of refactoring existing projects then you could go the mechanical route of just converting classes like-for-like. But you miss out on some of the amazing type system benefits of F# if you do that.
What I tend to do is design all of the types first, as records or discriminated unions. A bit like if you were doing a DB related project you might spend some time designing the schema first, thinking about how the data should be laid out. With ADTs you can design the states of your application, whatever it is, and then you write the functions that transform those states in a referentially transparent way.
Then you book-end your lovely functional code with the IO.
This whole process is much simpler when you start with smaller services; so if you've found sections of your existing app that you want to break out, then that's perfect.
By the way, if you want some of the functional niceness in C# too, then check my library below. It was built with your situation in mind (because it's mine too). It also has some utility functions for F#/C# interop.
Thank you, that is a very nice summary of the design process. I'll be keeping it in mind as I think about my Skype for Business Online UCWA wrapper later this week..,
To have the equivalent outside the .net world, there could be a Ocaml for JVM, that would allow to fall back to a ecosystem of libraries and toolchains. I think there have been some experiments to do that, but not a finished one to my knowledge.
I think Scala is the main functional offering for JVM, no?
Although with C#'s the direction of travel (bringing in pattern matching, record types, etc.) I reckon C# and F# will end up more like Scala and OCaml, rather than Java and OCaml.
I'm the CTO at my place of work, and our primary app is C#. I wanted to tame some of the excesses of the language, and started looking at Haskell - I knocked up a few small projects with it; got it talking to the C# app through RabbitMQ, all happy days. But a few months later I came back to the projects to find they had rotted because of cabal. Some projects I found it next to impossible to recover. That left a pretty sour taste, which was gutting because I loved the language.
Then I took a look at F#. It's not as impressive as Haskell as a language, but it really does sit in that sweet spot for 'fitting in' to a big project environment. I've found that creating satellite projects to our core app in F# has been the perfect way to go. It's moved the team into that mindset slowly without having to force the issue.