## Matching and Guards and Scope of Variables

In the previous section we wrote a little example program for converting temperatures. In creating programs like that with special data structures (in our case, a list of cities and their temperatures), it's often useful to create utility functions which make working with our data more convenient. We will explore that below and use these functions to introduce some new concepts.

### A Utility Function

In this case, it could be useful to find the maximum and minimum temperature in our data. We can add support for this by creating the necessary code little bit at a time. Let's start with creating functions for finding the maximum value of the elements of a property list:

``````(defmodule tut9
(export (list-max 1)))

(defun list-max

(defun list-max
(('() results)
results)
(list-max tail result-so-far)))
``````

Then, in the LFE REPL:

``````> (c "tut9.lfe")
#(module tut9)
> (tut9:list-max '(1 2 3 4 5 6 7 4 3 2 1))
7
``````

### Pattern Matching

Before we talk about pattern matching, let's clarify why we have two different functions with the same name. Note that the two `list-max` functions above each take a different number of arguments (parameters). Or, another way of saying it: they have different arity. In LFE, functions having the same name but differing in arity are actually different functions. Where we need to distinguish between these functions we write `<function name>/<arity>`, where `<arity>` is an integer representing the number of arguments that function takes. For our example above, we would write `list-max/1` and `list-max/2`.

The next thing we should explain is the arguments for the `list-max/2` function, since that probably looks pretty strange the first time you see it. If you look closely, you will see that there are three clauses in `list-max/2` and each clause stats with the function arguments for that clause; in order, they are:

• an empty list and `results`
• a `cons` and `results-so-far` with something called a guard (more on that soon)
• a `cons` and `results-so-far` just by itself

What each of these are doing is what is called pattern matching in LFE: if the arguments passed to `list-max/2` match the first pattern, the first clause gets executed and the others don't. If the first one does not match, the second one is tried, and so on.

So what is being "matched" here? Well, the first clause will match if it's first argument is an empty list. The second and third will match if the first element is a list. The second has something more, though: let's take a closer look.

### Guards

In the second clause of `list-max/2` we see a new form: `(when ...)` which contains a comparison operation. The special form `when` is a something we can use with LFE patterns to limit a match. In this case we use it to say: "only use this function clause if `head` is greater than `result-so-far`. We call tests of this type a guard. If the guard isn't true (usually referred to as "if the guard fails"), then we try the next part of the function.

### Stepping Through the Function

Now that we know how there can be two functions with the same name and how the arguments for `list-max/2` are working, let's step through the functions above. They represent an example of walking through a list and "carrying" a value as we do so, in this case `result-so-far` is the variable that carries a value as we walk. `list-max/1` simply assumes that the max value of the list is the head of the list and calls `list-max/2` with the rest of the list and the value of the head of the list, in the above this would be `(list-max '(2 3 4 5 6 7 4 3 2 1) 1)`. If we tried to use `list-max/1` with an empty list or tried to use it with something which isn't a list at all, we would cause an error. The LFE philosophy is not to handle errors of this type in the function they occur, but to do so elsewhere. More about this later.

In `list-max/2` we walk down the list and use `head` instead of `result-so-far` when `head` is greater than `result-so-far`. In this function, if `head` isn't greater than `result-so-far` then it must be smaller or equal to it, and the next clause is executed under this condition.

To change the above program to one which works out the minimum value of the element in a list, all we would need to do is to write `<` instead of `>` in the guard ... but it would be wise to change the name of the function to `list-min` :-).

### Scope and `let`

In a function, the arguments that are passed to it are in scope or "accessible" for all of that function. In another function which has been passed its own arguments, only those are in scope; arguments from other functions are not available for use.

In the case of functions which are pattern matching on the arguments, like our `list-max/2`, we have three clauses, each with their own arguments and each with their own scope. The parentheses at the beginning of each clause mark this scope. In that case, the `results` variable is only available in the first clause; it is not in scope for the second two clauses.

But passing arguments to functions and pattern matching function arguments are not the only ways in which you can bind a value to a variable. There is a special form in LFE (and other Lisps) called `let`. Let's1 take a look, shall we? Here's another way we could have written `list-max/2`:

``````(defun list-max
(('() results)
results)
We only made a change to the second clause: we assigned the value of `head` to the variable `new-result-so-far`. This assignment didn't involve any computation or new values, it was essentially just a "renaming" mostly for the sake of demonstration, and arguably to make it more clear the purpose of the value stored in `head`.