# Expressions And Operators: Some Basics

An *expression* involves one or more terms and zero or more operators. Consider the following:

```
$result = get_value(123, "Monday", true)
```

This is an expression, which contains other (sub)expressions: the source code elements `$result`

, `getvalue`

, `123`

, `"Monday"`

,
and `true`

; the operators assignment `=`

and function-call `()`

; and the subexpression `get_value(123, "Monday", true)`

.

A *full expression* is an expression that is *not* part of another expression. Consider the following:

```
$result = get_value(123, "Monday", true);
$v = 10 + $result;
++$v;
for ($i = 1; $i <= 10; ++$i) {
echo "$i\t" . ($i * $i) . "\n"; // output a table of squares
}
return \sqrt($x*$x + $y*$y);
```

The full expressions in this example are, as follows:

```
$result = get_value(123, "Monday", true)
$v = 10 + $result
++$v
$i = 1
$i <= 10
++$i
echo "$i\t".($i * $i)."\n"
\sqrt($x*$x + $y*$y)
```

A *side-effect* is an action that changes the state of the execution environment. (Examples of such actions are modifying a variable,
writing to a device or file, or calling a function that performs such operations.)

When an expression is evaluated, it produces a result. It might also produce a side-effect. The Hack operators that produce side-effects are
assignment, prefix and postfix `++`

and `--`

, and sometimes function-call `()`

. For example, given the
expression statement

```
$v = 10;
```

the expression 10 is evaluated to the result 10, and there is no side-effect. Then the assignment operator is executed, which results in the
side-effect of `$v`

being modified. The result of the whole expression is the value of `$v`

after the assignment has taken place. However,
that result is *not* used! Similarly, given the expression statement

```
++$v;
```

the expression is evaluated to the result 11, and the side-effect is that `$v`

is actually incremented. Again, the final result, 11, is not
used. [If you are confused by that explanation, consider that the perfectly well-formed expression statement `$v + 6;`

has no affect; it
has no side-effect and its result is not used.]

The occurrence of value computation and side-effects is delimited by *sequence points*, places in a program's execution at which all
the computations and side-effects previously promised are complete, and no computations or side-effects of future operations have yet
begun. There is a sequence point at the end of each full expression. The logical AND, logical OR,
conditional, and function-call operators each contain a sequence point. (For example, in the following
series of expression statements:

```
$a = 10; ++$a; $b = $a;
```

there is sequence point at the end of each full expression, so the assignment to $a is completed before `$a`

is incremented, and the
increment is completed before the assignment to `$b`

.

When an expression contains multiple operators, the *precedence* of those operators controls the order in which those operators are
applied. For example, the expression

```
$a - $b / $c
```

is evaluated as:

```
$a - ($b / $c)
```

because the division (`/`

) operator has higher precedence than the binary subtraction `-`

operator. The precedence of all operators is
defined in operator precedence.

If an operand occurs between two operators having the same precedence, the order in which the operations are performed is defined by those
operators' *associativity*. With *left-associative* operators, operations are performed left-to-right. For example:

```
$a + $b - $c`
```

is evaluated as:

```
($a + $b) - $c
```

With *right-associative* operators, operations are performed right-to-left. For example:

```
$a = $b = $c
```

is evaluated as:

```
$a = ($b = $c)
```

Precedence and associativity can be controlled using *grouping parentheses*. For example, in the following expression:

```
($a - $b) / $c
```

The subtraction is done before the division. Without the grouping parentheses, the division would take place first.
While precedence, associativity, and grouping parentheses control the order in which operators are applied, they do **not** control
the order of evaluation of the terms themselves! Unless stated otherwise, the order in which the operands in an expression are evaluated
relative to each other is *unspecified*. (See the discussion above about the operators that contain sequence points.) For example, in
the following full expression:

```
$list1[$i] = $list2[$i++] // diagnosed by the type checker
```

whether the value of `$i`

on the left-hand side is the old or new `$i`

, is unspecified. Similarly, in the following full expression:

```
$j = $i + $i++ // diagnosed by the type checker
```

whether the value of `$i`

is the old or new `$i`

, is unspecified. The same situation occurs in the following:

```
$v = $a + ($a = 6) // diagnosed by the type checker
```

As shown by the comments, in all three cases, the type checker complains, saying something like "Unsequenced modification and access
to local variable", which is good, as there are *no* sequence points in these full expressions.

Finally, in the following full expression:

```
f() + g() * h()
```

the order in which the three functions are called, is unspecified. Yes, multiplication takes precedence over addition, but that
says **absolutely nothing** about the order in which the three functions are called!