Once every other month a new F# link lands on top page and receives a few hundred of upvotes.
I think F# needs and deserves more publicity in order for it to win a larger audience. If only F# community would be half as vocal as Rust community.
Or: Is it more like the Swift / Objective C ecosystem where Swift, Objective C, and even straight C can co-exist in the same library?
In a mixed C# and F# codebase, generally when do you favor C# versus F#?
Coming from a C# background, what are the areas where F# is a better language?
Any success stories for F#, especially if it co-exists with C#? Any horror stories?
The biggest advantage of F# is its gradual typing and full type inference which allows to massively reduce the amount of text required to describe application or domain logic. It is also extremely composable and I find doing async in F# somewhat nicer than in C# too. F# also has better nullability (or, rather, lack of thereof) assurances and, in my opinion, better UX for records.
1: C# Library with interfaces and/or abstract base classes
2: F# library with implementations of those interfaces and base classes
3: C# program (console, web service, GUI, ect) that specifies the implementations in Dependency Injection
Or is there a simpler way for C# and F# to co-exist in the same project (dll or exe)?
For that matter, you don't even need the interfaces if you wouldn't have had them in a C#-only solution. Just define the class in F# and use it directly from C#.
You still need a separate assembly for F#, but that doesn't imply dependency injection - again, just reference it and use it.
The basic decision making logic needs to be very simple and easy to follow by scientists and people who aren't day-to-day software engineers: Basically, input some data, such as sensor readings, run it through an algorithm that makes decisions, and then output the decisions.
When mixing, you often write business logic as self-contained F# libraries with a C#-friendly API; and use C# to integrate them with whatever imperative, reflection-heavy and DI-heavy frameworks .NET is promoting the current year, since those are filled with interop edge cases for F# anyway.
You really want to avoid a language sandwich though (e.g. C#/F#/C#), because you'll keep wishing to remove the middle layer. Sadly, the addition of source generators make this mistake even more appealing.
It seemed that I had to learn C# in order to use F# properly and it seemed that porting it to C# was the saner option. I went with Rust after all and it seems to have been the right choice.
That was kind of my main problem with dotnet stack in general, although that was some years ago. I've tried sneaking F# into our project by building set of tests (the main codebase was in C#), but some of my teammates would have none of that.
My personal perception of the dotnet community was that developers either were too pigheaded about doing things "the Microsoft way", or hyped about "innovation" — "Oooh... check this out, Scott Hanselman made a whole new conference talk about it...", and then you'd look into this "innovation", and it often turns out to be some decades old, well-known thing, only "wrapped into MSFT packaging", which is not really bad by itself - it just seemed that people didn't actually use them in a practical way. I just never found that sweet-spot between pragmatism and excitement. You have to find a middle ground between: "This works! Sure, yeah, but isn't it darn ugly and probably not scalable?" and "This is so beautiful, and cool, but nobody besides Jeff really understands it." And my personal experience was that .net programmers would always want to be on one of those sides.
Speed of development is debatable. I think you can be pretty fast with both.
Easy to learn I concede but it gets easier with time, until it becomes very easy
* Network effect, or lack thereof. Very few people use it. * Its nature is contrary to the ecosystem. The CLR is fundamentally resistant to the paradigms that F# creates.
Wonderful little language - one of my favorites - and we owe a lot to it for the great features that C# has. But it just hasn't picked up the critical mass it needs.
IMO its generally more readable as well to non-dev than C# and to dev's outside the Java/C# ecosystem (e.g. Node, Go, etc). I've shown F# code back in the day to non-tech stakeholders and they typically understand it (e.g. data modelling).
Also, basic object initialization in C# has turned into a nightmare with recent versions. You need a flowchart to select among the 18 syntax options which suite your current needs.
With F# (and other newer languages), record fields are either `T` or `T option`. No need to worry about whether the value needs to be computed in a constructor and then remain immutable, whether it needs to be initialized by an object initializer and/or a constructor or not, whether it needs to remain interior-ly mutable throughout the life of the record, and so on. (Although as I recall you do still need to consider null values assigned to non-nullable references in your F# code that consumes C#.)
And while I agree that I don't love some of the object initialization patterns C# allows--I respect that other people might have different style than me and don't mind ignoring that those styles exist when writing my own stuff :)
My general rule goes something like:
1. Use record types for any simple data structure
2. Avoid using primary constructors (even on record types).
3. Use { get; init; } properties for everything unless there's a good reason not to.
4. For things that need to carry internal state, have different methods for mutations, emit events, etc., use a class with regular old constructors and either { get; } (for immutable) or { get; private set; } (mutable) properties as needed.
It's not always about the features such as keywords, built-in functionality and types. It's also how language features work together.
C# is more fit for an imperative or OOP style when F# is more fit for a functional style.
Trying to use a functional pipeline instead of DI.
I'm kinda wondering if anyone here with decent C#/.net experience can give their version of the answer?
---
The article really didn't answer its own question. It basically says "How" instead of "Why"...
...Which as someone who's spent over 20 years in C#, and tends to advocate for "functional" style, leaves me with more questions than answers!
F# is just a better language. Simpler, more concise, more readable with stronger type safety. I will never go back to writing C# as I'm finding it too frustrating at times and unproductive.
Pro tip: don't write F# like you would write C# - then you might as well write C#. Take the time to learn the functional primitives.
let bar =
if foo then
7
else
11
or let bar =
try
// code that might throw
7
with ex ->
11
and will ensure that both/all code branches return a compatible type for the `let` binding.Whereas in C# you have to do like
int bar;
if (foo) {
bar = 7;
} else {
bar = 11;
}
And C# will let you know if you omit the `else` on accident ...Except that most C# developers do
int bar = 0; // or some other default value`
to get the red squiggly to go away while they type the rest of the code, unknowingly subverting the compiler's safety check.This doesn't seem like a big deal given these examples. But it becomes a much bigger deal when the if/else grows super large, becomes nested, etc.
bar = foo switch
{
true => 7,
false => 11
}
1. It doesn’t support code blocks, so if you need multiple lines or statements you have to define a function elsewhere. 2. To get exhaustiveness checking on int-backed enums you have to fiddle with compiler preprocessor directives.
And for #2 any data associated with each enum variant is left implied by C# and has to be inferred from a reading of the surrounding imperative code, whereas in F# the union data structure makes the relationship explicit, and verifiable by the compiler.
I don't know if I would say 'well'. For simple GUIs it's OK but, for non-trivial GUIs I would use the approach to write the GUI frontend code in C# and have it call the F# 'backend'. If for no other reason than that the support and documentation for doing GUIs in C# is much better.
How about mobile?
Never tried, but I'm guessing more or less the same story as above. I would probably start by looking into .Net MAUI for that.
And how does it compare to e.g. Scala?
The biggest difference is that Scala is a much bigger and more of a multi-paradigm language. F# feels smaller and more focused and on its ML roots and functional programming. Not saying that Scala is less 'functional' than F#, but Scala supports you writing your code in a much more OOP way if you want. Yes you can (and sometimes have to) do OOP in F#, but it doesn't feel natural.
For mobile we have FuncUI (on top of Avalonia) and Fabulous (on top of Avalonia, Xamarin and Maui). Most of these frameworks use Elm architecture, but some do not. For example I use Oxpecker.Solid which has reactive architecture.
Can't help with Scala comparison, but at least DeepSeek V3 prefers F# for UI https://whatisbetter.ai/result/F%23-vs-Scala-9eaede00c7e4485...
I don't have much experience with Scala, but I think the two languages are pretty comparable in their respective ecosystems. The biggest difference I'm aware of is that Scala has typeclasses and F# does not.
ahhh, Its April Fools?
JK, I love F#. Please get over the hump and be a big language.
C# and F# both work fine with Rider or VS Code on Mac or Linux.
Even in a VM? Why not?