Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
Mastering F#

You're reading from   Mastering F# A comprehensive and in-depth guide to writing functional programs using F#

Arrow left icon
Product type Paperback
Published in Nov 2016
Publisher
ISBN-13 9781784393434
Length 264 pages
Edition 1st Edition
Languages
Arrow right icon
Authors (2):
Arrow left icon
Suhaib Fahad Suhaib Fahad
Author Profile Icon Suhaib Fahad
Suhaib Fahad
Alfonso García-Caro Núñez Alfonso García-Caro Núñez
Author Profile Icon Alfonso García-Caro Núñez
Alfonso García-Caro Núñez
Arrow right icon
View More author details
Toc

Key features of F#

The following are some points that Distinguish the F# language from other .NET languages:

  • F# is a functional first language, which means that functions are treated as first-class citizens, but it also provides ways to work with other paradigms, such as object-oriented programming (OOP) (as in C#).
  • Unlike other languages, such as C#, which mixes expressions (language constructs returning a value) and statements (constructs that don't return a value), F# is an expression-based language. You can think of every syntax construct in F# as a small function.
  • F# is a strongly-typed language, meaning that the type of every expression in the program is determined at compile time. This allows the compiler to make verifications in our code and enables great tooling support, such as autocompletion, refactoring, and so on.
  • Additionally, F# has a very strong type inference mechanism to infer types for the expressions in a program. This removes much of the verbosity usually associated with strongly-typed languages.
  • The .NET generics' type system is baked into the core of F#. For example, the programmer doesn't have to specify the functions to be generic; if the F# type system infers the variables can be generic (provided it is implemented that way), the function becomes generic. This makes it easier to write polymorphic code, that is, functions that can be reused with different types.
  • F# has a module system that allows data structures to be specified and defined abstractly. Unlike C# namespaces, F# modules can contain functions that help you separate data (types) from logic (functions in modules).
  • F# implements a pattern matching mechanism, which allows controlling conditions based upon structural similarities; whereas, other languages only allow value matching as in IF...ELSE statements in C#.

Functional and imperative languages

Imperative languages usually modify the state of a variable for most operations. This makes it more difficult to reason about our program, particularly when different parts of our code change values that are globally accessible. When a piece of code modifies a value outside its scope, we talk about side-effects (this may also include other state modifications, such as file or console operations). OOP tries to tame side-effects by encapsulating state. However, this is not always a complete solution, as objects often develop tight and complex dependencies with each other that are still difficult to reason with.

Functional languages solve this problem using pure functions. Pure functions are closer to the mathematical ideal of functions, in the sense that they don't have side-effects (don't change state outside their scope) and always produce the same output given the same input. Pure functions are easier to refactor and reason with because their output is predictable, and can be used as building blocks to write large programs with different techniques of function composition.

F#, as described, is a functional-first language, but the language can also deal with unavoidable side-effects such as file or logging operations.

To compare F# with a more imperative language, we can take the example of a Fibonacci sequence generator, as follows:

public static int Fibonacci(int n)
{
    int a = 0;
    int b = 1;
    // In N steps compute Fibonacci sequence  iteratively.
    for (int i = 0; i < n; i++)
        {
            int temp = a;
            a = b;
            b = temp + b;
        }
            return a;
}

let rec fib n =
if n < 2
then 1
else fib (n - 2) + fib (n - 1)

Note

For illustration purposes, C# in procedural style is used. It is also capable of more functional implementations, such as Language Integrated Query (LINQ). Also, performance is not taken into consideration.

In an imperative language, the algorithm is normally implemented as a loop, and progress is made by modifying the state of the variables used in the loop.

In F#, the Fibonacci sequence is implemented using recursion. The let keyword, which defines the function, and the rec keyword, which specifies the function, can be called recursively. Using recursion, we are parameterizing the state (we will pass the updated values as parameters to the next call) so we do not need to use mutable variables.

However, please note that programs exclusively using a functional style can have performance problems. In this book, we will take an intermediate approach of using imperative code when necessary.

lock icon The rest of the chapter is locked
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $19.99/month. Cancel anytime
Banner background image