# Partially Applied Functions

Think about functions and ask this question to yourself.

What is a function?

Whatever definition you accept, you can always break a function into two parts.

- A fixed part (function body)
- A variable part (function arguments)

We keep the fixed part into the body of a function and pull the variable parts outside the body as a parameter list. The purpose is to create a generalized solution. Let's look at a couple of simple examples.

` ````
def div(x:Double, y:Double):Double = x/y
def add(x:Double, y:Double):Double = x + y
```

Above functions are generic solutions for a pair of numbers. The first one is a
division and the second one is an addition.
These are small and simple functions, but they also have a fixed part (function
body)
and a variable part (argument list). Have you ever thought that fixing some of the
variable
parts (arguments) can give you an entirely different solution?

Let's see an examples.

` ````
def inv(y:Double):Double = 1.0/y
```

The above code is an inverse function. The division is a general solution, and the
inverse is a particular case of a division
operation. Isn't it? You fix the first variable to one, and the division becomes an
Inverse
operation. Similarly, you set the first variable to one, and the addition becomes
an
increment operation. Inverse and increment are entirely new solutions.

Let's say. You have a function to charge a customer for an online purchase. It
takes
two parameters. The payment method and the amount. You fix the payment method to
the
credit card, and it becomes a new function. PayByCreditCard. Similarly, you can
create
other specialized cases like PayByWallet. The idea is similar to the one shown in
below
figure.

Take a generic function, fix the value for some parameters and you get a brand new specialized function. We have a standard terminology for this whole idea. That is what we call the partially applied functions. The notion of partially applied function is powerful, and hence Scala offers a syntax to implement the partial application of parameters. The implementation is extremely simple.

### Partially Applied Function Syntax

Let me take the division function and use it to demonstrate the syntax.

` ````
def div(x:Double, y:Double):Double = x/y
//div: (x: Double, y: Double)Double
div(1, _:Double)
//res2: Double => Double = <function1>
val inverse = div(1, _:Int)
inverse(10)
//res3: Double = 0.1
```

The first line in the above code is my division function. I said, fix the first
parameter to 1, and you can create a brand
new function for the inverse. The second line does the same thing. We fixed the
first
parameter to one and gave a placeholder for the second parameter.

In fact, we applied the div function to its first argument and left the second
argument
as unapplied. That's why we call it a partially applied function.

We have a small limitation in this syntax. We must specify the data type for
the
unapplied parameters. The type inference doesn't work in this case.

If you look at the output of the partially applied function, Scala returned a
new
function. Strange. Isn't it. If I look at the implementation of my div function, It
doesn't
return a function. It simply returns a double. But in case of partially applied
functions,
the Scala compiler will do a couple of things internally, and instead of returning
a
double, it will return a new function that takes the remaining unapplied
parameters.

You can hold the returned function into a val. That's what we do in the next
line.

The inverse is now a new function that takes a single argument because we
didn't
apply one argument earlier. You can call inverse as shown at the last line.
Amazing.
Isn't it.

### Partial application in Higer Order functions

In functional programming languages, the notion of partially applied function is
much more powerful because we can have a
parameter that itself is a piece of code (a function literal). You can achieve much
more
by hooking up a new algorithm to a generalized Higher Order Function.

Let's see an example. I have got a requirement to calculate different types of
sums
for given bounds. Let's assume the lower bound is 1 and the upper bound is 5. And
the
requirement is to calculate three types of sums as listed below.

- A simple sum.

1 + 2 + 3 + 4 + 5 = 15 - A sum of squares.

1*1 + 2*2 + 3*3 + 4*4 + 5*5 = 55 - A sum of cubes.

1*1*1 + 2*2*2 + 3*3*3 + 4*4*4 + 5*5*5 = 255

Do you want to create three different functions for these three requirements? I don't want to do that because I am expecting to get some more similar requirements. So I decided to create a higher order function. The code is shown below.

` ````
def sumOfX(f: Int=> Int, a: Int, b: Int):Int =
if (a>b) 0 else f(a) + sumOfX(f, a+1, b)
```

The first parameter is the logic. The other two parameters are the lower and upper
bounds. I can fulfill all the three requirements
using the higher-order function *SumOfX*.
The code is shown below.

` ````
sumOfX(x=>x, 1,5)
sumOfX(x=>x*x, 1,5)
sumOfX(x=>x*x*x, 1,5)
```

To calculate a simple sum, I can use an identity function. To calculate a sum of
squares, I can use a squaring function.
Similarly, to calculate a sum of cubes, I can use a cube function. I can also
fulfill
some future requirements. For example, to calculate a sum of factorials, all I need
to
do is to pass a factorial function.

Great. However, the example shows a use of a Higher Order function. There is
nothing
to do here with partially applied functions. Now, you might be wondering, why do we
need
a partially applied function? I mean, it's a nice idea. Take a generic function,
fix
some of the parameters and create a brand new function. But why the hell I need to
do
that? If at all I need to calculate a sum of cubes, I will simply use the *SumOfX*
as shown above. Why do I take the pain to create a partially applied function and
then use it to calculate the sum of cubes?

There is a difference in the type. Let me explain. Let's create a partially
applied
function.

` ````
val sumOfCubes = sumOfX(x=>x*x*x, _:Int, _:Int)
```

Now the *sumOfCubes* is a function that takes two parameters. But *sumOfX*
was taking three parameters. When you have a downstream function that expects *sumOfCubes*,
you cannot use *sumOfX*. Let's take an example.

` ````
def applySums(f: (Int, Int) => Int) =
println("I am applying the sum of 1 to 5 and answer is = " + f(1,5))
```

The *applySums* takes a function of type *(Int, Int) => Int*. If you
try
passing *sumOfX*, you will get a type mismatch error. However, you can use a
partially
applied function to generate a function of type *(Int, Int) => Int*. Let's
try
it.

` ````
applySums(sumOfX(x=>x*x*x, _:Int,_:Int))
applySums(sumOfX(x=>x*x, _:Int,_:Int))
```

So, the partially applied function is a technique to generate a brand new function.
And the generated function comes with
a brand new type. You mostly need it to pass it to the downstream functions.

Continue reading for more on Scala functions.

#### 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:

Kafka Core Concepts

Learn Apache Kafka core concepts and build a solid foundation on Apache Kafka.

Scala Function Basics

Start learning Scala functions from the basics and become an expert.

Referential Transparency

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

Lazy Evaluations

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

Higher Order functions

Scala allows you to create Higher Order functions as first class citizens.