Scott Wlaschin writes tutorials on F# and functional programming, including railway-oriented programming and domain modeling with types.
Commenters recommend it as a great learning resource for functional programming ideas, even for people who never write F#.
While the libraries and techniques I mentioned above seem to be well-known, I couldn't find a good public sample project.
I can recommend https://fsharpforfunandprofit.com/ as a starting point.
If there's interest, I can split some of my code into stand-alone chunks and post my experience of what worked well and what didn't.
I wanted to share some thoughts on here on what brought me to F#. Maybe this can serve as a starting point for people who have similar preferences and don't know much about F# yet.
A big part that affects my choice of programming language is its type system and how error handling and optionality (nulls) are implemented.
That "if it compiles, it runs" feeling, IMO, isn't unique to Rust, but is a result of a strong type system and how you think about programming. I have a similar feeling with F# and, in general, I am more satisfied with my work when things are more reliable. Avoiding errors via compile-time checks is great, but I also appreciate being able to exclude certain areas when diagnosing some issue.
"Thinking about programming and not the experience" the author lamented in the blog post appears to be the added cost of fitting your thoughts and code into a more intricate formal system. Whether that extra effort is worth it depends on the situation. I'm not a game developer, but I can relate to the artist/sound engineer (concept/idea vs technical implementation) dichotomy. F#'s type system isn't as strict and there are many escape hatches.
F#…
Hello,
Apart from my family and some minor health issues, I currently am focused on 2 things: learning Luxembourgish/Luxembourgian and develop a deep understanding of functional programming.
About the former one: that should help me find a job in some Luxembourgish administration (I really wish I'll be able to find one soon).Luxembourg might be a small country, but I think it's managed well, CTIE (Luxembourgish administration that manages most of the IT infrastructure and software used by the state) has quite smart and competent people (also some dumb ones, but where's that not the case?), and I think I like the culture, which is almost my own, as I grew up close to Luxembourg and even went to a german-speaking school, while speaking family-native French (I'm as fluent speaking German as French, no accent).
Regarding the latter one, I started applying functional programming principles early this year, almost as obstinately as I can (and as much as possible using Java 8 then now 17) (I've got more than 16 years of professional experience using Java, both as a developer and software architect).
This was just the beginning of a more insightful journey into new coding practices, which result from one principle I discovered this year: source code should never lie.
This became an evidence once I implemented and started to use my self-made "Maybe" type (a better Optional - Optional is quite weak if you want to avoid procedural programming). While using Maybe, it struck me…
Yes, please do! Warning: F# will ruin other languages for you. I find it rather painful to work in basically anything else after using F#, with gradients of pain for different languages. Haha.
And that's a good question. I have basically every book written on F#, but I can't say I have ever used them for anything more than reference.
The official docs/guide/reference are actually really good, and I refer to them a lot when using some feature I'm not familiar with: https://docs.microsoft.com/en-us/dotnet/fsharp/what-is-fsharp
F# For Fun and Profit is well-known, but I can't say I use it a lot: https://fsharpforfunandprofit.com/
The same author's (Scott Wlaschin) book is very good: https://pragprog.com/titles/swdddf/domain-modeling-made-functional/
As for books, I have always liked:
* Functional Programming Using F# by Hansen and Rischel (might be too simple if you are already comfortable with functional programming and is out of date every now and then with changes to F# that's happened)
* Expert F# 4.0 by Don Syme and others (contains a lot of nice things by the designer of F#
One of the latest books is Stylish F# 6: Crafting Elegant Functional Code for .NET 6 by Kit Eason. I have the first edition but haven't read it.
My personal recommendation is to take the approach of type/domain driven design. That is, I start off every F# module the same:
1. Define my types with discriminated unions, records, type aliases (such as for tuples) or single case discriminated…
A bunch of ppl mentiond C#/F# so figured I'd just make a top-level response with some thoughts.
I wrote C# professionally for about five years (and actually just got a new job writing it again) and I spent about three writing production Go code. I love C# (it's my favorite overall language) and respect Go, though I personally don't enjoy the language.
There's definitely a concern about C# getting larger and larger, and while you can write in a functional/declarative style with things like LINQ (I'm mostly talking about the library, not the SQL'ish syntax), it's still very much OOP by default--at least in my experience, but you can write it in a very clean OOP way. That said, Go's philosophy about language size is almost the polar opposite of C#, and there's definitely a new-dev rampup that can come with it.
If you're looking for a type system with tagged unions/sum types then C#'s not going to do much for you there. That's actually the main thing I personally miss in it as well. There have been long-running design conversations about adding it, but hasn't happened (and I get why).
Here's a link to an interview with Mads Torgersen who runs the C# design stuff at MS where he talks about it, if you're interested (it's a super interesting conversation overall and I love listening to Mads talk about design):
https://youtu.be/Nuw3afaXLUc?t=3804
I can't really speak to the AOT compilation stuff since I've never had to do that with C#, but dang it's convenient with…
"FP works great for distributed systems, and most software written today is distributed."
According to Grokking Simplicity[1], good functional programming isn't about avoiding impure functions; instead extra care is given to them. These functions depend on the time they are called, so they are the most difficult to get right.
Compare to pure functions: given the same input, the results are always the same regardless of when the function was called. So they are easier to reason with.
There is actually a level that is even easier to reason about than pure functions: plain data.
So functional programmers prefer data over pure functions over impure functions.
The reason to avoid "leaks" is because impure functions cause everything that calls them to also become impure. However, it is OK to use local mutation contained to the function itself. Sometimes mutation is simpler and doesn't affect the purity of the function that contains it.
Another good book on practical functional programming is Domain Modeling Made Functional[2]. Actually all of Scott Wlaschin's material[3] is very good!
[1]: https://www.manning.com/books/grokking-simplicity
[2]: https://pragprog.com/titles/swdddf/domain-modeling-made-functional/
[3]: https://fsharpforfunandprofit.com/
I agree in the difficulty of finding abundant, good examples for F#. I'll throw out some plugs for ones that I liked.
* https://pragprog.com/titles/swdddf/domain-modeling-made-functional/ Uses F# as implementation language, though I cannot recommend this book enough for general type-safe design modeling regardless of the language.
* https://fsharpforfunandprofit.com/ Website of the author of the book mentioned above. He also has some good Youtube videos on the topic.
* https://www.demystifyfp.com/FsApplied/ A book that will walk you though developing a webserver, and also introduces you to Paket for dependency management.
I don't develop F# (or .NET) professionally, but I had fun when I played around with it. I found the interop with C# very seamless as well.