if and match are control structures that determine which code block to perform based on the evaluated result of one or more conditional expressions.

## if vs. match

Let's use a simple number comparison to illustrate how if and match work.

### if

In this heavily commented example, the code block to perform is determined by comparing a combined roll of two die with 7:

```// Is roll equal to 7?
if roll == 7
// If so, assign result to "Perfect"
result = "Perfect"

// Otherwise ("else if"), is roll less than 7?
elif roll < 7
// If so, assign result to "Too low!"
result = "Too low!"

// Otherwise (since the roll is not 7 nor less than 7)
else
// Assign result to "Too high!"
result = "Too high!"
```

Every if structure follows these rules:

• It begins with if followed by a conditional expression and then a block of statements. In this example, roll == 7 is the conditional expression. A block may hold one or more multiple statements.
• Any number of elif structures may follow (including none). Each specifies its own conditional expression and a block of statements.
• If specified, a single else structure comes last. It has no conditional expression; only a block of statements.

Since if may be used as an expression, the above code can be simplified to:

```result = if roll == 7
"Perfect"
elif roll < 7
"Too low!"
else
"Too high!"
```

If a block has multiple statements, the expression in the last statement of the block is used as the value of that block.

The above example can also be written on a single line:

```result = if roll == 7 {"Perfect"} elif roll<7 {"Too low!"} else {"Too high!"}
```

#### if clause

When an if structure has only a single block containing only a single statement, this can be written on a single line by appending an if clause to the statement:

```bignumber = true if nbr > 100
```

That line is exactly equivalent to:

```if nbr > 100
bignumber = true
```

### match

The match statement works similarly to if. Its purpose is to match a single value against a list of patterns. In effect, it splits up a conditional expression into two parts: the value to match and a list of patterns to match it against using the ~~ operator.

Here is the earlier example rewritten using match:

```result = match roll
with 7
"Perfect"
with 1 .. 6    // Using a range of values as a match pattern
"Too low!"
else
"Too high!"
```

match has a number of other tricks up its sleeves, described in depth later in this chapter once we have described the powerful match operator.

## Conditional Expressions

A wide variety of conditional expressions can be formulated, from simple equivalence or comparisons to complex algorithms that use logical operators, pattern matching, functions or methods.

### True vs. False

A conditional expression evaluates to true or false. The integer number 0, the null pointer, and false all evaluate to false. All other values evaluate to true. Thus:

```// This statement will never execute
a += 1 if 0   // since 0 is equivalent to false

// This statement will always execute
a += 1 if "hello"
```

These rules make it possible to use function or method calls as part of a conditional expression:

```a += 1 if a.isOdd
```

Conditional expressions are not just for if and while. A conditional expression may be used within any expression:

```imm isOne Bool = (a == 1)    // isOne will be either true or false
```

### Equivalence Operators

The == operator returns true if two values have the same content and type. != (not equal) is true if they do not. For example:

```x == 3.0        // Returns true if the local variable x's value is 3.0
x+1 != y        // Returns true if x is not exactly 1 greater than y
true != false   // Returns true
```

As with the arithmetic operators, the == and != operators are implemented as type-specific methods. Thus, each type can establish its own rules for equivalence. For example, two floating point numbers could be evaluated as equal if they are within some margin of error (resulting from floating point calculation rounding errors). Similarly, two lists might be equal if they have the exact same contents. Some types may not implement the == method.

### Comparison Operators

Comparison operators determine whether one value is greater or less than some other value. They work only on types that are comparable, such as numbers.

```x >= 2          // Returns true if x is greater than or equal to 2 (>, <, <= are variants)
2 <= 2.0        // Returns false any time the types do not agree
```

Float values are compared using the same closeness criteria described above. For one Float value to be less than another, it must be less by at least the comparable closeness.

In some cases, a type can make its values comparable by implementing just the <=> (rocket-ship) operator/method. This returns an integer (rather than true or false): -1 if less, 0 if equal, and 1 if greater.

```-2 <=> 4      // Returns -1
```

Use of the Comparable trait would then implement the other comparison operators using the rocket-ship operator.

