top | item 18706245

Why you should learn F#

272 points| aloisdg | 7 years ago |dusted.codes | reply

174 comments

order
[+] algorithmsRcool|7 years ago|reply
F# is 3 big things to me:

Safer threading with immutability

Safer programming with null-safety

Safer logic with precise domain modeling

The precise domain modeling is the real paradigm shift.

The whole point of static typing is to inform the compiler about your intent so that it can provide guarantees about correctness. F# makes it easy to define lots of small types that precisely model state so that you can give more responsibility to the compiler to verify your program.

I cannot overstate how important this is to maintaining correct software overtime. If you guard your touches with non F# code, you need far fewer unit tests and probably even less runtime checks because you already know if the types are right, so is the logic. And when you need to write unit tests, the functional style makes your tests very easy to write.

I have personally struggled with domain complexity in C# that i was able to model precisely in F# and have it work perfectly on the first try.

[+] pimeys|7 years ago|reply
I would say it's the same with Rust and Haskell. And I agree, the superior type system of these languages is really a game changer for me and it's very hard to go back to languages missing these features.
[+] sparkie|7 years ago|reply
One of the features that makes F# great for organization is the sequential ordering of compilation units which makes it easier to understand code dependencies, and makes it awkward to create mutually recursive types (requiring them to be in the same code file separated by `and`, or defined in signature files in advanced).

This might sound like an unwanted restriction, but 9 times out of 10, having mutually recursive types is signs of a code smell. You can almost always model your problem better with a slight indirection through an interface or function, it helps avoid the need for mutation, and makes testing simpler.

[+] contravariant|7 years ago|reply
>I have personally struggled with domain complexity in C# that i was able to model precisely in F# and have it work perfectly on the first try.

If you're willing to provide a (simplified) example I would be very interested.

[+] tatoalo|7 years ago|reply
I’ve also really liked FsCheck, if well configured of course.

Just a shame that the university exam I took this summer was to implement binary trees and a parser...

[+] phillipcarter|7 years ago|reply
Hey folks,

Glad to see Dustin's good post get some visibility here :)

If anyone is interested in learning F#, there are some resources available:

F# docs index (has multiple guides for specific editors and a comprehensive overview of the language): https://docs.microsoft.com/dotnet/fsharp/

F# on JavaScript with Fable: https://fable.io/docs/

More F# in the browser with WebSharper: https://try.websharper.com/

F# on Azure Notebooks (a hosted Jupyter notebook service that's free): https://notebooks.azure.com/Microsoft/projects/2018-Intro-FS...

