As new to functional programming and Scala, I found it challenging to understand what Partially Applied Functions are. I decided to take it slow and let the concept sink in before I make any progress since they are some of the building blocks for writing better, cleaner functional code. And since they are used everywhere in Scala, learning them would give a better velocity when writing code.

As a new comer, I try to concentrate on following things (for any concept)

1. What does this concept mean?

2. What benefits does it provides? or when to use them?

#### What does the it mean?

When we invoke/call any function, it means that we “apply” function to the arguments (used often in mathematics). In programming world it simply means calling a function with arguments. Read this stackoverflow answer for explanation.

Taking the same definition forward, "partially applied functions” means functions where some of the argument are applied. For example

``````scala> def sum(a:Int, b:Int, c:Int) = a + b + c
sum: (a: Int, b: Int, c: Int)Int``````

Invoking or calling or applying arguments to this function means

``````scala> sum(1,2,3)
res0: Int = 6``````

So how partially applied functions would look like?

``````scala> val partialSum2ArgumentsProvided = sum(1, 2, _:Int)
partialSum2ArgumentsProvided: Int => Int = <function1>``````

There are two important things to observe here

1. The way we did not provide the third argument value. The syntax `_:Int` means I am not providing the third value which is of type `Int`

2. The function `partialSum2ArgumentsProvided` did not return any value but a function

Here `partialSum2ArgumentsProvided` is a partially applied function since we did not provide all the values required by `sum`

There are other uses of `_` just in case you are curious but for the purposes of this example, all it means that I do not provide the value when I apply function.

`<function1>` represents a Scala trait which basically means "a function of 1 parameter."

With this in mind, let’s recap.

`partialSum2ArgumentsProvided` is a partially applied function because we did not provide third parameter value.

So how do I get the value out of that function?

``````scala> partialSum2ArgumentsProvided(3)
res1: Int = 6``````

Aha!, so when we called/applied `3` to our partially applied function and we got our result `6` back. But how come it knows about `1` and `2`?

Remember when we created `partialSum2ArgumentsProvided` we applied arguments `1` and `2`?

It may be confusing, but try some other examples so that you can understand it.

Taking this concept even further, you may want to ignore some or all of the arguments. Lets see how

``````scala> val partialSum1ArgumentsProvided = sum(1, _:Int, _:Int)
partialSum1ArgumentsProvided: (Int, Int) => Int = <function2>

scala> partialSum1ArgumentsProvided(2,3)
res2: Int = 6``````

`<function2>` means "function with 2 parameters"

and

``````scala> val partialSumNoArgumentsProvided = sum(_:Int, _:Int, _:Int)
partialSumNoArgumentsProvided: (Int, Int, Int) => Int = <function3>

scala> partialSumNoArgumentsProvided(1,2,3)
res3: Int = 6``````

`<function3>` means "function with 3 parameters"

#### When to use them?

While reading over from many places following list was common

##### Creating a function which is pre-loaded with some values

For example, consider multiply function which looks like

``````scala> def multiply(a:Int, b:Int) = a * b
multiply: (a: Int, b: Int)Int``````

Some partially applied functions that we could make are

``````scala> def multiplyBy2 = multiply(_:Int, 2)
multiplyBy2: Int => Int

scala> multiplyBy2(2)
res4: Int = 4

scala> multiplyBy2(10)
res5: Int = 20

scala> def multiplyBy3 = multiply(_:Int, 3)
multiplyBy3: Int => Int

scala> multiplyBy3(10)
res6: Int = 30

scala> multiplyBy3(30)
res7: Int = 90``````
##### Providing only unique variables to a function

Consider an application that send email to customer support `customersupport@enterprise.com`. We may have a function that looks like

``````scala> def email(to:String, from:String) = ()
email: (to: String, from: String)Unit``````

We have not implemented how this would be done since this is just an example.

So instead of customer knowing the email for customer support or enterting it (assuming the email for support would not change), we can have a partially applied function that looks like

``````scala> def emailCustomerSupport = email("customersupport@enterprise.com", _:String)
emailCustomerSupport: String => Unit