# 10.8. Composing Functions¶

The practice of using functions to build other functions is known as function composition, or simply composition. To demonstrate, we consider a specific example.

## 10.8.1. Palindrome Checker¶

A palindrome can be defined as a word that is spelled the same backwards and forwards. Some examples are "tacocat", "kayak", and "racecar".

Note

There are other factors that are sometimes included in the definition of a palindrome. For example, an alternative definition is that a palindrome is a sentence or phrase that contains letters in the same order, whether considered from beginning-to-end, or end-to beginning, ignoring punctuation, case, and spaces.

We want to write a boolean function---a function that returns `true` or `false`---to determine if a word is a palindrome.

One way to state the palindrome condition is to say that a palindrome is a string that is equal to its reverse. In other words, we can test for palindromes by taking a string, reversing it, and then comparing the reversed string to the original. If the two are equal, we have a palindrome.

To that end, it would be very useful to have a function that reversed a string, wouldn't it?

### 10.8.1.1. The `reverse` Function¶

Let's write a function that, given a string, returns its reverse.

One approach uses the accumulator pattern:

 ```1 2 3 4 5 6 7 8 9``` ```function reverse(str) { let reversed = ''; for (let i = 0; i < str.length; i++) { reversed = str[i] + reversed; } return reversed; } ```

This is the same algorithm that we used previously to reverse a string.

Another approach is to use the fact that there is a `reverse` method for arrays, and that the methods `split` and `join` allow us to go from strings to arrays and back (this was covered in Array Methods).

 ```1 2 3 4 5``` ```function reverse(str) { let lettersArray = str.split(''); let reversedLettersArray = lettersArray.reverse(); return reversedLettersArray.join(''); } ```

Let's break down the steps carried out by this function:

1. Turn the string into an array of characters. We call `str.split('')`, using the empty string as the splitting character, returns an array of the individual characters that make up the string.
2. Reverse the array of characters. To do this, we use the built-in array method `reverse`.
3. Join the reversed character array into a string. We call `.join('')`. Joining with the empty string is the same as concatenating each of the individual characters together into a single string.

Try It!

Use method chaining to reduce the `reverse` function to a single line. Open the link below the source code above to give it a shot.

### 10.8.1.2. The `isPalindrome` Function¶

Using our `reverse` function for strings, we can create our palindrome checker. Recall that our approach will be to take the string argument, reverse it, and then compare the reversed string to the original string.

 ```1 2 3 4 5 6 7``` ```function reverse(str) { return str.split('').reverse().join(''); } function isPalindrome(str) { return reverse(str) === str; } ```

Since `isPalindrome` uses our `reverse` function, this is an example of composition.

Try It!

Does our `isPalindrome` function work? Run it yourself to see!

## 10.8.2. Functions Should Do Exactly One Thing¶

An important consideration when writing a function is size. By "size" we mean that functions should be short and, more importantly, do exactly one thing.

This principle is easier to state than to put into practice. For example, what if we had written `isPalindrome` without breaking out the `reverse` code into a separate function?

 ```1 2 3 4``` ```function isPalindrome(str) { let reversed = str.split('').reverse().join(''); return reversed === str; } ```

This function is still short, which is good. But does it do one thing (check if a string is a palindrome) or multiple things (check the string, and reverse a string)? This is a bit subjective, and here the answer is certainly debatable.

Some cases will be much more clear-cut, however. Consider the sandwich function, `makeSandwich`, from the section A Good Function-Writing Process. Suppose we wanted to expand the capability of our program to not only make a sandwich, but to also pour a beverage (to go along with our lunch). It would be a bad idea to amend our function to do both, ending up with a function that has a name like `makeSandwichAndPourDrink`.

A much better solution would look like this:

 ``` 1 2 3 4 5 6 7 8 9 10 11 12``` ```function makeSandwich( /*parameters*/ ) { // make the sandwich } function pourDrink( /*parameters*/ ) { // pour the drink } function makeLunch( /*parameters*/ ) { makeSandwich( /*parameters*/ ); pourDrink( /*parameters*/ ); } ```

Why is this better? Smaller functions are easier to debug, for one thing. And by separating single responsibilities into individual functions, we also make our code easier to read and more reusable. In looking at the `makeLunch` function, it is very clear what is going on. First, it makes a sandwich, then it pours a drink.

Were the `makeLunch` function to simply contain all of the code necessary to carry out both tasks, there would be no clear separation between one task and the other, and the only way we might describe the various sections of the larger function would be to use comments. And, as we've discussed, comments should be a secondary option for explaining your code.