And of course, the now legendary (at least among the F# community), F# for Fun and Profit: https://fsharpforfunandprofit.com/

[+] daxfohl|7 years ago|reply
The only thing I don't like is the DI story presented here and many other F# guides. Having gone down that rabbit hole and using F# in production for 5 years now, I have gone back to classes and interfaces in almost all cases.

Functions as DI mechanism suffers from a few things. First, it's hard to search for implementations. They could be defined anywhere. With interfaces, the implementations are a hot key away. Second, functions only replace single-function interfaces. Even with a purist view of ISP, there are still plenty of occasions where a service would expect to call multiple functions on a contained service. Passing all those in as multiple parameters gets unwieldy in real world scenarios. Third, F# has no way to inject a dependency into a whole module, so you have to go function by function. Injection into classes is much easier to manage this way. Finally since none of the services or interfaces are named, they don't work with IoC containers.

The good side is that there is nothing in F# preventing you from using classes and interfaces in your design. Unsurprisingly this is my preferred way to go about it.

I kinda wish the function based DI wasn't brought up so much and so early. It's a big mental leap that I think turns off some people coming from other languages. And for limited benefit. Or negative benefit in plenty of cases.

[+] sevensor|7 years ago|reply
I have a seasonal project that spins up around this time every year. Last year, I chose F# for a (relatively small) component of the project and I was not disappointed. I don't have access to the customer's systems, and usually with Python there's a bit of back and forth where I have to fix bugs that only customer is able to trigger. My F# program worked flawlessly the first time and has caused no complaints. I'm excited about writing more F# this year.
[+] jweir|7 years ago|reply
A gripe about F# on MacOs - how to install it, count the ways - 6.

https://fsharp.org/use/mac/

Don't I need Mono, wait, shouldn't I be using .NET? Oh I will probably install it one way, only to discover I should have installed it another.

I find the .NET and Mono differences confusing.

So this is a barrier to entry to consider.

That said, this free book is kind of nice introduction:

https://www.oreilly.com/programming/free/analyzing-visualizi...

[+] knocte|7 years ago|reply
Yeah, the fact that Mono is inheriting all BCL code from .NETCore nowadays, but is still not .NETCore (because it has its own runtime) is a bit confusing.

That being said, the best/easiest way to use .NET in the Mac is just install "Visual Studio for Mac" (the Community edition is completely free), which will under the hood install all you need (Mono, .NET Core, etc).

[+] jjtheblunt|7 years ago|reply
brew install fsharp or similar worked fine for me.
[+] thedirt0115|7 years ago|reply
I don't know F#, but I do know C#, and it feels like the author is trying to make C# look more difficult/verbose than it needs to be to make F# look better. Here is an alternative version of the "Everything is a function" section's IPasswordPolicy thing: https://ideone.com/3Savt9 I even went a little overboard with the function that takes a list of functions and returns a single composed function -- I could've also written a one-off that uses "&&" like the F# version: bool isValidCustom(pw) { return f1(pw) && f2(pw) && ...; } Am I missing something? Why did the author make the C# version so complex??
[+] winkelwagen|7 years ago|reply
I've been diving into f# in 2018. I came from c# world, and it really made me a better developer. Really recommend the language. Think it has a great balance between functional programming and OO if it is really needed. I really do think it's easier to write better .net programs with f# then c#. Think this article point out some great stuff.

That said, it's quite hard to actually get to use it in production at the places I've worked. My college's are scared of it (that is pretty reasonable, considering c# is a good stable language and my team is confident that what we develop will make the customers happy).

One thing that makes me hesitant to really try to get this adopted in my company is the tooling. My experience hasn't been great. It works, but it has been pretty unreliable. Some documentation was more focused on the "pre dotnet core" era of f#. I know i've been spoiled, but stuff like debugging, tooling and refactor tools can't touch Visual Studio.

There are some decent options, Jetbrains Rider and VS Code are a couple of them.

Small things, like creating a record type while typing is inconvenient.

type Customer = { Id: int; Name: string; Age : int; }

While typing an instance of the record

let c1 : Customer = {Id = 1;

gives you a bunch of compiler warnings, I know I'm not done, Compiler knows there are more properties. But without looking at the record type it's hard to see what order things are.

I'm not sure if this is just OCaml thing, but C kind of languages are better at predicting what you want to create. It's weird that with the very predictable Hindley–Milner type system it can't provide the developer with good information.

I know it's a small thing, but when working with large projects, I don't want to look everything up, I have the compiler have my back.

I'll really think Microsoft should help the Fsharp Foundation more, seeing what an amazing language f# is. But it really could use some more love from MS. Perhaps they should help the community be more confident that they can solve the business problems they run into. I hope Microsoft would say: "Hey this is how you create The Boring Line Of Business App, with all the bells and whistles you normally need". From how to deal with Dependencies in large projects (No, a couple of (amazing) conference video's of Mark Seemann do not give me enough confident that after 6 months of development it still is manageable)

Until the Tooling is done, I just keep enjoying the language and learn how to become a better developer with it.

[+] mcintyre1994|7 years ago|reply
I've previously used Ocaml at my last job and use Scala at my current one, it's interesting that F# (just judging from this blog post) looks more similar to Ocaml than to Scala - like they've more aggressively pulled out syntax and embraced partial application etc.

I'd always assumed F# was to C# what Scala is to Java - and I think that probably does represent their design goals, so I wonder what the different considerations were that led to them being relatively quite far apart.

[+] ken|7 years ago|reply
"No matter if you are already a functional developer from a different community (Haskell, Clojure, Scala, etc.) or you are a complete newbie to functional programming (like I was 3 years ago) I think F# can equally impress you" -> "For this task and for the rest of this blog post I'll be comparing F# with C# in order to show some of the benefits."

F# is neat, and I see why it's useful if you have a big .NET program already, but for anyone else I don't see why I'd pick it over a more mature (and less Microsoft-centric) functional language like OCaml, SML, or Erlang.

Does F# have any unique features that other functional languages lack, or is .NET integration its killer feature?

[+] phillipcarter|7 years ago|reply
.NET integration is probably the biggest killer feature, because that unlocks official support for most important platforms that you'll need to use. Using AWS or Azure or GCP because your business is moving stuff to a butt provider? You have access to fully-supported SDKs maintained by teams who do that stuff for a living. And so on. .NET also has a spectacular standard library, and with .NET Core, runs _very_ well in any environemnt.

But from a language standpoint, here are three unique features

* Type Providers, which let you generate types based on a data source, and tie compilation to the use of that data being correct

* Active Patterns, which are similar to Haskell's View Patterns, and let you tie some arbitrary functionality that ultimately returns an Option into a pattern for neat pattern matching

* Computation Expressions, which let you express, compose, sequence, etc. monadic and monoidal computations in a convenient syntax that's super easy for newcomers to grok. There is also an RFC and WIP implementation that expands these to support applicative constructs

There's more (Units of Measure, universal quantification via Interfaces, etc.) but these three tend to be something people like a lot.

[+] Dn_Ab|7 years ago|reply
As others have said, F# interesting language features are computation expressions, active patterns, units and type-providers. The library, platforms and ecosystem benefits are gravy. Though subjective, the syntax is clean too, being somewhere between an ML and Python.

Something that no one has mentioned yet is that F# is now among the fastest functional first programming languages. At least according to (take with a grain of salt) benchmarks like [1] and https://www.techempower.com/benchmarks/

[1] https://benchmarksgame-team.pages.debian.net/benchmarksgame/...

[+] BeetleB|7 years ago|reply
As someone said on HN a while ago: F# works better on Linux than OCaml does on Windows. I recently was trying to decide which new language to learn, and reduced the choices to F# and OCaml. The catch? I need something that works on both Windows and Linux. I first attempted OCaml, and gave up soon after starting. I could tell that fighting Windows would be a constant battle. So I went with F#.

And then of course, parallel computation is an issue with OCaml.

SML: Kind of lacks libraries. I did learn some SML in the past and loved it, but I want a language that will let me be about as productive as Python is. SML lacks a strong ecosystem.

[+] gameswithgo|7 years ago|reply
F# features that are unique or not present in all other functional langs:

* multi-threading (vs Ocaml) * type providers (perhaps totally unique) * units of measure * active patterns * computation expressions

[+] hacker_9|7 years ago|reply
The .Net ecosystem is definitely a killer feature. Everything you want, and it 'just works', as well as everything being seamlessly integrated with each other. This is only possible with the backing of a huge amount of funding, and there are probably millions of man hours spent on it at this point.
[+] mmirate|7 years ago|reply
Why is the .NET integration a feature rather than an antifeature? Don't null and subclassing tend to poke holes in F#'s type system's ability to detect mistakes? And would it not be better to compile to native code than to require the Mono VM or whatnot?
[+] PsylentKnight|7 years ago|reply
Regarding F#'s real world usage, today I came across an end-to-end F# stack, SAFE stack.[0] It looks very intriguing and I would be interested to know if anyone here has experience with it and has thoughts on it.

[0]https://safe-stack.github.io/docs/intro/

[+] chusk3|7 years ago|reply
Yep, almost all of my side stuff and an ever-increasing proportion of my work stuff is in SAFE. It's actually built on Dustin's Giraffe library, which itself is built on top of Asp.Net Core. Cross platform, great ergonomics due to Giraffe, and I get to share client side/server side domain models, validations, etc due to the shared F# heritage.
[+] Nelkins|7 years ago|reply
That "famous slide" really rings true for me. F# allowed me to forget (or at least not worry about) a TON of OO design patterns. Data goes in, transformation happens, data comes out.

I do like that F# is very practical about OO though.[0] I feel that the language often strikes a balance of programming paradigms that enables me to be very productive.

[0] https://eiriktsarpalis.wordpress.com/2017/03/20/why-oo-matte...

[+] moron4hire|7 years ago|reply
I really wish Unity3D would relinquish control of my Visual Studio Solution files and have a much nicer path to including its libraries as a dependency manually so I could start using some of the other languages in the CLR ecosystem.

I've managed to get it to work before by very carefully searching for the DLLs in the Unity install directory and compiling my own DLLs into a Plugins folder in my Unity project, but it's very brittle. It's not obvious which set of DLLs to import (there are lots of different versions of each, for various rhyme platforms), and I upgrade new Unity versions frequently, so the location is a moving target. And Heaven help you if you want to depend on something that is only released as a script bundle in a Unity Package (like every VR SDK out there right now). And given how Unity's braindead YAML metafile system works, you're pretty sure to break your component references in your scenes and prefabs with even the most minor of rearchitecturings.

Unity having its own build pipeline is a huge impediment. It all but forces you to write custom scripts that do some of the most basic things, as if we live in the Node hellscape of Gulp/Grunt/Webpack. And none of it is documented well enough to get it right without hours of ping-pong with test runs.

[+] dzonga|7 years ago|reply
Like I mentioned in another thread > Been learning F# the last two months. Wanted to learn Ocaml first. But F# is the sweet spot, beautiful functional syntax . Can leverage the now open .Net Ecosystem + pretty fast for doing financial stuff that I wanna do.
[+] bnt|7 years ago|reply
Honest question: As someone who does web development and is looking to learn a new programming language in 2018, would you recommend F# over Elixir (and why)?
[+] smush|7 years ago|reply
This has been previously mentioned but F# gets all of the goodies that come with being a .NET language. Elixir comes from Ruby land and thus has a framework called Phoenix(?) which also has its fans.

The big difference is that F# is a statically typed functional language, while Elixir is a dynamically typed functional language. Comparison of static vs dynamic types -> https://hackernoon.com/statically-typed-vs-dynamically-typed...

I personally opted for F# because of the domain modelling tools and the offloading of various caveats and edge cases onto the compiler's stack rather than the meatspace stack, but Elixir has many fans for a good reason no doubt, but I'll defer to someone with more experience working with it to weigh in.

[+] keithnz|7 years ago|reply
I'd suggest try both.

The Elixir web world gets a lot more love than the F# one. F# always touts the advantage of living in the .NET world, but it means most things are built with C# in mind, not F#. There are F# frameworks, and they are nice, but the community is quite small. But the advantage is the .NET world has a vast amount of libraries for doing most things.

OTP and Elixir is a better story than F# equivalents. There are no lightweight isolated processes in .NET

Elixir also has macros ( a very sharp double edged sword ) which can make frameworks nice to use.

F# is stronger typing which is nice and often has the trait if it compiles, it works. Though the normal downsides of dynamic typing in Elixir are not so bad.

But the best thing is to try both and make up your own mind

[+] GordonS|7 years ago|reply
I'm a C# and Typescript guy, and recently spent a day with each of Elixir and F#.

I loved them both!

Elixir has a great 'getting started' site, which was really well put together, and similarly the 'F# for Fun and Profit' site was great too, so I feel like I had equally good resources to introduce me to them both.

I'd love to spend more time with both of them, but in general I'm more comfortable with static typing, so if I progress further with either, it'll be F#.

I only wish that Microsoft would start treating F# as a first-class citizen alongside C# :/

[+] garfieldnate|7 years ago|reply
Honestly I was super psyched to get into F# after finishing Dan Grossman's programming languages class, but I abandoned it pretty quickly because setup was so difficult on my Mac.

1) Multiple versions of .Net available (.Net Core, Mono...) and different tutorials and documentation would apply only to one or the other. 2) I went with .Net Core because the community seemed to have decided on that, but there is no easy way to do a cross-platform GUI in F# using .Net Core. 3) I just couldn't find find a simple tutorial taking me from beginner to intermediate using a cross-platform toolchain and development environment. I stumbled around with Visual Studio Code for a while, ran into some compatibility issues with hundreds of lines of errors messages...

