---
title: Operators
canonical_url: https://mew-lang.org/language/operators/
sidecar_url: https://mew-lang.org/language/operators.md
content_hash: sha256:ae48b7f88527b6baae22c605c5b5443e1b45378e95fb9af852013918b286f67e
tokens: 1618
uid: language.operators
reading_time_minutes: 6
---

Language
# Operators

 
## Precedence

 
Tightest first. An operator binds its operands more tightly than anything below it in this table.

 
    Level Operators Groups     15 `a[i]` left   14 `f(x)` left   13 `a.b` `a::b` left   12 `!a` `-a` `+a` right   11 `*` `/` `%` left   10 `+` `-` left   9 `is` left   8 `as` left   7 `<` `<=` `>` `>=` left   6 `==` `!=` left   5 `&&` left   4 `\|\|` left   2 `a ? b : c` right   1 `=` `+=` `-=` `*=` `/=` `%=` right    
 
Parentheses group, and a grouped expression is whatever is inside it.

 
> [!IMPORTANT]
> `as` and `is` bind looser than arithmetic, which is not how they read. Both take a type on the right rather than an expression, so everything the arithmetic operators have already claimed is the left operand.
> 
> `a + b as i64` is `(a + b) as i64`, not `a + (b as i64)`.

 
```mew
use std;
  
let a: i32 = 7;
let b: i32 = 2;
  
let together = a + b as i64;   // (a + b) as i64
let separate = a + (b as i64); // the other reading, written out
  
println($"{together} {separate}");
```

 
The two answer the same here, but they do not in general: the cast applies to a different value, so a sum that overflows an `i32` overflows before it widens. Write the parentheses when the difference matters.

 
Member access binds tighter than unary, so `-point.x` negates the field rather than the value. A call binds tighter than the access it is part of, which is why `value.doubled()` reads as one thing.

 
## Arithmetic

 
    Operator On Produces     `*` `/` `%` `-` two numbers their [coercion](https://mew-lang.org/language/primitives/numbers.md#coercion)   `+` two numbers their coercion   `+` two strings `string`   `+` a `string` and a `char` `string`    
```mew
use std;
  
println($"{7 * 6}");
println($"{7 / 2}");
println($"{7 % 2}");
println("Hello, " + "world");
println("x" + 'y');
```

 
`+` joins text only for those two cases. To put a number or a `bool` into a string, [interpolate](https://mew-lang.org/language/primitives/text.md#string-interpolation) it.

 
```mew
let text = "count: " + 3;
```

 
## Comparison

 
`<`, `<=`, `>` and `>=` compare two numbers and answer a `bool`. A `char` takes part as its code point.

 
```mew
use std;
  
println($"{1 < 2}");
println($"{'a' < 'b'}");
```

 
`==` and `!=` work on the numeric types, `string`, `bool` and `char`, the types that have a value to compare.

 
```mew
use std;
  
let name = "Ada";
  
println($"{1 == 1}");
println($"{name == "Ada"}");
println($"{true != false}");
println($"{'x' == 'x'}");
```

 
They do not work on a type you declare, on a [union](https://mew-lang.org/language/unions.md), on an array, or on `any`. There is no structural comparison and no way to give a type one.

 
```mew
pub type Point {
    pub field x: i32;
}
  
let a = new Point { x: 1 };
let b = new Point { x: 1 };
let same = a == b;
```

 
To compare two values of your own type, write a method that says what comparing them means.

 
```mew
use std;
  
pub type Point {
    pub field x: i32;
    pub field y: i32;
}
  
impl Point {
    pub fn equals(other: Point) -> bool {
        return self.x == other.x && self.y == other.y;
    }
}
  
println($"{new Point { x: 1, y: 2 }.equals(new Point { x: 1, y: 2 })}");
```

 
To ask which case a union holds, [match](https://mew-lang.org/language/unions.md#reading-a-value) is what asks.

 
## Logical

 
`&&`, `||` and `!` work on `bool` and answer one. `&&` and `||` [short circuit](https://mew-lang.org/language/primitives/bool.md#short-circuiting); everything else evaluates both sides, left before right, before the operator is applied.

 
```mew
use std;
  
let ready = true;
let done = false;
  
println($"{ready && !done}");
println($"{done || ready}");
```

 
## Unary

 
    Operator On Produces     `!` `bool` the negation   `-` a number the negation   `+` a number the operand unchanged    
 
There is no negative literal, so `-1` is this `-` applied to `1`. That matters only where it changes the reading: `-a.b` is `-(a.b)`.

 
```mew
use std;
  
let value = 5;
  
println($"{-value}");
println($"{+value}");
println($"{!(value > 10)}");
```

 
## Type operators

 
[is](https://mew-lang.org/language/type-checking.md) asks what a value is and answers a `bool`. [as](https://mew-lang.org/language/type-casting.md) performs a conversion that is not implicit. Both take a type on the right, and both bind looser than arithmetic.

 
```mew
use std;
  
let boxed: any = 32;
  
if boxed is i32 {
    println($"{boxed as i32}");
}
```

 
## Conditional

 
`a ? b : c` produces one of two values. The condition is a `bool`, and exactly one of the two branches is evaluated.

 
```mew
use std;
  
let count = 3;
  
println(count == 1 ? "one" : "many");
println($"{count < 0 ? -count : count}");
```

 
It groups to the right, so a chain of them reads as a run of tests.

 
```mew
use std;
  
let count = 3;
let name = count == 0 ? "zero" : count == 1 ? "one" : "many";
  
println(name);
```

 
The two branches decide the type between them. Either they already agree, or one of them converts implicitly to the other and that one is the type of the whole expression. `null` brings no type of its own, so the other branch decides.

 
```mew
use std;
  
let wide: i64 = 1 > 0 ? 1 : 2;
let name = 1 > 0 ? "mew" : null;
  
println($"{wide} {name}");
```

 
Branches with nothing in common are an error.

 
```mew
let mixed = 1 > 0 ? 1 : "one";
```

 
Everything except assignment binds tighter, so a comparison in front of the `?` is the condition rather than part of it. Writing one as a statement is an error: it produces a value and a statement discards it, so [if](https://mew-lang.org/language/control/conditions.md) is what runs one of two statements.

 
```mew
use std;
  
let ready = true;
  
ready ? println("saved") : println("discarded");
```

 
## Assignment

 
`=` and the compound operators are the loosest of all, and they group right to left. Assignment is an expression that produces the value it assigned, which [Assignment](https://mew-lang.org/language/assignment.md#assignment-is-an-expression) covers.

 
## What is not here

 
There is no bitwise operator, no shift, no increment or decrement, and no way to give a type an operator of its own. A method is how a type says what an operation on it means.

 
[Previous
                
                Arrays](https://mew-lang.org/language/arrays.md)[Next
                    
                Functions](https://mew-lang.org/language/functions.md)