## Thinking in Patterns

We've learned how to get a description of all places, but how do we get just the description of just the place where our player is? We can apply our new knowledge:

1. Let's write a function that checks the player location against a `place` record to see if they're the same.
2. Then, let's use that function with a list of place records!

Here's the first part:

``````(defun here?
((loc (match-place name place-name)) (when (== loc place-name))
'true)
((_ _)
'false))
``````

That looks pretty wild, so let's pause while we go through it.

LFE supports something called pattern matching thanks to its heritage from Erlang (which got it from Prolog). Many of the Lisp forms in LFE support pattern matching, and one of those is a function definition: you can put patterns in a function's arguments when you define it. However, when you do this, you need to make some changes. That's why the function above looks funny, because of these changes: an extra set of parentheses is needed (if you're wondering why, it's because instead of just one set of arguments and a function body, patterns allow for many sets of arguments and corresponding bodies ... so the extra set of parentheses is like a list of function definitions).

Functions without pattern matching in their arguments look like this, as we saw previously:

``````(defun <name> (<arg> ...)
<body>)
``````

Whereas functions with pattern matching in their arguments look like this:

``````(defun <name>
((<pattern>)
body)
((<pattern>)
body)
...)
``````

You can have as many different patterns and associated function bodies as you want -- as long as they all have the same number of arguments (also known as arity). Our function has two arguments (2-arity): a location `loc` and a pattern matching against a `place` record. Our pattern was a call to one of the magical functions created by our `place` record, `match-place`. So what got filled in the `<pattern>` slot was a `(match-place ...)` call, and that explains why you saw three opening parentheses in a row.

But we've got something else new there, too: the `when` form. When you see a `(when ...)` after a pattern in LFE, it's called a guard. This guard is standing watch over the pattern, and will only let the pattern match if the location `loc` that was passed as a regular function argument is the same as the `place` record's `location` field.

That takes care of the first pattern and function body. The second function body has a pattern that seems rather strange: `(_ _)`. Then the body simply returns `false` no matter what! In this case, the pattern is saying "I don't care what the values are for the two arguments that are getting passed to me, just move on to the body." And, as we noticed, the body then just returns `false`. Thus, the overall meaning of this function is "if the first pattern is matched, the definition of "here" is met and return `true`; anything else does not meet the definition of "here", therefore return `false`.

Let's try it out against the first place in our `state`'s `places` field:

``````> (here? 'living-room (car (state-places state)))
true
> (here? 'attic (car (state-places state)))
false
``````

`here?` takes two arguments: a location name and a place record. Remember we wanted to be able to handle a list of places. We used `lists:map` before, but that's not exactly what we want here. What would be perfect is if we could find a function that would only return the items of a list that met certain criteria (in this case, the criteria is that the player location and the place record name are the same!).

It turns out there is exactly this function in the Erlang standard library: the `lists:filter` function. `lists:filter` takes two arguments:

1. A predicate function (a function that returns `true` or `false`), given some input, and
2. A list of inputs to give the predicate function.

Let's create a function which uses `lists:filter` to only return the place that returns `true` when we ask `here?`:

``````(defun get-here
(((match-state player-location player-loc places locs))
(car (lists:filter
(lambda (loc)
(here? player-loc loc))
locs))))
``````

We used pattern matching again, but this time to do something a tiny bit clever: we used it to define the variables `player-loc` and `locs`. In other words, with our pattern above, we said "When you get a `state` record coming through here, get its `player-location` field and assign it to the `player-loc` variable; also get its `places` field and assign it to the `locs` variable."

Now we can use this function to get the description of the player location:

``````(defun describe-location (game-state)
(++ (place-description (get-here game-state)) "\n"))
``````

Now let's use our new function:

``````> (describe-location state)
``````
``````"You are in the living-room of a wizard's house. There is a wizard
snoring loudly on the couch."
``````

Perfect! Just what we wanted.