# Functions

## Basics of functions

Most functions in F# are created with the `let` syntax:

``````let timesTwo x = x * 2
``````

This defines a function named `timesTwo` that takes a single parameter `x`. If you run an interactive F# session (`fsharpi` on OS X and Linux, `fsi.exe` on Windows) and paste that function in (and add the `;;` that tells `fsharpi` to evaluate the code you just typed), you'll see that it replies with:

``````val timesTwo : x:int -> int
``````

This means that `timesTwo` is a function that takes a single parameter `x` of type `int`, and returns an `int`. Function signatures are often written without the parameter names, so you'll often see this function type written as `int -> int`.

But wait! How did F# know that `x` was an integer parameter, since you never specified its type? That's due to type inference. Because in the function body, you multiplied `x` by `2`, the types of `x` and `2` must be the same. (As a general rule, F# will not implicitly cast values to different types; you must explicitly specify any typecasts you want).

If you want to create a function that doesn't take any parameters, this is the wrong way to do it:

``````let hello =  // This is a value, not a function
printfn "Hello world"
``````

The right way to do it is:

``````let hello () =
printfn "Hello world"
``````

This `hello` function has the type `unit -> unit`, which is explained in The "unit" type.

## Curried vs Tupled Functions

There are two ways to define functions with multiple parameters in F#, Curried functions and Tupled functions.

``````let curriedAdd x y = x + y // Signature: x:int -> y:int -> int
let tupledAdd (x, y) = x + y // Signature:  x:int * y:int -> int
``````

All functions defined from outside F# (such as the .NET framework) are used in F# with the Tupled form. Most functions in F# core modules are used with Curried form.

The Curried form is considered idiomatic F#, because it allows for partial application. Neither of the following two examples are possible with the Tupled form.

``````let addTen = curriedAdd 10 // Signature: int -> int

// Or with the Piping operator
3 |> curriedAdd 7 // Evaluates to 10
``````

The reason behind that is that the Curried function, when called with one parameter, returns a function. Welcome to functional programming !!

``````let explicitCurriedAdd x = (fun y -> x + y) // Signature: x:int -> y:int -> int
let veryExplicitCurriedAdd = (fun x -> (fun y -> x + y)) // Same signature
``````

You can see it is exactly the same signature.

However, when interfacing with other .NET code, as in when writing libraries, it is important to define functions using the Tupled form.

## Functions of more than one parameter

In F#, all functions take exactly one parameter. This seems an odd statement, since it's trivially easy to declare more than one parameter in a function declaration:

``````let add x y = x + y
``````

But if you type that function declaration into the F# interactive interpreter, you'll see that its type signature is:

``````val add : x:int -> y:int -> int
``````

Without the parameter names, that signature is `int -> int -> int`. The `->` operator is right-associative, which means that this signature is equivalent to `int -> (int -> int)`. In other words, `add` is a function that takes one `int` parameter, and returns a function that takes one `int` and returns `int`. Try it:

``````let addTwo = add 2
// val addTwo : (int -> int)
// val five : int = 5
``````

However, you can also call a function like `add` in a more "conventional" manner, directly passing it two parameters, and it will work like you'd expect:

``````let three = add 1 2
// val three : int = 3
``````

This applies to functions with as many parameters as you want:

``````let addFiveNumbers a b c d e = a + b + c + d + e
// val addFiveNumbers : a:int -> b:int -> c:int -> d:int -> e:int -> int
// val addFourNumbers : (int -> int -> int -> int -> int)
// val addThreeNumbers : (int -> int -> int -> int)
// val addTwoNumbers : (int -> int -> int)
let six = addThreeNumbers 1 2 3  // This will calculate 0 + 0 + 1 + 2 + 3
// val six : int = 6
``````

This method of thinking about multi-parameter functions as being functions that take one parameter and return new functions (which may in turn take one parameter and return new functions, until you reach the final function that takes the final parameter and finally returns a result) is called currying, in honor of mathematician Haskell Curry, who is famous for developing the concept. (It was invented by someone else, but Curry deservedly gets most of the credit for it.)

This concept is used throughout F#, and you'll want to be familiar with it.

## Inlining

Inlining allows you to replace a call to a function with the body of the function.

This is sometimes useful for performance reason on critical part of the code. But the counterpart is that your assembly will takes much space since the body of the function is duplicated everywhere a call occurred. You have to be careful when deciding whether to inline a function or not.

A function can be inlined with the `inline` keyword:

``````// inline indicate that we want to replace each call to sayHello with the body
// of the function
let inline sayHello s1 =
sprintf "Hello %s" s1

// Call to sayHello will be replaced with the body of the function
let s = sayHello "Foo"
// After inlining ->
// let s = sprintf "Hello %s" "Foo"

printfn "%s" s
// Output
// "Hello Foo"
``````

Another example with local value:

``````let inline addAndMulti num1 num2 =
let add = num1 + num2

let i = addAndMulti 2 2
// After inlining ->
// let add = 2 + 2
// let i = add * 2

printfn "%i" i
// Output
// 8
``````

## Pipe Forward and Backward

Pipe operators are used to pass parameters to a function in a simple and elegant way. It allows to eliminate intermediate values and make function calls easier to read.

In F#, there are two pipe operators:

• Forward (`|>`): Passing parameters from left to right

`````` let print message =
printf "%s" message

// "Hello World" will be passed as a parameter to the print function
"Hello World" |> print
``````
• Backward (`<|`): Passing parameters from right to left

`````` let print message =
printf "%s" message

// "Hello World" will be passed as a parameter to the print function
print <| "Hello World"
``````

Here is an example without pipe operators:

``````// We want to create a sequence from 0 to 10 then:
// 1 Keep only even numbers
// 2 Multiply them by 2
// 3 Print the number

let mySeq = seq { 0..10 }
let filteredSeq = Seq.filter (fun c -> (c % 2) = 0) mySeq
let mappedSeq = Seq.map ((*) 2) filteredSeq
let finalSeq = Seq.map (sprintf "The value is %i.") mappedSeq

printfn "%A" finalSeq
``````

We can shorten the previous example and make it cleaner with the forward pipe operator:

``````// Using forward pipe, we can eliminate intermediate let binding
let finalSeq =
seq { 0..10 }
|> Seq.filter (fun c -> (c % 2) = 0)
|> Seq.map ((*) 2)
|> Seq.map (sprintf "The value is %i.")

printfn "%A" finalSeq
``````

Each function result is passed as a parameter to the next function.

If you want to pass multiple parameters to the pipe operator, you have to add a `|` for each additional parameter and create a Tuple with the parameters. Native F# pipe operator supports up to three parameters (|||> or <|||).

``````let printPerson name age =
printf "My name is %s, I'm %i years old" name age

("Foo", 20) ||> printPerson
``````

2016-07-22
2017-05-29
F# Pedia
Icon