Functional languages are very different from standard imperative languages, and can be quite tricky to get the hang of initially. This page offers some tips on how to learn F# effectively.
If you have experience in languages such as C# and Java, you have probably found that you can get a pretty good understanding of source code written in other similar languages, even if you aren’t familiar with the keywords or the libraries. This is because all imperative languages use the same way of thinking, and experience in one language can be easily transferred to another.
If you are like many people, your standard approach to learning a new programming language is to find out how to implement concepts you are already familiar with. You might ask “how do I assign a variable?” or “how do I do a loop?”, and with these answers be able to do some basic programming quite quickly.
When learning F#, you should not try to bring your old imperative concepts with you. In a pure functional language there are no variables, there are no loops, and there are no objects!
Yes, F# is a hybrid language and does support these concepts. But you will learn much faster if you start with a beginners mind.
It is important to understand that functional programming is not just a stylistic difference; it is a completely different way of thinking about programming, in the way that truly object-oriented programming (in Smalltalk say) is also a different way of thinking from a traditional imperative language such as C.
F# does allow non-functional styles, and it is tempting to retain the habits you already are familiar with. You could just use F# in a non-functional way without really changing your mindset, and not realize what you are missing. To get the most out of F#, and to be fluent and comfortable with functional programming in general, it is critical that you think functionally, not imperatively.
By far the most important thing you can do is to take the time and effort to understand exactly how F# works, especially the core concepts involving functions and the type system. So please read and reread the series “thinking functionally” and “understanding F# types”, play with the examples, and get comfortable with the ideas before you try to start doing serious coding. If you don’t understand how functions and types work, then you will have a hard time being productive.
Here is a list of dos and don’ts that will encourage you to think functionally. These will be hard at first, but just like learning a foreign language, you have to dive in and force yourself to speak like the locals.
mutablekeyword at all as a beginner. Coding complex functions without the crutch of mutable state will really force you to understand the functional paradigm.
if-then-else. Use pattern matching for testing booleans and recursing through lists.
String.length "hello"rather than
"hello".Length. It might seem like extra work, but this way of working is essential when using pipes and higher order functions like
List.map. And don’t write your own methods either! See this post for details.
On the other hand:
seqtypes and their associated library modules. Functions like
List.mapare very powerful. Once you understand how to use them, you will be well on your way to understanding higher order functions in general.
List.fold, you can never have that problem.
|>) and composition (
>>) as much as you can. This style is much more idiomatic than nested function calls like
There are a number of extremely common errors that beginners make, and if you are frustrated about getting your code to compile, please read the “troubleshooting F#” page.