What I love about F# is<p>- no NULL- just use option types and pattern matching<p>- how powerful pattern matching is<p>- pipelining<p>- units of measurement- we all know the billion dollar disasters caused by distributed teams all thinking in their respective units- these should always be in the signature of a method<p>but when starting I can still remember how I struggled with the rather mathematical notation of int -> int -> int for signatures- I often failed to quickly spot the error in calling a function.<p>brace placement just felt wrong (when nesting function calls, which could be necessary despite pipelining)- I understand why, but for the most part it just felt wrong coming from Java/C#.<p>unfortunately it is a rather niche language- being a .net language does not help here as the main features such as algebraic datatypes are largely incompatible with C# syntax.<p>I am just glad that more and more features are adopted by C#- only downside is, that C# suffers of feature bloat :(
I personally found F# to be a decent alternative to Elm for small browser apps with Fable, Elmish/Feliz, Feliz.Plotly etc.
You can generate typed interfaces for any libs you're missing which have a typescript interface using ts2fable, that's the kind of pragmatic tooling you need if you're veering off the well-trodden path in commercial development. Ionide in VSCode is excellent (though not perfect) and the compilation times are decent.
In terms of community (which is not unimportant when it's that small) even the compiler gitter folks were super helpful when I had some reflection questions. Overall I'd use it again for small browser apps, for backend I guess it depends on your company and domain.
This lament reminds me of the cliché:<p>A good programmer can write FORTRAN code in any language.<p>Much as I loved LISP, back in the day, I hated working on other people's code. The author's prior (preferred) programming language was so obvious. And advocating consistent idiomatic LISPy house conventions never proved worthwhile.<p>Ditto pretty much every language since. So much so, I've come to reject metaprogramming and reflection for team projects. Any more, JavaScript (gods save us) is a language dialect construction kit, with every person and cohort creating their unicorn opinionated mutant variant. As much as C++ ever was.<p>In contrast: I do like like Lua. But I almost prefer using it. It's one virtue is simplicity. It has less potential for individual artistic expression. When maintaining someone else's Lua goo, I spent much less time bending my mind to the author's mental frame.<p>Perhaps we should revert to BASIC, Pascal, or Java 1.0.<p>Perhaps future parsers will permit subsetting grammars, to better define and enforce house rules.<p>Perhaps we'll all revert to just banging the rocks together. Ook, ook.
I've seen a lot of praise for F# but trying it out left me somewhat disapointed. Overall, it was nice to program in but there was a constant feeling of awkwardness which, it seems, was caused by F#'s ties to the rest of the .NET world. I don't remember the details too well but some of the examples are:<p>- NULL values still are a problem because they can be introduced any time you interact with the .NET framework. I got hit by this almost right at the beginning when first using the language – i defined some data type with non-optional fields and used it as an argument to an ASP.NET Core controller method only to realize that my non-optional fields don't enforce anything and ASP.NET will happily set them to NULL when data aren't present.<p>- There are multiple slightly different ways to define data types – classes, records, discriminated unions – and it's not immediately clear what are the consequences of using which. I remember having to switch some of my datatype definitions to classes because otherwise i couldn't make ASP.NET Core automatically deserialize them.<p>- You still have to learn in detail how all of the C# and .NET concepts map into F# to work with .NET and other libraries, e.g., there is a weird duplication of collection types, sometimes you have to do a weird casting dance with the :> and :?> operators when working with interfaces, dealing with out parameters also took me quite some time to figure out.<p>- Namespaces, classes and modules also seem to have some confusing redundancy.<p>I've tried out F# only once for a single project so a lot my complaints are probably due to my inexperience with the language, but all in all it seems that a lot of the suffering is inflicted by the association with .NET and the language could have been a lot nicer if it wasn't tied to it (I'm not dismissing the benefits of it, though).
The bad of F# is trying to find work in F#. I have the freedom to choose F# at work but it often seems like the wrong choice. If I want a web app I'm pulling in so many extra dependencies.
Many of the points here don't necessarily have to do with the language, well at least to me and could easily have occured in other languages such as coding style. Sure - the language uses some sensible defaults and is somewhat pragmatic when to be pure and when to not. But in the end programming can get complex. Even if the language steers you towards practices that lower complexity (a productivity win) you still need to understand what is going on and use the right tool when appropriate.<p>On a side note the performance thing seems to be a myth to me. There's no reason C# or F# should be faster or slower than one another with enough effort given the same underlying runtime. Many of the functional features are moving to be lower/zero cost in F# (inline lambdas, state machines, etc). They all compile down to IL in the end so as long as you can get the IL you want does it matter? Sure it may be easier to express more performant code in one or another depending on the domain. I could argue many cases where F# was easier to write performant code (numeric, generic algo's, explicit inline functions, inline vs ref, tail rec, compile time polymorphism, avoiding virtual dispatch preferring static functions, etc) and vice versa (native interop, until recently specialised async/await, etc).
Maybe this is a problem of our tooling or terminology not being good enough, but I don't agree with the idea that code that passes the available acceptance tests at a given point in time is "right". A codebase is a living thing that needs to be maintained, so it's not enough for the code to be "accidentally right"; it needs to do the right thing <i>for the right reasons</i> such that it will still do the right thing as it evolves.
I'm mostly a C# programmer by trade, and having tried F# multiple times (last time by doing half of the AoC in F#) , I haven't felt that I'd be ready to make the jump.
My main issues were:<p>- Much of the functional stuff like map/filter is available in C# as Linq, which granted, is not as nice, but the difference is not huge.<p>- Much of the new stuff in C# like ValueTuples does make it into F# but with a godawful syntax, I don't think this is the language's fault, but rather is the result of Microsoft's inattention<p>- I'm still not sold on the idea of functional languages - much of the stuff in them, like map/filter, option chaining, high quality type inference, pattern matching has shown up in procedural languages (they are all available in C# with the exception of option chaining), and the downsides, like immutability making some algorithms impossible to implement, is great. Imo, local mutation is not that bad, and functional languages actively prevent it, while global mutation is still a thing, which tends to be more problematic<p>- The generated .NET IL is not great. seq turns into an IEnumerable, list is some sort of linked list, I'm pretty sure you'd get pretty terrible performance if you did this.
> I like F# because it's the best programming training language I've found.... It still works great for making me think about and become a better programmer, no matter what language I use in everyday work.<p>I can understand how trying a range of language can make you a better programmer, by better appreciating the dimensions of language design and how it fits together, etc. but I have harder time accepting this stronger, more specific claim. There's not really any support for this claim in the article.
In the 2010s, there were a lot of posts about how C# could never even match F# even in 30 versions from that time.<p>But then C# started adding compiler flags that allow a redo of past suboptimal decisions (nullable reference types) without breaking existing code.<p>What is the current feeling on this? It seems kind of countered by the fact that the C# team is no longer bound by any past decisions.
The good, it is a ML language with the goodies from the .NET ecosystem.<p>One of the languages I enjoy coding every now and then.<p>The bad, it appears .NET team never really knows how to "sell" F#, and anything related to it comes as an afterthough if at all.<p>So on MS shops that actually make use of it, it gets relegated to writing libraries, or in a parallel universe with wrappers or competing stacks for anything .NET.
F# is practically dead. Worked with a lot of projects that jumped that hype wagon. Do not know of any company that use F# as of today. From a holistic viewpoint F# is complete garbage comparing to C#. Could we have a working pure attribute in C# though.