# Operators¶

Corporate accounts payable, Nina speaking! Just a moment!

—Nina, corporate accounts payable,

Office Space

The expression subset of the Monte grammar is presented here in
operator precedence order, meaning that later constructs bind tighter
than earlier constructs. For example, expr “+” expr is presented
before expr “*” expr, so `*`

binds tighter than `+`

. Therefore,
`a + b * c + d`

is equivalent to `a + (b * c) + d`

. All the
constructs in presented in the same section have the same precedence.

Monte has a rich set of operators above and beyond those in Kernel-Monte. All
operators are overloadable, but overloading follows a very simple set of
rules: Operators expand to message passing, and the message is generally
passed to the left-hand operand, except for a few cases where the message is
passed to a *helper object* which implements the operation. In object
capability shorthand, we are asking the object on the left what it thinks of
the object on the right.

There are some special rules about the behavior of the basic operators because of E’s distributed security.

Todo

special operator rules because of security

## Sequence¶

**sequence**

A sequence expressions evaluates to the value of its last item:

```
>>> { 4; "x"; "y" }
"y"
```

## Assignment and Definition¶

**assign**

**lval**

Assignment is right associative. The list update on the right happens before the definition on the left:

```
>>> def color := ["red", "green", "blue"].diverge()
... def c := color[1] := "yellow"
... c
"yellow"
```

### Indexed Update Expansion¶

An indexed update expands to a call to `put`

:

```
>>> m`x[i] := 1`.expand()
m`x.put(i, def ares_1 := 1); ares_1`
```

### Augmented Assignment Expansion¶

**VerbAssignExpr**

All binary operators which pass a message to the left-hand operand can be used as augmented assignment operators. For example, augmented addition is legal:

```
>>> { var x := "augmenting "; x += "addition!"; x }
"augmenting addition!"
```

Behind the scenes, the compiler transforms augmented operators:

```
>>> m`x += "addition!"`.expand()
m`x := x.add("addition!")`
```

Monte permits this augmented construction for any verb, not just those used by
operators. For example, the `with`

verb of lists can be used to
incrementally build a list:

```
>>> { var l := []; for i in (1..10) { l with= (i) }; l }
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
```

And even non-unary messages can get in on the fun, with a properly placed pair of parentheses:

```
>>> { var x := 7; x modPow= (129, 3) }
1
```

Todo

VERB_ASSIGN lexical details

### Assignment operators¶

```
>>> var x := 5; [ x += 2, x -= 1, x *= 2, x **= 3 ]
[7, 6, 12, 1728]
>>> var x := 50; [ x //= 3, x %= 7, x /= 4]
[16, 2, 0.500000]
>>> var x := 5; [ x ^= 3, x |= 15, x &= 7, x <<= 3, x >>= 2]
[6, 15, 7, 56, 14]
```

## Conditional-Or¶

**logical_or**

Monte uses C syntax for the basic logical operators:

```
>>> false || true
true
```

Evaluates left to right until it finds a true condition.

```
>>> {((1 =~ x) || (2 =~ x)); x}
1
>>> {((1 =~ [x, y]) || (2 =~ x)); x}
2
```

## Conditional-And¶

**logical_and**

### Logical Expansion¶

Boolean conditionals expand to `if`

expressions:

```
>>> m`a || b`.expand()
m`if (a) { true } else if (b) { true } else { false }`
>>> m`a && b`.expand()
m`if (a) { if (b) { true } else { false } } else { false }`
```

## Comparisons and Bitwise/Logical Operators¶

**comp**

**order**

These are non-associative: `x == y == z`

is a syntax error.

```
>>> false == true
false
```

```
>>> false != true
true
```

You can compare with a pattern and use the resulting bindings:

```
>>> [1, "x"] =~ [_ :Int, _ :Str]
true
>>> [1, 2] =~ [a, b]; b
2
>>> "<p>" =~ `<@tag>`; tag
"p"
>>> "<p>" !~ `</@tag>`
true
```

Comparison is more strict than you might expect:

```
>>> 3 == "3"
false
>>> 1 + 1 == 2.0
false
```

We also have negated implication operator:

```
>>> true &! false
true
```

Boolean Comparisons (non-associative):

```
>>> false & true
false
>>> false | true
true
>>> false ^ true
true
```

### Comparison Expansion¶

Comparisons expand to use of a helper object:

```
::
```

```
>>> m`x == y`.expand()
m`_equalizer.sameEver(x, y)`
>>> m`x != y`.expand()
m`_equalizer.sameEver(x, y).not()`
```

```
>>> m`"value" =~ pattern`.expand()
m`def sp_1 := "value"; def [ok_2, &&pattern] := escape fail_3 { def pattern exit fail_3 := sp_1; _makeList.run(true, &&pattern) } catch problem_4 { def via (_slotToBinding) &&broken_5 := Ref.broken(problem_4); _makeList.run(false, &&broken_5) }; ok_2`
>>> m`"value" !~ pattern`.expand()
m`(def sp_1 := "value"; def [ok_2, &&pattern] := escape fail_3 { def pattern exit fail_3 := sp_1; _makeList.run(true, &&pattern) } catch problem_4 { def via (_slotToBinding) &&broken_5 := Ref.broken(problem_4); _makeList.run(false, &&broken_5) }; ok_2).not()`
```

```
>>> m`x ^ y`.expand()
m`x.xor(y)`
>>> m`x & y`.expand()
m`x.and(y)`
>>> m`x | y`.expand()
m`x.or(y)`
>>> m`x &! y`.expand()
m`x.butNot(y)`
```

## Partial Ordering¶

**CompareExpr**

Monte has the usual ordering operators:

```
>>> 3 < 2
false
>>> 3 > 2
true
>>> 3 < 3
false
>>> 3 <= 3
true
```

They are non-associative and only partial:

```
>>> try { 3 < "3" } catch _ { "ouch! no order defined" }
"ouch! no order defined"
```

Use `<=>`

aka `asBigAs`

to compare magnitudes:

```
>>> 2.0 <=> 1 + 1
true
>>> 2 + 1 <=> 3.0
true
```

### Ordering Expansion¶

Ordering operators expand to use of a helper object:

```
>>> m`3 < 2`.expand()
m`_comparer.lessThan(3, 2)`
>>> m`2.0 <=> 1 + 1`.expand()
m`_comparer.asBigAs(2.000000, 1.add(1))`
```

## Interval¶

**RangeExpr**

Non-associative.

We can build a half-open interval with the range operator:

```
>>> [for x in (1..!4) x * 2]
[2, 4, 6]
```

Or we can build closed intervals with the inclusive range operator:

```
>>> [for x in (1..4) x * 2]
[2, 4, 6, 8]
```

Half-open intervals are more typical, though they are in most ways equivalent to closed intervals:

```
>>> (0..!10) <=> (0..9)
true
```

Expansion:

```
>>> m`lo..hi`.expand()
m`_makeOrderedSpace.op__thru(lo, hi)`
>>> m`lo..!hi`.expand()
m`_makeOrderedSpace.op__till(lo, hi)`
```

## Shift¶

**shift**

Left associative.

Among built-in data types, this is only defined on integers, and has the traditional meaning but with no precision limit.

Expansion:

```
>>> m`i << bits`.expand()
m`i.shiftLeft(bits)`
>>> m`i >> bits`.expand()
m`i.shiftRight(bits)`
```

## Additive¶

**additiveExpr**

Left associative.

- ::
>>> [1, 2] + [3, 4] [1, 2, 3, 4]

>>> "abc" + "def" "abcdef"

>>> ["square" => 4] | ["triangle" => 3] ["square" => 4, "triangle" => 3]

>>> def sides := ["square" => 4, "triangle" => 3] ... sides.without("square") ["triangle" => 3]

Expansion:

```
>>> m`x + y`.expand()
m`x.add(y)`
>>> m`x - y`.expand()
m`x.subtract(y)`
```

## Multiplicative¶

**multiplicativeExpr**

Left associative.

```
>>> 2 * 3
6
```

Modular exponentiation:

```
>>> 5 ** 3 % 13
8
```

expansion:

```
>>> m`base ** exp % mod`.expand()
m`base.modPow(exp, mod)`
```

## Exponentiation¶

**exponentiationExpr**

Non-associative.

```
>>> 2 ** 3
8
```

Expansion:

```
>>> m`2 ** 3`.expand()
m`2.pow(3)`
```

## Unary Prefix¶

**prefix**

**SlotExpr**

**BindingExpr**

Monte has logical, bitwise, and arithmetic negation operators:

```
>>> - (1 + 3)
-4
>>> ~ 0xff
-256
>>> ! true
false
```

Todo

discuss, doctest SlotExpression `&x`

, BindingExpression `&&x`

Expansions:

```
>>> m`! false`.expand()
m`false.not()`
```

## Unary Postfix¶

**MetaExpr**

**CoerceExpr**

```
meta.getState()
meta.context()
```

A guard can be used as an operator to coerce a value:

```
>>> 1 :Int
1
```

## Call¶

**calls**

**call**

**send**

**curryTail**

**index**

**verb**

**argList**

Todo

named args in argList

There are two ways to pass a message. First, the **immediate call**:

```
>>> { def x := 2; def result := x.add(3) }
5
```

And, second, the **eventual send**:

```
>>> { def x; def prom := x<-message(3); null }
null
```

Calls may be curried:

```
>>> { def x := 2; def xplus := x.add; xplus(4) }
6
```

Todo

discuss matchers in object expressions

### Call Expansion¶

Function call syntax elaborates to a call to `run`

(
and likewise vice-versa):

```
>>> m`f(x)`.expand()
m`f.run(x)`
```

Indexing elaborates to a call to `get`

:

```
>>> { object parity { to get(n) { return n % 2 }}; parity[3] }
1
```

`M`

is a helper object that provides several runtime services. It can pass
messages on behalf of other objects and quote strings.

Eventual send syntax expands to calls to `M`

:

```
>>> m`target<-verb(args)`.expand()
m`M.send(target, "verb", _makeList.run(args), _makeMap.fromPairs(_makeList.run()))`
>>> m`target<-verb(args, "name" := namedArg)`.expand()
m`M.send(target, "verb", _makeList.run(args), _makeMap.fromPairs(_makeList.run()))`
```