I'm sure it would have been fantastic if I had had an F# person help me get set up and started, but the setup curve was too steep to be enjoyable (actually, setting up is never enjoyable. I just want to get to the good part of coding stuff!).

[+] atombender|7 years ago|reply
F# seems like such an amazing language every time I look at it — a modern version of OCaml, with a clean syntax, some novel ideas, and fewer legacy warts.

However, I wish that it had, like OCaml, a native AOT compiler that didn't come with the baggage of the .NET runtime. Some people might consider this a benefit, not baggage, of course. But it's the same reason I'm put off by Scala.

From what I understand, to even run a compiled F# program you have to have Mono installed? It does look like you can get AOT compilation with Mono [1], but the limitations (e.g. no generics, apparently) seem too onerous.

[1] https://www.mono-project.com/docs/advanced/aot/

[+] javcasas|7 years ago|reply
After being deeply burned by the .NET framework, I consider OCaml significantly superior to F# just because it doesn't depend on .NET or Microsoft.

And yes, somehow the OCaml guys have managed to implement generics and AOT compilation to optimized machine code long before the .NET framework existed, but now this is something "truly hard" on .NET.

[+] AdeptusAquinas|7 years ago|reply
Its part of dotnet core, so you don't need Mono installed. And you can build a self-contained dotnet core application so you don't need core installed to run it.

