# Higher Order functions

Scala allows you to create Higher Order functions. These are the functions that can do at least one of following things.

- It can take a function as an argument
- It can return a function

In this article, we will try to understand the syntactical side of the following things.

- How to create a function that takes another function as an argument
- How to create a function that returns another function

## How to create a function that takes another function as an argument?

Let's try to understand it with the help of a simple example.

We want to create an integer decorator function. It should take two arguments.
The
first argument should be an integer and the second argument should be the logic to
decorate
the given integer.

The following example shows some usages and the result.

` ````
intDecorator(5, (y:Int) => "[" + y + "]" )
//res3: String = [5]
intDecorator(5, (y:Int) => "-" + y + "-" )
//res4: String = -5-
intDecorator(5, (y:Int) => "Page " + y + "-" )
//res5: String = Page 5-
```

The first example takes five and returns the same in a bracket. The second example
takes five and decorates it with a hyphen.
The third example also does a similar thing. Can you define intDecorator?

Let's take another requirement. Create a function *sumOfX*. It takes
three
inputs. The first two parameters are integers. The last parameter is the logic to
create
the sum. The following example shows some usages and the result.

` ````
sumOfX(3,5, (x,y)=> x+y)
//res7: Int = 8
sumOfX(3,5, (x,y)=> x*x +y*y)
//res8: Int = 34
sumOfX(3,5, (x,y)=> x*x*x +y*y*y)
//res9: Int = 152
```

The first example takes *3* and *5* as first two inputs and returns a
simple
sum. The second example takes *3* and *5* as first two inputs and
returns
the sum of squares. Similarly, the last example returns a sum of cubes. The code
below
shows the definition of *sumOfX* as well as the *intDecorator*.

` ````
def sumOfX(x:Int, y:Int, f:(Int,Int) => Int) = f(x,y)
def intDecorator(x:Int, f: Int=>String) = f(x)
```

The functions shown in the above example takes a function value as an input argument. There is no complexity in the syntax as long as you pass simple parameters. Every parameter has three parts.

- Parameter name
*(for example x)* - A Colon
*( : )* - Value type
*(for example Int)*

The function parameter syntax is also same.

- Parameter name
*(for example f )* - A Colon
*( : )* - Function value type for example
*(Int, Int) => Int*

Defining a function value type is all about knowing the input type and output type
of the target function. So we define the
type of the function value *f* as below.

- A right arrow in the middle
- Input type on the left
- Output type on the right

It simply tells that the function *f* takes two Integers and gives a single
Integer.
Defining a Higher Order function that takes another function is as simple as shown
in
the above examples.

## How to create a function that returns another function?

We created a *sumOfX* function earlier. The earlier version of the *sumOfX*
takes three arguments. The first two arguments were integers, and the final
argument was the logic to calculate the sum.
Let's create another version of the same.

` ````
def sumOfX(f:(Int,Int)=>Int) = {
def myLocalFunc(x:Int, y:Int) = f(x,y)
println("I am returning a function")
myLocalFunc _
}
//sumOfX: (f: (Int, Int) => Int)(Int, Int) => Int
```

This new version takes a single argument. It takes only the logic to calculate the
sum.

In the function body, We create a local function as *myLocalFunc*, and
then
we return it as the last expression of the *sumOfX* function. As a result,
the
*sumOfX* is now a Higher Order function. The returned function takes two
integers
and calculates the sum based on the logic provided to the *sumOfX*.
Primarily,
I tried to break it into a two-step process. Now you can use it as shown below.

` ````
//Step 1 - Provide the logic
val simpleSum = sumOfX((x,y)=> x+y)
/* Output: -
I am returning a function
simpleSum: (Int, Int) => Int = <function2>
*/
//Step 2 - Canculate simple sums
simpleSum(3, 5)
//res10: Int = 8
-----------------------------
//Step 1 - Provide the logic
val sumOfSquare = sumOfX((x,y)=> x*x+y*y)
/* Output: -
I am returning a function
sumOfSquare: (Int, Int) => Int = <function2>
*/
//Step 2 - Canculate sum of squares
sumOfSquare(3, 5)
//res11: Int = 34
```

The examples shown above is the primary method to create a Higher Order function
that returns another function. However,
we can apply some shortcuts to squeeze the code.

Instead of declaring a local function and then returning in the end, we can
directly
use an inline function literal at the end. The example below shows that change.

` ````
def sumOfX(f:(Int,Int)=>Int) = {
println("I am returning a function")
(x:Int, y:Int) => f(x,y)
}
```

The last line of the *sumOfX* is a function literal. As we already learned
in
the function literals, it contains two parts saperated by an *=>* symbol. A
list
of parameters comes before the *=>* symbol and the function body after the
*=>*
symbol.

You will often see another syntactic sugar. You can shift the list of
parameters
to the beginning, right after the *=* symbol of the parent function. Here is
the
code.

` ````
def sumOfX(f:(Int,Int)=>Int) = (x:Int, y:Int) => {
println("I am returning a function")
f(x,y)
}
```

The syntax shown in the above example is more common and popular. However, it is just a syntactic sugar of returning a local function from a Higher Order function. I hope this helps you to grab the syntax for creating Higher Order functions in Scala.

#### Read More

Basics of Scala functions | Function Literals in Scala | Function values | Local Functions | Variable length argument | Default values and named arguments | Scala Placeholder syntax | Higher Order functions | Partially applied functions | Function currying

## You will also like:

Pattern Matching

Scala takes the credit to bring pattern matching to the center.

Anonymous Functions

Learn Scala Anonymous Functions with suitable examples.

Referential Transparency

Referential Transparency is an easy method to verify the purity of a function.

Statements and Expressions

Statements and Expressions in Scala. How are they different?

Lazy Evaluations

Evaluate the expression now vs evaluate it for the first use. Strict vs Lazy?