Coding With Fun
Home Docker Django Node.js Articles Python pip guide FAQ Policy

The scope of the Erlang match, Guards, and variables


May 13, 2021 Erlang


Table of contents


The scope of the Erlang match, Guards, and variables

In some scenarios, we may need to find the maximum temperature or minimum temperature. T herefore, it is useful to find the maximum or minimum value in the temperature value list. B efore the extender implements this feature, let's look at the method of finding the maximum value in the list:

-module(tut6).
-export([list_max/1]).

list_max([Head|Rest]) ->
   list_max(Rest, Head).

list_max([], Res) ->
    Res;
list_max([Head|Rest], Result_so_far) when Head > Result_so_far ->
    list_max(Rest, Head);
list_max([Head|Rest], Result_so_far)  ->
    list_max(Rest, Result_so_far).
37> c(tut6).
{ok,tut6}
38> tut6:list_max([1,2,3,4,5,7,4,3,2,1]).
7

First note that the names of the two functions are exactly the same. H owever, because they accept different numbers of arguments, they are treated as two completely different functions in Erlang. W hen you need to use them, you can use the name/number of parameters, the name here is the name of the function, the number of parameters refers to the number of parameters of the function. I n this example, list_max/1 and list_max/2

In this example, during traversing the middle element of the list, a value (maximum) is "carried", which Result_so_far list_max/1 the first element in the list as the maximum element, and then uses the remaining element as an argument list_max/2 I n the example above list_max([2,3,4,5,6,7,4,3,2,1],1) I f you call list_max/1 as an list_max or data of a non-list type, an error occurs. N ote that Erlang's philosophy is not to deal with errors where they occur, but to deal with them in places that specialize in errors. W e'll explain it in more detail later.

In list_max/2 when head is Head > Result_so_far head is used instead Result_so_far the function continues to be called. W hen used in front of the function is a special word that means that this part of the function will only be used if the test condition is true. T his type of test is called guard. I f the guard is false (that is, the guard test fails), skip this section and try to use the later part of the function. I n this example, if Head is not greater Result_so_far be less than or equal to . S o the guard test is not required in the next part of the function.

Operators that can be used in guard also include:

  • < Less than
  • > Greater than
  • == Equals
  • >= Is greater than or equal to
  • =< Less than or equal to
  • /= Not equal to

(See Guard Sequences for details)

It's easy to modify the program that looks > for the maximum above to find the minimum element, just < . ( However, it is a good idea to also modify the function list_min

As we mentioned earlier, each variable can only be assigned once within its scope. A s you can see from the example above, Result_so_far been assigned more than once. T his is because every time a list_max/2 is called, a new scope is created. I n each of the different scopes, Result_so_far treated as completely different variables.

In addition, we can use the matching operator to create a variable and assign a value to it. T herefore, the variable M is created by M s 5 and is assigned a value of 5. I f you write M s 6 again in the same scope, an error will result. T ry it in the shell:

39> M = 5.
5
40> M = 6.
** exception error: no match of right hand side value 6
41> M = M + 1.
** exception error: no match of right hand side value 6
42> N = M + 1.
6

In addition to creating new variables, another use for matching operators is to separate the Erlang items.

43> {X, Y} = {paris, {f, 28}}.
{paris,{f,28}}
44> X.
paris
45> Y.
{f,28}

As above, the X value is paris, and the value of Y is .f, 28.

If you use X and Y again, you get an error:

46> {X, Y} = {london, {f, 36}}.
** exception error: no match of right hand side value {london,{f,36}}

Variables are used to improve the readability of the program. F or example, list_max/2 you can write something like this:

list_max([Head|Rest], Result_so_far) when Head > Result_so_far ->
    New_result_far = Head,
    list_max(Rest, New_result_far);

Writing this way makes the program clearer.