A function is a section of code that performs an action and may produce a result.

Creating a Function

The
fundamental formula used to create a function is:

letFunctionName = Function Body

You start with the let keyword, followed by a name for the
function. The name of the function binds it to the value it would produce. The name follows the rules we saw
for names in the F# language. Here is an example that starts a function:

let show . . .

Defining a Function

Defining or implementing a function consists of specifying its purpose, that is, what the
function is supposed to accomplish. The definition or implementation of a function is done in its body, which is
after the = sign. If the purpose of the function is short, the body can directly follow the
= sign. Here
is an example where the body of of the function simply uses printfn to display a sentence:

let show = printfn "Employee Record"

If the purpose of the function is long, it may need various lines of code. In this case, the
body must start on a line after the = sign. In this case also, the body of the function must be indented. The
indentation can be created by simply pressing the Space bar from the level of the let keyword used on the
function. To make your code better to read, indentation is typically applied by using 2 or 4 spaces (some of us
typically press the Tab key). The formula to create the function would be:

letFunctionName =
Function Body

Here is an example:

let show =
printfn "Employee Record"

Normally, you can do anything you want in the body of a function. For example, if necessary,
you can declare one or more variables and use them as you see fit. The variables declared in a function are
referred to as local variables. Here is an example of a local variable:

As an alternative, if you want to explicitly call a
function, when creating it, add some empty parentheses. Then, to call the function, type its name. Here is an example:

let show() = printfn "Employee Record"
show

This would produce:

Press any key to continue . . .

If the function was created with empty parentheses, then you must follow its name with
empty parantheses. Here is an example:

let show() = printfn "Employee Record"
show()

This would produce:

Employee Record
Press any key to continue . . .

Parameters and Arguments

Introduction

To perform its actions, a function may need external values. These are called
parameters and they must be supplied to the function. The formula to create such a function is:

letFunctionName Parameters = Function Body

In this case, after the name of the function, create a list of parameters
represented each by a name. If the function is using one parameter, simply type its name. Here is an
example of a function named calculate and that takes one parameter:

let calculate x . . .

If the function is taking more than one parameter, separate
them with spaces. Here is an example:

let calculate x y z . . .

The Data Type of a Parameter

You don't have to specify the data type of a parameter. If you don't, the
compiler will have to figure out what type to apply to the parameter. To start, the computer would
automatically infer that the parameter is an integer, of type int. In many cases,
you should (must) specify the data type of a parameter. For example, if the parameter uses a value other
than an integer, if a function is using more than parameter and at least one of them is not an integer
type, it is better to indicate the data type of the parameter.

To specify the data type of a parameter, include the parameter in parentheses, type :
followed by its data type. Here is an example:

let calculate (x:int) . . .

If the function takes more than one parameter and you want
to specify the data type of each, include the combination of the variable name
and its data type in parentheses. Here is an example:

let calculate (x:int) (y:int) (z:int) . . .

If the function is taking more than one parameter but one
of them is an integer type, you can specify the data types of the other
parameters and omit that of the integer type. Here is an example:

let showStudentInfo (name:string)age

As mentioned already, if you don't specify the data type of
a parameter, the compiler first infers that the parameter is an integer type. In
reality, when the function processes that parameter, the type of operation can
indicate the actual type of the parameter.

To define or implement the function, after the parameter or the list of
parameters and the assignment operator "=", in the body section, use the parameter(s)
as you see fit. Here is an example that indicates that a function named show
receives a string parameter and will display the value of that parameter using
the printfn function:

let show message = printfn "%s" message;

Once again, remember that if a function is short enough, you can define it on the same
line as the function name. If the function is long, start its body in the lines after = and indent the code.
Here is an example:

let show message =
printfn "%s" message;

Also remember that you can declare local variables in the function and use them as
necessary. Here is an example:

One of the characteristics of functional programming is
that a function can be created in the body of another function. Here is an
example of a function named show that is created inside a function named calculate:

To call a function that takes arguments, you can just type its name. If you don't
specify the value of the parameter, the call would produce an empty result. If you want to use the
parameter that the function has, you must supply a value for the parameter. This is referred to as
passing the argument to the function. To do this, after the name of the function, add a space and the
argument or the list of arguments. Here is an example:

let show message = printfn "%s" message;
show "Welcome to the wonderful world of functional programming!";

This would produce:

Welcome to the wonderful world of functional programming!
Press any key to continue . . .

