# Operators

Birch supports the most common arithmetic and logical operators found in other programming languages.

### Unary operators

The (prefix) unary operators are all of equal precedence, and of higher precedence than all binary operators:

+ Identity - Negative ! Logical not

The standard library provides the obvious overloads for these standard operators for built-in types.

There are no operators for power or modulus: the standard library functions pow and mod should be used instead. There are no operators defined for bit operations.

### Binary operators

The (infix) binary operators are, in order of highest to lowest precedence:

* Multiply / Divide
+ Add - Subtract
< Less > Greater <= Less/equal >= Greater/equal
== Equal != Not equal
&& Logical and
|| Logical or
<- Assign <~ Simulate ~> Observe ~ Distributed as

The last three operators are introduced for concise probabilistic statements. They are syntactic sugar. Firstly, a ~> b is defined to mean exactly:

yield b.observe(a);


where the yield will be of type Real, and gives the log-likelihood of the observed value a under distribution b. Consequently, it is necessary that b is of a class type with an appropriate observe() member function, typically a subtype of the Distribution class defined in the standard library. If the operator is used outside of a fiber, the yield is omitted.

Then, a <~ b; means exactly:

a <- b.simulate();


and a ~ b; means exactly:

if (a.isMissing()) {
a.assume(b);
} else {
a ~> b;
}


Again, this means that b must be of a class type with appropriate member functions defined, typically a subtype of the Distribution class defined in the standard library

### Query-Get

These are postfix unary operators used with optional and fiber types. They are of equal precedence, and of higher precedence than all other operators:

? Query ! Get

The action of standard operators is defined by overloads, declared using the operator statement. Only the standard operators may be overloaded. All other operators have in-built behaviour as described above.

Info

It is still possible to manipulate the behaviour of some operators that cannot be overloaded. For example, the behaviour of the assignment operator <- can be manipulated by declaring assignments and conversions in class declarations.

A binary operator + with two operands a:A and b:B, and return type C, is declared as:

operator (a:A + b:B) -> C {
c:C;
// ...
return c;
}


Any of the standard binary operators may be used in place of +.

A unary operator + with one operand a:A, and return type C, is declared as:

operator (+a:A) -> C {
c:C;
// ...
return c;
}


Any of the standard unary operators may be used in place of +.

Operators always have a return type. It is not possible to manipulate operator precedence.