AOT is possible via something like CoreRT, but its still a bit beta and not straightforward. From my experience the only limitation with CoreRT and F# is certain reflection heavy functionality. No problem with generics.

[+] knocte|7 years ago|reply
AOT not supporting generics? that's a pretty bad reading/summary of the webpage you link to (not to mention, that page may be a bit outdates, and more cases are supported by AOT now; take in account this is the mode that iOS apps developed with Xamarin need to use).
[+] vumgl|7 years ago|reply
(no/less functional) C --> Java --> C# --> Scala --> F# ---> Haskell (more/all functional) - form a talk by Martin Odersky
[+] Timothycquinn|7 years ago|reply
Do you know which talk this is discussed? I'm interested in watch his stuff.
[+] urda|7 years ago|reply
Do HN users have any F# references, books, or guides they recommend? I've always been intrigued by F# but haven't found a good project / use case for it, but I suspect that's because I need to know more about it first.
[+] winkelwagen|7 years ago|reply
I've really enjoyed

https://www.manning.com/books/get-programming-with-f-sharp

Think it gives a good overview of the language and it's easy to read. Considering that after a day of working I'm not that sharp anymore it was a good read for me.

Also mentioned in the article, but Scott Wlaschin book really show the strengths of the language. Most of his stuff is great actually, but his website (FSharp for fun and profit) is not the most coherent read, I love using it as reference. I also recommend his conference talks, it has quite a bit wide range of topics.

https://pragprog.com/book/swdddf/domain-modeling-made-functi...

There are also few courses on pluralsight, but cannot remember which ones I really enjoyed.

[+] dgudkov|7 years ago|reply
>I've always been intrigued by F# but haven't found a good project / use case for it

I would highly recommend trying F# on a project with complex data processing.

[+] sparkie|7 years ago|reply
I used Expert F# (2.0) when learning some years ago. A bit dated now, but I believe that it has had a more recent revision.

It is co-authored by the language creator, Don Syme.

[+] cflyingdutchman|7 years ago|reply
If you want to get paid to learn F#, my team is hiring at Jet/WalmartLabs. If you want to learn more, email me at [email protected].
[+] AchieveLife|7 years ago|reply
Has the culture improved since the acquisition? Last time I interviewed there I was treated like dirt.