### Pattern Matching Operator

The ~~ pattern match operator is used to match a value to a specific pattern. For example:

```5 ~~ i32      // true, since the type of 5 is i32
5 ~~ 1 .. 7   // true, since 5 is within the range between 1 and 7
```

The ~~ operator is powerful and unusual:

• It may be used to match a value to a type. The match also succeeds if the value's type is a subtype of the specified type. This match could happen at compile-time or run-time.
• If the match pattern is not a type, it uses the ~~ method on the match pattern. Thus, in the example above, the Range type implements the ~~ method that is used to determine if a value lies within the Range's interval of values.

Notice that this reverses the usual order for operators which are implemented using methods: it is the right-hand value (the match pattern) that must implement the ~~ method, and the left-hand value which is passed as a parameter to that method. Thus, a~~b is implemented as: b.`~~`(a). This exception makes the code easier to read and mirrors the order on the 'match' statement, while still putting the matching work on the pattern, where it belongs.

• Any type that implements the == method should also implement the ~~ method, even if only to the same method. Doing so allows the use of the match statement for simple multi-value comparisons.
• The ~~ method may be used as an match-and-extract mechanism, by returning an extracted value upon a successful match, or else null if the match fails. For example, the match pattern might be a regular expression that returns an extracted string or list of strings on a successful match.

Use of the powerful ~~ operator is made possible by the richness of pattern-matching types it is capable of supporting: set membership, regular expression, search selectors (e.g., for parts), parsers, input decoder, translater, information analysis, etc.

### Boolean Operators

Acorn has three boolean operators: and ('&&'), or ('||') and not ('!'). One can use either the word or the symbol. For example:

```0==3 or not 2<3 and 3==3   // Returns true ('and' is evaluated before 'or')
0==3 || !2<3 && 3==3       // equivalent to above
```

The logical operators work mostly how you would expect:

• As mentioned earlier, they treat 0, null and false as false. All other values are considered true.
• The boolean operators && and || will stop evaluating any time the answer is known for sure. Thus, the .isEmpty method will never be performed in this expression (making it similar to a simple 'if' statement):
```false and list.isEmpty
```
• The logical operators have a lower precedence than evaluation operators, but higher than assignment. ! has the highest precedence, then &&, then ||.

Note: In case it is not obvious by now, these boolean operators are not the same as the boolean bit-wise logical operators described earlier.

Note 2: If a comparison operator or boolean operator is used outside the context of a control structure that wants a conditional expression (e.g., if), in most cases it will evaluate to a value of 'true' or 'false'. If the conditional expression just uses 'and' or 'or' operators, its value will be the last value evaluated in that expression.

## Match statement

Now that we have talked about the ~~ pattern match operator, let's return to the match statement which makes use of that operator. By default, the 'match' statement uses the '~~' method to match each successive pattern against the value of the 'match' statement's value.

### The 'using' clause

Append a 'using' clause to the 'match' statement to specify a specific method to use for matching (as opposed to using the default '~~'):

```match number using `==`
with 0
.turn
with 1
.jump
```

The using clause can specify any method name or an executable function or closure.

### Multiple patterns on a 'when'

A 'with' statement can list multiple match patterns, separated by commas. A match on any of those match patterns activates that code block.

```match number using '=='
with 0,1
.turn
with 2,3,4
.jump
```
Extracting match results

Some patterns do more than matching. They also extract or transform matched elements within a successfully matched source value, returning one or more new digested value (so long as the first returned value is not false or null, which indicates a match failure). Specify the variables names that hold these returned values with an 'into' clause at the end of the 'match' statement:

```match command into thing
with +Regex"fight [*]"
combat: true
opponent: thing
with +Regex"use [*]"
.use(thing)
```

Regex returns the portion of the Text that lies within the square brackets. So, if command was "fight Lux", the first match would succeed and thing would be set to "Lux".

Alternatively, the return variable name(s) may be specified on any specific 'with' statement:

```match command
with +Regex"fight [*]" into npc
combat: true
opponent: npc
with +Regex"use [*]" into item
.use(item)
```