If the function is taking more than one argument, when
calling it, type the name of the function followed by the value of each
parameter. The values are separated by spaces. In the same way, if the function has a local variable, it is
called the same way. Here is an example:

Once again, remember that you can pass a parameter to
a function without specifying the data type of that parameter, in which
case the compiler would consider that the parameter uses an integer value.
We also saw that the way a parameter is used, whether in the function's
body or when the function is called, can specify the actual value of the
parameter. This is also valid if the function takes more than one
parameter. This is referred to as automatic generalization.

Returning a Value From a Function

Introduction

When a function has performed its assignment, it may or may
not produce
a value. In some languages such as Visual Basic, Pascal, or Ada, a function that
doesn't produce a value is called a procedure.

If a function produces a value, that function is said to return a value.
In some languages such as Visual Basic or Pascal, a procedure that produces a value is called a function.

If you create a function and appropriately define it,
the compiler will try to find out the type of value the function must
return. Consider the following function:

let multiply(a) =
a * 2

Obviously this function should always return a number (an
integer). Now consider the following function:

getValue(value) = value

You can pass any type of value to this function and it would
react appropriately. For example, you can pass a number:

let getValue(value) = value
getValue(28)

Or you can pass a string:

let getValue(value) = value
getValue("James Thoedore Leasy")

Obviously this function can return any type of value. In
some cases, you may want to specify the type of value that a function must
return. To specify the return type, before the = sign, type a colon followed by
the desired data type. Here is an example:

let getValue() : int =
1450

Do the same even if the function takes more than one
parameter. Here is an example:

If you specify the data type(s) of the parameter(s) and you
want to indicate the return type of the function, specify it after the
parentheses of the (last) parameter. Here is an example:

let add (x:int) (y:int) (z:int) : int = x + y + y

If the function will not return a known value, set its
return type as unit. Here is an example:

let show() : unit =
printfn "This is the house of the scorpion"

Techniques of Returning a Value

Consider the
following function:

let calculate x y z = x + y + y;

If a function has only one statement in its body, that
statement produces the value that the function returns. In the above case, the
function returns the value that would be produced by the expression x + y + z.
As mentioned previously, the body of a function can start and/or end on a line
other than the one with the = sign. Here is an example:

let calculate x y z =
x + y + y;

Still, in this case, the return value is the one produced by
x + y + z.

In some cases, before giving its last expression, the body
of a function may contain multiple statements. Here is an example:

In this case also, the last expression constitutes the
return value of the function.

Remember that if you use only the name of the function
without passing some arguments, that is without specifying the values of the
arguments, the function would produce an empty value.

Using the Returned Value of a Function

When calling a function, you can get its return value and use it as you
see fit. For example you can display the value to the user. You can retrieve the value and
store it in a variable. To do this, you can assign the function to a declared variable. Here is an example:

By the way, because F# is an inferred language, you can create a function without specifying its
return value. If you want to indicate the return type of the function, just before
its assignment operator, type : followed by the data type. Here is an example:

Instead of first declaring a variable to hold the returning value of a function,
you can call the function directly where its value is needed. In the case of a placeholder of the
printf or the printfn function, you must include the whole call in parentheses.
Here is an example:

let multiply(a) = a * 2
printfn "Number: %i\n" (multiply(44));

This would produce:

Number: 88
Press any key to continue . . .

In a function that contains more than one expression, the
return value of the function is the last expression it performs.

As mentioned already, if you don't specify the data type of
a parameter, the compiler infers the type. Consider the following
example:

If you are using Microsoft Visual Studio and if you
position the mouse on a parameter, a tool tip would indicate the inferred data
type of a parameter:

We also metioned that
the way the parameter is used in the body of the function can suggest its type. In the
above cases, the compiler automatically infers that the
parameters use integral numbers. The calling of a function can also suggest the
type of a parameter. Consider the following example:

Although the definition of the function has not
changed, the compiler infers a float for it:

Partially Passing Arguments

When you call a function that takes argument(s), you are
supposed to pass the appropriate type(s) and the right number of arguments. F#
allows you to pass a fewer number of arguments but... Consider the following
example:

let add x y = x + y
let addition = add 36.94

Notice that, when it is defined, the add() function takes
two parameters but when it is called, it is passed only one argument, and its
call is assigned to a local variable named addition. If/when you do this, the
compiler considers that you have just created a new function named addition and
that takes one argument. When you call the function and pass a partial number of
argumnets, it is as if you are telling the compiler that you plan to call the
function but you don't yet have all the arguments; so you are temprarily first
passing this (these) argument(s) and the other argument(s) will be passed at a
later time. This means that, to get the actual value produced by
the original function (in this case, add), you must call the variable as
argument and pass the additional value(s) to it. Here is an example:

