liveBook · Manning

Function

As explained in F# in Action: A Revised Edition of Get Programming with F#

A function is a named or anonymous program construct that maps input values to a result and can encapsulate computation.

A function transforms input data into an output value. In F#, functions are the main unit of behavior: model application state as data, then build functions that validate, transform, and eventually emit results such as JSON, files, or messages. A purchase flow, for example, can validate a request, turn it into an invoice, and email that invoice as separate steps. section 1.5.5

Define functions with let. The same declaration pattern also binds ordinary values, because functions are values too: they can be named, passed as arguments, and assembled with other functions. Indentation defines the function body, while type inference usually determines argument and result types without annotations. section 3.1.1 section 3.1.2

Define and call a function

let greetPerson name age = $"Hello, {name}. You are {age} years old" greetPerson "Fred" 21 Defining the function loads it into F# Interactive; calling it supplies values and produces the greeting. Change the arguments and run it again to experiment with the result. section 2.5.5

Prefer small functions that do one job, then compose them into larger behavior. This keeps calculation separate from output: a function can calculate an age description, while another prints it. The calculation can then be reused for console output, files, or tests without bringing printing along with it. section 2.1.2 section 4.1.5

IEnumerable<int> SquareNumbers(IEnumerable<int> numbers) {
    // implementation of square elided...
}
 
IEnumerable<int> GetEvenNumbersThenSquare(IEnumerable<int> numbers) {
    return SquareNumbers(GetEvenNumbers(numbers))                     #1
}
 
let squareNumbers = Seq.map (fun x -> x * x)
let getEvenNumbersThenSquare = getEvenNumbers >> squareNumbers        #2

Compare nested method calls with composition: getEvenNumbers feeds directly into squareNumbers, making the reusable transformation sequence explicit. section 2.1.2

F# functions always have one input and one output. A function with no meaningful input or output uses unit (). Apparent multi-argument functions are curried: supplying the first argument returns a function waiting for the next. This supports partial application, such as fixing an initial value before supplying the rest later. section 6.1.1 section 6.4

Listing 6.2 Calling an F# function
let add (firstNumber:int) (secondNumber:int) =   #1
    firstNumber + secondNumber 
let addFive = add 5                              #2
let fifteen = addFive 10                         #3

Calling add with 5 creates addFive, a new function that accepts the remaining number; calling it with 10 yields 15. section 6.1.1

Organize behavior in modules that operate on records, tuples, and unions instead of fusing mutable state and methods into classes. A basket, for instance, can be immutable data with AddItem, Clear, and Checkout functions that return an updated basket. This separation makes behavior easier to create, test, maintain, and change independently of the data shape. section 2.1.3 section 10.1.2

For testable code, favor functions that take all required data as arguments and return results rather than changing hidden state. Tests can then arrange input, call the function, and assert the output. Test small, lower-level functions or groups first when possible, since they usually isolate more of the algorithmic logic. section 14.3.1 section 14.3.3

Functions work alongside the .NET ecosystem. F# can call C# classes and methods when needed, while F# functions in modules appear as methods to C# callers; partially applied functions are exposed with normal C# method arguments. section 11.1.1 section 11.2.1

How F# in Action: A Revised Edition of Get Programming with F# covers it

How deep it goes
Explains declaration, inference, composition, currying, partial application, organization, and testing, while deferring generic types for later detail.
Examples
Uses greetings, even-number squaring, age descriptions, shopping baskets, ATM balances, and Arrange-Act-Assert tests.
What it assumes
Teaches function creation from zero while easing transitions from Java, JavaScript, C#, and object-oriented designs.
What you can do after
Build it from scratch by defining small F# functions, composing them, partially applying inputs, and extracting testable calculations from output code.
How it connects
Connects functions with type inference, pipelines, currying, partial application, modules, immutability, unit testing, and C# interop.

Also explained in

Compare how 20 books explain function →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of F# in Action: A Revised Edition of Get Programming with F#. The section links point to the parts of the book it draws on.