# Operators and Expressions¶

## Assignment¶

We touched on assigning a variable a particular value in the Variables tutorial. For example, consider the following line of code:

```var height = 5.4;
```

In this instance, the variable `height` is assigned the value 5.4. Another example would be:

```var total = 6 + 6;
```

The variable `total` is assigned the result of the expression `6 + 6`, which is `12`.

While these two examples constitute the basics of assignment, Shadow also has some unique features assigning more than one value at once.

 ```1 2 3 4 5 6``` ```int x; int y; int z; (x, y) = (3, 6); (x, y) = (y, x); (x, y, z) = 10; ```

The above section of code demonstrates a few Shadow syntactic structures: sequences and two of its subtypes, swaps and splats. In the first three lines of code, the variables `x`, `y`, and `z` are declared but not initialized. However, in Line 4, variables `x` and `y` are initialized in a single line using the basic sequence notation. Line 5 is an example of a swap because now `x` has a value `6` and `y` has value `3`. A swap works because all of the values on the right side are computed before they are stored on the left side. Lastly, Line 6 is called a splat because all three variables are set to `10` in the same line.

## Arithmetic operators¶

Arithmetic operators in Shadow appear mostly as they would in an elementary math class. These are the high-precedence arithmetic operators:

• `*` is used for multiplication

• `/` is used for division

• `%` is used for modular division

These are the low-precedence arithmetic operators:

• `+` is used for addition

• `-` is used for subtraction

### Precedence with arithmetic operators¶

In Shadow, multiplication, division, and modulus take precedence over addition and subtraction, but you can use parentheses to group operations together. The short programs below shows basic expressions using Shadow arithmetic operators.

First, let’s examine some nuances of Shadow division.

```import shadow:io@Console;

class OperatorsExamples
{
public main( String[] args ) => ()
{
/*
* When using / for division, if either the operator or operand is a
* double, the result will be a double (double division).
*/
var divide = 7.0 / 2;
Console.printLine("Result 1: " # divide);

/*
* If the operator and operand are both ints, the result will
* be an integer with everything after the decimal point cut off.
*/
var divide2 = 7 / 2;
Console.printLine("Result 2: " # divide2);

/*
* Although both the operator and operand are ints, the variable
* divide3 is a double. What happens? First, the expression to the
* right of the equals sign is evaluated. Since both numbers are
* ints, the result is also an int: 3. Assignment happens second.
* Shadow recognizes that the result must be stored as a double, so
* now divide3 holds the value 3.0, not 3.5 as some would expect.
*/
double divide3 = 7 / 2;
Console.printLine("Result 3: " # divide3);
}
}
```

Below is the console output for the above program:

```Result 1: 3.5
Result 2: 3
Result 3: 3.0
```

Warning

You will cause a compile error if you try to store the result of `double` division in an `int`.

The program below provides a few extra examples of using the arithmetic operators.

```import shadow:io@Console;

class ArithmeticOperators
{
public main( String[] args ) => ()
{
// Order of operations: (6/3) == 2; (2*2) == 4; (1+4) == 5
// expression1 == 5
var expression1 = 1 + 6 / 3 * 2;

// expression2 == 0
var expression2 = 10 % 2;

// expression3 == 1
var expression3 = 10 % 3;
}
}
```

Note

Modular division is useful when trying to determine if a number is even or odd.

### Negation¶

In addition to being used for subtraction, the `-` operator can also be used for negation of a single item as shown below.

```var x = 6;
x = -x; // Now the variable x holds the value -6
```

When an operator can be used between two operands, it’s called a binary operator (which has nothing to do with binary numbers). When an operator can be used with only a single operand, it’s called a unary operator. In this case, the `-` operator has both binary and unary forms.

## Relational operators¶

Relational operators in Shadow are used to make comparisons and evaluate to one of two values: `true` or `false`. See the list below.

• `==` equal to

• `!=` not equal to

• `>` greater than

• `<` less than

• `>=` greater than or equal to

• `<=` less than or equal to

### A note on `==`¶

When comparing two numeric values, `==` works in the way you would expect. For example:

```var test = (6 == 6);
```

The variable `test` is assigned `true`. However, suppose you wanted to compare two `String` variables using `==`. What would the result be? Consider:

```var want = "coffee";
var need = "coffee";
var compare = (want == need);
Console.printLine(compare);
```

Here, the variables `want` and `need` both are equal to the literal `String` value `"coffee"`, so the result is `true`. While the `==` compares values, Shadow also has the `===` operator which compares references. Let’s say we assign `want` and `need` to new `String` objects (see Classes for more on objects) that both contain the same value:

```want = String:create("coffee");
need = String:create("coffee");

Console.printLine(want === need);
```

Although their contents are the same, `false` is printed because the variables now point to two distinct objects.

The following short program provides examples and explanations for the remaining relational operators.

