Operators

Unary operators

-a negates a number.

~a is bitwise negation.
Since this latter is an uncommon operation, it's defined in keen/bits. (Imports will be explained in Modules.)

import keen/bits main void() i int = 1 log -i n nat = 1 log ~n

The - operator doesn't work on nat since that is an unsigned type.
The ~ operator doesn't work on int since bitwise operations on signed numbers are confusing.

Defining operators

Operators are just ordinary functions, so you can define them for any type.

main void() a point = 1, 2 log -a point record(x float, y float) ~ - point(a point) -a.x, -a.y

Binary operators

Here are all binary operators and operator-like syntaxes, in order from lowest to highest precedence.
Operators with the same precedence, such as < and >, share a row in the table.

Lower precedence means being less tightly binding.
+ has lower precedence than *, so 1 +2 *3 is 7 because 2 * 3 binds more tightly than 1 + 2.

SyntaxUse
isAsserts that two expressions have the same value.
foo=A function name may end in = , which makes it parse as infix.
elseProvides a default value for an option. See Options.
orTrue if either side is true.
andTrue if both sides are true.
'fooInfix function calls.
fooNormal function calls.
..Creates a range, e.g. 0 .. 10 . The low end is inclusive and the high end is exclusive.
~, ~~Adds one (~) or many (~~) elements to a collection.
==, !=, <, >, <=, >=, <=>Standard comparison operators. All return bool except <=> returns comparison.
|Union (of sets, flags, or bits in a nat).
&Union (of sets, flags, or bits in a nat).
<<, >>Bitshift left and right. These are only defined for nats.
+, -Addition and subtraction.
*, /, %Multiplication, division, and modulo.
**Exponentiation: 2 ** 3 is 8.

As shown above, infix function calls like 'contains have lower precedence than any operator.

main void() log (10 .. 10 + 10 'contains 15)

The above parses like: log ((10 .. (10 + 10)) 'contains 15)

The parentheses around the argument to log are needed because the call to 'contains has lower precedence.

Assignment functions

Function names are allowed to end in an = sign.
If they do, they are always parsed as infix and with an especially low precedence.

main void() # This declares a mutable array. xs nat mut[] = 1, 2, 3 xs ~= 4 xs ~~= 5, 6 xs filter= it.is-even log xs

Binary assignment

Any binary function, including operators, can be combined with the assignment operator := to update a local.

main void() x mut = 3 # Same as `x := x + 2` x +:= 2 log x # Same as `x := x 'min 4` x min:= 4 log x

This works with set-x functions too, such as record field setters.

main void() a mut-point = 1, 1 # Same as `set-x a, a.x * 2` a.x *:= 2 log a.x mut-point record mut x mut float y mut float

Logical "operators"

The logical binary operators are and and or. These don't evaluate their right hand side if not necessary.
not negates a boolean.

main void() x nat = 11 log not is-even x # Parentheses are needed because "and" and "or" # have lower precedence than normal functions like "log" log (x > 3 and x < 6 or x > 9 and x < 12)