We saw how to call a function and get the value it
returns. Sometimes, when calling a function, you may not be interested in
the value it return, only in the object of calling that function. When
calling a function, to indicate that you are not interested in the value it
is returning, at the end of the function call, type |> ignore.
Here is an example:

All of the data types we have seen so far are used to
represent known values. Variables or values of those types can be combined
in/as expressions to produce new values. In the same way, a function can be
created to return a value of one of those types. In some cases, you may not
want a function to return a regular value, or a function may not return a
known value, or the return value of a function is not clearly known. Such as
function is said to return a void or a unit type. Actually, the void keyword
is mostly used in C-based languages to represent the same thing.

The unit type is represented as an empty placeholder,
represented as empty parentheses (). When you must use a unit type in a function,
such as if passing an argument of unknown type, pass the type as unit.
Here is an example:

let show(unit) = printfn "Employee Record"

In most cases, you can also pass the argument as an underscore.
On the other hand, to indicate that a function doesn't return a value, specify
its return type as unit. Here is an example:

let show() : unit = printfn "Employee Record"

The Signature of a Function

The signature of a function is a technique of indicating its arguments and its return type.
The basic formula of a function signature is:

function-name : parameter-type(s) -> return-type

The signature starts with the name of the function. This is followed by a colon.
If the function takes one argument, specify its type. This is followed by -> and the data type of the
value the function returns. Here is an example:

calculateSquareArea : float -> float

This means that we are using a function named calculateSquareArea. The function takes one
argument that is a decimal number. The function returns a decimal number.

Here is how to specify or read the signature of a function:

If the function doesn't take any argument, in which case it may have empty parentheses, specify
its parameter-type as unit. This would be done as follows:

presentGreetings : unit -> return-type

If the function doesn't return a value, specify its return-type as unit. This would be done as follows:

presentGreetings : parameter-type(s) -> unit

If the function takes more than one argument, in the parameter-type(s) placeholder, specify the data type
of each argument but separate them with ->. Here is one example:

calculateCylinderVolume : float -> float -> float

This indicates that we have a function named calculateCylinderVolume. The function takes two arguments of type float.
The function returns a floating-point number. Here another example:

showStudentRecord : string -> int -> unit

This indicates that we have a function named showStudentRecord. The function takes two arguments. The first argument is a
string. The second argument is a character. The function doesn't return a known value. Here another example:

This means that we have a function named createMemberSummary. The function takes three arguments. The first is a string. The
second argument is based on the Gender enumeration. The third argument is a floating-point number. The function returns a
string

The Entry Point of a Program

