2.17 Local Variables

Consider the following triangle:

image

Let us try to define a function in Julia that calculates the area of the triangle from the parameters \(a\), \(b\) and \(c\). To this end, we can use Heron’s formula:

Heron of Alexandria was an important Greek mathematician and engineer of the 1st century AD to whom numerous discoveries and inventions were credited, including the steam engine and the syringe.

\[A=\sqrt{s\left(s-a\right)\left(s-b\right)\left(s-c\right)}\]

in which \(s\) is the triangle’s semi-perimeter:

\[s=\frac{a+b+c}{2}\]

When trying to translate Heron’s formula to Julia we come across a problem: the formula is (also) written in terms of the semi-perimeter \(s\), which is not a parameter but rather a value that is derived from other parameters of the triangle.

One way of solving this problem is to replace \(s\) with its meaning:

\[A=\sqrt{\frac{a+b+c}{2}\left(\frac{a+b+c}{2}-a\right)\left(\frac{a+b+c}{2}-b\right)\left(\frac{a+b+c}{2}-c\right)}\]

From this formula, it is now possible to define the function in Julia:

triangle_area(a, b, c) =

  sqrt((a+b+c)/2*((a+b+c)/2-a)*((a+b+c)/2-b)*((a+b+c)/2-c))

Unfortunately, this definition has two problems. The first one is the loss of correspondence between the original formula and the function definition, making it harder to recognize it as Heron’s formula. The second problem is the repeated use of the expression (a+b+c)/2, which is not only a waste of human effort, because we had to write it four times, but also a waste of computational effort, because, for each invocation of the function, the expression needs to be calculated four times, even though we know that the last three calculations will produce the same result as the first one.

In order to solve these problems, Julia allows the use of local variables. The meaning of a local variable is restricted to the scope where the variable was established and is used to calculate intermediate values such as the semi-perimeter s. We can create local variables using the let form. The redefinition of the previous function using the let form is as follows:

triangle_area(a, b, c) =

  let s = (a+b+c)/2

    sqrt(s*(s-a)*(s-b)*(s-c))

  end

When we call the function triangle_area, giving it the arguments for the corresponding parameters a, b and c, the function starts by introducing an additional name - s - associated to the value of the expression (a+b+c)/2. The function then evaluates the remaining expressions in the function’s body, which may reference this new name. In practice, it is as if the function was stating: “Knowing that \(s=\frac{a+b+c}{2}\), calculate \(\sqrt{s\left(s-a\right)\left(s-b\right)\left(s-c\right)}\).”

In the previous function, we only introduced one local variable, but it is possible to introduce several variables at the same time. The syntax of let is the following:

let name1 = expr1,

    name2 = expr2,

    ...

    namen = exprn

  body

end

The semantics of the let form consists in successively associating each name namei to the corresponding expression expri and, in the context established by that association, evaluating the let’s body.