Piping Bash commands
Executing a composition or chain of functions is very much like executing a series of Bash commands, where the output from one command is piped into the next command. For example, we might cat an input a file that contains a list of timestamps and IP addresses in an awk command. The awk command removes all but the seventh column. Next, we sort the list in descending order, and finally, we group that data by unique IP addresses.
Consider the following Bash command:
$ cat ips.log | awk '{print $7}' | sort | uniq -c
Let's give this command the following input:
Sun Feb 12 20:27:32 EST 2017 74.125.196.101
Sun Feb 12 20:27:33 EST 2017 98.139.183.24
Sun Feb 12 20:27:34 EST 2017 151.101.0.73
Sun Feb 12 20:27:35 EST 2017 98.139.183.24
Sun Feb 12 20:27:36 EST 2017 151.101.0.73
>Sun Feb 12 20:27:37 EST 2017 74.125.196.101
Sun Feb 12 20:27:38 EST 2017 98.139.183.24
Sun Feb 12 20:27:39 EST 2017 151.101.0.73
Sun Feb 12 20:27:40 EST 2017 98.139.183.24
Sun Feb 12 20:27:41 EST 2017 151.101.0.73
Sun Feb 12 20:27:42 EST 2017 151.101.0.73
Sun Feb 12 20:27:43 EST 2017 151.101.0.73
We will get the following output:
6 151.101.0.73
2 74.125.196.101
4 98.139.183.24
This is a very common pattern in functional programming. We often input a collection of data to a function, or chain of function calls, and get a result that has been transformed in some way.
Collections are used frequently. When we implement them in a concise manner, chaining function calls that explicitly declare what we want to accomplish, we greatly reduce code ceremony. The result is that our code is more expressive, concise, and easier to read.