Many computer languages, especially compiled languages like C, C++, Visual Basic (the original BASIC
language doesn't apply here), Java, and C# have a special function named main (or Main) that controls where
a program starts executing. That function, or the section where it is defined, is called an entry point. Many other
languages, especially interpreted languages (like JavaScript, VBScript, etc) don't have that function.

The F# language doesn't directly support the entry point concept. In fact, F# proceeds from the
top of the document that contains the code (of a program) to the bottom section of the document. To specify an entry point for an F#
program, somewhere in the document that holds the code of the application, create a section that starts with an
attribute named EntryPoint. This would be done as follows:

[<EntryPoint>]
. . .

On the line(s) after the [<EntryPoint>] attribute, you can specify what to do. Here is
an example:

[<EntryPoint>]
printfn "The buck starts here!";

This program will not do anything significant. The reason you create an entry poing is if you
want to specify the starting point of execution of the program. To do this, you should a function named main and
that takes one argument (the argument will actually be treated as a group of values, called an array). In the body of
the function, do whatever you want. Before exiting the function, you should indicate a constant integer as its return
value. Normally, you can use any number. Here is an example:

By tradition, the return value of the entry point function is specified as 0.

Doing Something

The F# language provides the do keyword that can be used to
perform an action without creating a function. The formula to use the do keyword is:

[ attributes ]
doexpression

If you have some attribute(s) you want to use to control the execution of the section, start
with that (those) attribute(s). If the expression is short enough, you can write do and
the expression on the same line. Here is an example:

do printfn "Welcome to the wonderful world of F# programm!"

If the expression is long, type on its own line but indent
it. Here is an example:

do
printfn "Welcome to the wonderful world of F# programm!"

Asserting an Expression

Consider the following program that provides a radius of a
circle and calculates the diameter:

When the assert() function is called, if it returns
false, the compiler displays an error dialog box and stops. The above program
would produce:

Of course, if the function returns true, the program
proceeds normally.

Conditional Return

A function is meant to return a value, but that value may depend
on some condition. For example, imagine you have a function that takes a value, must
evaluate it, and returns either a simple value or an expression. In this case, you can
create a conditional statement and return a value. Here is an example:

When you create a function that conditionally returns
a value, make sure that function returns a value before its end. Otherwise
you would receive an error (in reality, the error is more likely to occur
in other languages like C/C++/C#, Java, or Visual Basic because those
languages explicitily use a keyword to indicate the return value while in
F#, any last expression in a function is considered as the return value).

Applying a Value to a Function

To apply a value to a function, use the <| operator. The
formula to use is:

Function <| Value

The function appears on the left of the operator while the
value is on the right. Here is an example:

An alternative is to use the |> operator. In this case, the
value must be written to the left of the operator and the function to the right.

Inline Functions

If you create function that uses a long body, which means its
implementation spans various lines, and if you call that function many times,
everytime the function is called, the compiler must "travel" from the section
where the function is called to where it is defined. This travel can be done too
many times, putting a big burden on the compiler. On the other hand, if the
function is short, to cut this travel, you can ask the compiler to bring the
definition of the function to where it is called. To do this, when defining the
function, precede it with the inline keyboard. Here is an
example:

let inline show message = printfn "%s" message;
show "Welcome to the wonderful world of functional programming!";

or:

let inline show (message:string) = printfn "%s" message;
show "Welcome to the wonderful world of functional programming!";

A Function as Parameter

By definition, a function is a value by itself. This means
that one function can be directly defined in the body of another function. Such
a function is passed as a parameter and it is called a function value.

To pass a function as parameter, after the name of the
function that takes it as argument but before its own argument(s), open some
parentheses. In the parentheses, enter a name for the function passed argument,
followed by a column, the data type of its argument, followed by ->, and the
data type(s) of its argument(s). Here is an example:

let display (show : string -> unit) message = show message;

This means that you are creating a function named display,
that takes two parameters. One (the first) parameter is a function named show.
This function takes an argument of type string and returns a unit (unknown) type. The
second argument of the main function is named message. As done for every
function, type = followed by the body of the function.

Before calling the main function, you must define the
function, or you must define a function that performs the task of the function
value. Here is an example:

let present msg = printfn "Welcome to the wonderful world of functional programming!";

When calling the main function, pass the necessary
arguments. Here is an example:

In the section about lambda expresion, we used only one parameter. In
reality, you can pass as many arguments as you want. Imagine you want to
create a function that solves the equation ax + b = c. Such a function would
take three arguments (a, b, and c), solve the equation, and return a new
value. Here is an example:

let solve a b c = (c - b) / a;

You can then pass such a function as argument to another
function. Here is an example:

In solving x-4=10, we get x = 14
In solving 2x-4=10, we get x = 7
In solving x+5=12, we get x = 7
In solving x-3=5, we get x = 8
In solving 7x=21, we get x = 3
In solving 8x-2=14, we get x = 2
Press any key to continue . . .

Lambda Expressions

Imagine you have a relatively small function such as one
that calculates the square of a number. Here is such a function:

let squareIt a = a * a

An anonymous function, also called a function expression, is a
function that doesn't have a name. In reality, a lambda expression is a type
of function that is passed to another function as argument, as we saw about
function values. This time, to create the function you are passing as argument,
that is, to create the lambda expression, use the
following formula:

fun parameter(s) -> expression

This time, the expression starts with the fun keyword.
This time also, the function is not named. Instead, the fun keyword is followed
by the name(s) of the parameter(s) of the function/expression. After the name(s) of the
parameter(s), type the -> operator and the purpose
or definition of the function. Here is an example:

fun x -> x * x

You pass this whole definition to the function that receives
it. Here is an example:

calculate (fun e -> e * e) 12

You must (have) define(d) a function that specifies what the
parent function does. In that parent function, the lambda expression is
represented by a name. That name is usually set as pred, which stands for predicate. Here is an example where a
function takes one function as argument and another value as another argument.
The parent function doubles the value of the parameter and passes the value to
the lambda expression:

In solving x+50=120, we get x = 70
In solving x-5=7, we get x = 12
In solving 4x=8, we get x = 2
In solving x-4=2, we get x = 6
In solving x+8=72, we get x = 64
In solving 5x=10, we get x = 2
Press any key to continue . . .

As mentioned earlier, the main idea to use a lambda
expression is to let it handle a small assignment. The implementation of such a
function can simply be assigned to a variable. Here is an example:

let multiply = fun a b -> a * b

In this case, notice that the variable is just that: it
doesn't take any argument because it is not a function. On the other hand, you
can use that variable where the function would have been called but pass the
appropriate arguments. Here are two examples:

Electric companies charge their
customers on the amount of kilowatts they consume each month. In the
following example, an electric company charges a base price of $8.50. Then,
for the first 700 kWh, the company charges $0.0650/kWh, and $0.0500/kWh.

A recursive function is a function that calls itself.
Usually, the function performs an operation first, then calls itself to perform
the operation again. Because this can be done over and over again, the function
must define when and how to stop.

To create a recursive function, you use one of
the following formulas:

Imagine you have two or more functions in a program: the functions take the same number
and type(s) of argument(s); the assignment(s) performed by one (or more) of function(s) can be used by another
function. for example, consider the area of a circle. It is calculated as Radius2 * PI (which is
approximately 3.14156...). The area of a sphere is gotten by simply multiplying the area of a circle by 4
(4 * Radius2 * PI). If you already have a function that calculates the area of a circle, you can
simply "add" is to another simpler function to get the area of a sphere.

The F# language allows you to "add" one function to another. This is referred to
as composing the functions. First, you must define the functions.
Here are examples:

To compose two functions, you use the >> or the << operator. As mentioned in the
begining, composed functions use the same number and type(s) of argument(s). To get the result of composing the
functions, you must provide the argument(s) to the composition. You have various options. If you want to
immediately use the result of the composition, you can include the operation in parentheses followed by the argument(s).
Here is an example:

In the previous examples, we first defined the function to compose. As an alternative, you can create the function
directly in the placeholder. This is done by creating a lambda expression. Here are examples:

Another way to chain functions is referred to as pipelining. It uses slightly different rules compared
to composition. First, Instead of << or >>, pipelining uses the <| or the |> operator. Second, when
performing the operation, pass the argument to the first function that will execute. As mentioned for pipelining:

If you use the |> operator, the function on the left side will execute first, and that's the function to which
you must pass the argument(s). Here is an example:

As mentioned for the composition, if the pipelining involves many functions and makes the line of code too long, to
make it easy to read, you can write each function and its operator on its own line. Here is an example:

Instead of first creating the functions, you can define them directly where needed. In this case, you should create
them as lambda expressions (we will see an example in the next section).

Chaining an Argument to Functions

On of the most valuable features of pipelining (and composing) is that you can pass (an) argument(s) once to a series
of functions that can perform operations in chain, one after another. In this case, each function uses the return value of the previous
function and applies that value to its own assignment. To do this, write the argument followed by a call to each function that is
preceded by the necessary pipelining operator (<| or |>).

This makes it easy to know what function is called and in what order. Instead of first defining the functions,
you can create each directly in its pipelining placeholder. Each function can be defined as a lambda expression. Here are examples:

To convert a value to an integer, use a function named
int. Here is an example:

let result = int 628.305;
printfn "The decimal 628.305 converted to an integer is %d" result;

This would produce:

The decimal 628.305 converted to an integer is 628
Press any key to continue . . .

An alternative it to call a function named int32. To
convert a number to an unsigned integer, call the uint32()
function.

To convert a value to a short integer, call the int16() function.
To convert a value to an unsigned short integer, call the unt16()
function.

If you want to convert a number to a long integer, use the int64() function.
To convert a number to an unsigned long integer, call the uint64()
function.

To convert a value to native integer, call the nativeint()
function. To convert the number an unsigned native integer, call the
unativeint() function.

To convert a number to decimal, call the decimal() function.
Here is an example:

let result = decimal 513;
printfn "The number 513 converted to decimal is %.3f" result;

This would produce:

The number 513 converted to decimal is 513.000
Press any key to continue . . .

To convert a value to a 32-bit decimal number, call the
float32() function. To convert a value to a 64-bit decimal
number, call the float() function.

Algebraic Functions

The F# language provides a series of functions you can
use in your programs.

The numbers in your program can be
positive or negative. A negative number is preceded by a - sign. To find the
cign of a number, call a function named sign. This function takes one
argument and works as follows:

If the value of the argument is positive, the function returns 1. Here is an example: