Scala Tutorial - Learn How To Create Nested Function
Overview
In this tutorial, we will learn how to create Nested Functions which as the name implies are functions that are defined inside other functions.
In Functional Programming, you should try to break your logic into other smaller functions. But sometimes you have logic that is tightly coupled with a particular function and Scala provides you with the ability to nest functions so that you can still benefit from functional style of coding.
Steps
1. How to define a function
If you have followed the tutorials from this Chapter On Functions, you should by now be familiar with defining a function.
So let's go ahead and write a function named checkDonutAvailability() which will check if a donut is available from your inventory.
But, this function will also perform some validation on the input parameter donutName.
println("Step 1: How to define a function")
def checkDonutAvailability(donutName: String): Boolean = {
// retrieve donut list that is currently in stock
val listDonutsFromStock: List[String] = List("Vanilla Donut", "Strawberry Donut", "Plain Donut", "Glazed Donut")
val iDonutInStock = (donutName.nonEmpty && donutName.length > 0) && (listDonutsFromStock contains donutName)
iDonutInStock
}
NOTE:
- Sure we could have inlined the body of this function but we are showing each individual step so you can easily compare with the nested function equivalent later on.
2. How to call a function
Once again, calling a function which has an input parameter should be straight-forward as shown below.
println("\nStep 2: How to call a function")
println(s"Calling checkDonutAvailability with Vanilla Donut = ${checkDonutAvailability("Vanilla Donut")}")
You should see the following output when you run your Scala application in IntelliJ:
Step 2: How to call a function
Calling checkDonutAvailability with Vanilla Donut = true
3. How to define a Nested Function
If you look closely at the function defined in step 1, you could easily encapsulate the validation logic into a separate function.
For the sake of this example, let's assume that the validation logic is tightly coupled with the function itself and should not be visible by any other functions. As a result, we can use a Nested Function as shown below.
println("\nStep 3: How to define a Nested Function")
def checkDonutAvailabilityWithNestedFunction(donutName: String): Boolean = {
// retrieve donut list that is currently in stock
val listDonutsFromStock = List[String]("Vanilla Donut", "Strawberry Donut", "Plain Donut", "Glazed Donut")
// validate the donutName parameter by some business logic
val validate = (name: String) => {
name.nonEmpty && name.length > 0
}
// first run validate and then check if we have a matching donut from our list
val isDonutInStock = validate(donutName) && (listDonutsFromStock contains donutName)
isDonutInStock
}
NOTE:
- We've defined a value function named validate() which should be familiar from the Function Stored As Values Tutorial.
- As a result, the body of the function becomes less cluttered and more clear to read.
4. How to call a Nested Function
The nested function named validate() from Step 3 should never be visible by anyone else. Hence, calling a function which has nested function in its body is inherently the same as calling any other function.
println("\nStep 4: How to call a Nested Function")
println(s"Calling checkDonutAvailabilityWithNestedFunction with Vanilla Donut = ${checkDonutAvailabilityWithNestedFunction("Vanilla Donut")}")
You should see the following output when you run your Scala application in IntelliJ:
Step 4: How to call a Nested Function
Calling checkDonutAvailabilityWithNestedFunction with Vanilla Donut = true
Summary
In this tutorial, we went over the following:
- How to define a function
- How to call a function
- How to define a Nested Function
- How to call a Nested Function
Tip
- If you have a more complex nested function that would need to be unit tested, then perhaps you should not use a Nested Function.
Source Code
The source code is available on the allaboutscala GitHub repository.
What's Next
If you have followed the previous tutorials, you should by now feel more comfortable with writing functions in Scala.
This would be a good place to proceed to Chapter 4 where I will go over classes and types in Scala.