```import shadow:io@Console;

class Comparisons
{
public main( String[] args ) => ()
{
/*
* The following code illustrates the use of "not equal to", or !=.
* You may use this operator to compare Strings or numeric values (and
* even objects). If the values being compared are not equal,
* "true" is returned.
*/

var sport1 = "polo";
var sport2 = "water polo";
// Should print true, as sport1 and sport2 are not equal.
Console.printLine("Polo is NOT the same as water polo: " # (sport1 != sport2));

/*
* The following code uses >= to make comparisons. Using >, <, and <=
* follows the same guidelines as shown below. If the the variable
* yourAge is greater than or equal to myAge, true will be printed.
*/
var myAge = 20;
var yourAge = 19;
// Should print false, as 19 is NOT >= 20
Console.printLine("You are older or the same age as me: " # (yourAge >= myAge));

/*
* Note: When you compare Strings with these relational operators,
* they are compared lexicographically, meaning with a dictionary ordering.
*/

// Should print true, as "a" comes before "b" in the dictionary
Console.printLine("a is less than b: " # ("a" < "b"));
}
}
```

The console output is here for reference.

```Polo is NOT the same as water polo: true
You are older or the same age as me: false
a is less than b: true
```

## Logical operators¶

Logical operators in Shadow, like relational operators, evaluate to either `true` or `false` when used in expressions. They are commonly used in `if`/ `else` statements, which are discussed in the next tutorial. See below for a list of logical operators:

• `and`

• `or`

• `xor`

• `!`

When two `boolean` values are combined with `and`, the result is `true` if and only if both the values are `true`. When two `boolean` values are combined with `or`, the result is `true` if either (or both) the values are `true`. When two `boolean` values are combined with `xor`, the result is `true` if the two values are different (one `true` and the other `false`). The `!` operator is a unary operator that logically negates its operand, turning `true` to `false` and vice versa.

The following basic program outlines how to use these logical operators:

```import shadow:io@Console;

class LogicalOperators
{
public main( String[] args ) => ()
{
/*
* As seen below, in order for the expression "withCream and !withSugar"
* to evaluate to true, each operand must also be true. In this case, we
* can see that withCream was assigned true and withSugar is assigned
* false but negated. Since both operands are true, the output "I like my
* coffee with cream but NOT sugar!" is printed.
*/
var withCream = true;
var withSugar = false;

if(withCream and !withSugar)
Console.printLine("I like my coffee with cream but NOT sugar!");

/*
* In order for the expression "withCream or withSugar" to evaluate to
* true, only one of the operands needs to be true. Although withSugar is
* assigned false, withCream is declared true, so the statement "I like
* cream OR sugar in my coffee. Surprise me!" is printed.
*/
if(withCream or withSugar)
Console.printLine("I like cream OR sugar in my coffee. Surprise me!");
}
}
```

Although the program outlines their basic functionality, there are a few more points to note when dealing with complex expressions of logical operators.

• `and` takes precedence over `xor`, `xor` takes precedence over `or`, and `!` takes precedence over all of them.

• It’s legal to have an expression with more than one `and`, `or`, or `xor`. When mixing logical operators, it’s wise to use parentheses to make your meaning clear.

• If you have an expression with `and` and the first part evaluates to `false`, Shadow performs short circuit evaluation. In this situation, the second part will not even be evaluated because the whole thing will be `false`. If the second part contains a method, it will not be called. The same idea applies to `or` when the first part evaluates to `true`.

## Combined assignment operators¶

In addition to `=`, there are a handful of other operators that give shortcuts for another operation combined with assignment. See the list below:

• `+=`

• `-=`

• `*=`

• `/=`

• `%=`

• `#=`

Each of these operators performs the operation (`+`, `-`, `*`, `/`, `%`, or `#`) with the values on the left and right sides of the operator and the assigns the result to the variable on the left.

 ```1 2 3 4 5``` ```var x = 10; x %= 2; //Now x == 0 var y = 10; y = y % 10; // Now y == 0 ```

Although Lines 2 and 5 effectively do the same thing, line 2 is shorter way to write the operation followed by assignment.

Note

The `++` and `--` operators used in Java and C-family languages to increment and decrement variables do not exist in Shadow. Instead, you can use `+= 1` and `-= 1`, respectively, to achieve the same effects.

## Cat operator¶

As mentioned in the earlier Declaring variables section, `#` is called the cat operator in Shadow. It’s Shadow’s version of the concatenation operator.

The purpose of `#` is to concatenate values with `String` values. For example, we can use `#` to combine the values of variables with formatting text in `Console.printLine()` statements. Another example is below. It’s important to note that this operator has a lower precedence than addition. In other words, the addition `1 + 1` will happen before the result is combined into a `String` with `#`.

```var name1 = "R";
var name2 = "D";
Console.printLine(name1 # 1 + 1 # name2 # 2);
```

When the program runs, `R2D2` will be displayed on the console.

You can also use a unary form of `#` by putting it in front of any value, which will call its `toString()` method. Take this example:

```String number = #25;
```

Now, `number` contains a `String` with the value `"25"`.