Making computations reusable
Up to this point, we've been programming statement by statement, just like a baking recipe. Take the following excerpt of a cookie recipe as an example where you have to put the cookies in the oven multiple times.
As you can probably tell, the instructions regarding the oven are very repetitive. Wouldn't it be smarter if you explained once how to use the oven and then just referenced that explanation everytime the oven has to be used? Admittedly, most people know how to use an oven and don't need an explanation on how to use one, but, just for the sake of the example, imagine you've never used one before.
With this change, the recipe has become a lot simpler and is no longer repetitive. Additionally, it becomes straightforward to add further steps where the oven has to be used.
In programming, we can achieve something similar with a concept you should be familiar with from math: Functions. Let's switch examples for now. What if you had a shopping coupon for 10% off and one for $5 off that can both be used simultaneously at the register. While shopping, you would like to continually know your total to see if you can afford further products with the coupons applied. In mathematical notation, you could define a function f that calculates the discounted price if you input the price as x into the function.
To make this more readable, let's use more descriptive names for the function f as well as the input x.
With this function we can easily calculate the discounted price over and over again. This has the same advantages as shown in the previous example. Instead of explaining once how to use the oven, we explained once how to apply the coupons to the items in our cart. Now we can continually calculate our total without having to type out the underlying calculation every time.
Let's take a look at how to define the same function in Rouge. It might look more verbose compared to the same function in its mathematical notation; however, you have been introduced to all the building blocks making up this definition. Let's go through it step by step.
A function is a value just like the Numbers, Booleans and Strings we have taken a look at previously. Therefore, we can just as much assign functions to variables. In our case, we are assigning our function to the variable called apply_discount which is how our function receives its name. On the other side of the assignment is where most of the definition resides. Whenever we want to define a function, we have to start with the specific word function so the language knows we want to define a function.
Now, just like in the mathematical notation, the input to the function is written in parentheses. This is the point where Rouge starts to differ from the mathematical notation. In maths, most of the time we are working with numbers. For this reason, we were able to skip an explanation of what the input total even is in the mathematical notation. However, we have learned that in programming there are various data types. In order for Rouge to work properly, it needs to know what data type the input of a function is made of. We are still working with numbers, therefore we can use the type literal Number on the input total.
In the mathematical definition we also assumed that the function computes to a number as well. In Rouge, we need to specify the data type of the function's result. We can do so by adding another type literal after an arrow (->). The data type of a function's result is referred to as its return type. In our example the return type is also a Number.
All the calculations we want to perform inside our function are placed between two curly braces. To be more specific, the inside of a function contains a list of statements. In turn, these statements perform the calculations. In our example, we are going to stick with a single statement for now to calculate our total. The actual calculation only comprises numeric operations that you are already familiar with. However, compared to the mathematical notation, there is one more difference. Our final statement needs to start with the keyword called return. This special statement indicates to the language that we have reached the end of our calculations inside the function, and we would like to use the value after the return keyword as the result of the function. A statement that returns the result of a function is also called a return statement.
The closing curly brace concludes the function definition in Rouge. Now, let's take a look at how we can use the function to calculate a result based on a given input. The process of taking a function and calculating its result is referred to as calling the function.
Output:
As you can see, calling a function does not differ from its mathematical notation. The result of calling the function is a value, which allows us to save the result in a variable. The result of the function call is referred to as the return value of the function.
To summarize, in this chapter we learned how to make numeric computations reusable by introducing the concept of functions. Functions can do much more than crunch numbers, however, which we will explore in the following chapters.