Langur uses the following, in order of descending precedence.
|after (function calls and indexing)||()
|product||x / \ //
|logical negation||not not?
|logical and||and nand
|logical equivalence||xor nxor
|logical or||or nor
See the numbers page for math operator descriptions.
The append operator works between 2 strings, 2 arrays, or 2 hashes.
It can also be used between a string and integer or between 2 integers (code points), generating a string.
Using append between hashes will silently overwrite if keys in the right hash match keys in the left hash. If you use the more() function instead to add to a hash, it will not overwrite, but throw an exception for matching keys.
As of 0.6.16, appending null to anything acts as a no-op (evaluates to left operand) instead of throwing an exception. Note that this is not how the more() function treats null.
Infix logical and mathematical operators, and the concatenate operator, can be used as combination operators with assignment. For example, writing .x += 1 is the same as writing .x = .x + 1.
It is as though the right-hand is wrapped in parentheses, so that .x x= .a + .b is the equivalent of .x = .x x (.a + .b), not .x = .x x .a + .b (which would be the same as .x = (.x x .a) + .b because of operator precedence).
Prefix combination operators not= and not=? reverse the truthiness of a variable. Writing not= .somevariable is like writing .somevariable = not .somevariable, but much shorter.
Normal operators treat null as an ordinary value (don't favor propagating null). Testing null == null returns true and null == false returns false.
Operators ending with ? are null-propagating (or "database") operators. For these, if either side is null, the result is null. Testing null ==? anything returns null.
The and, or, nand and nor operators are short-circuiting.
Null-propagating operators are short-circuiting in a different manner (only if the left value is null). This includes all infix operators that end with ?, such as and?, nor?, ==?, xor?, etc.
Items of the same type (arrays, hashes, or ranges) may be directly compared for equality or inequality.
Whereas 1 == 1.0, within a composite comparison, this is not true, so that  != [1.0] (checked to see if the same, not equal).
NaN within composite items compare as being the same. So, NaN != NaN, but [NaN] == [NaN]. As of 0.8, this does not apply, as 0.8 has no NaN at all.
As of 0.8, this does not apply, as 0.8 has no NaN at all.
Testing NaN == NaN returns false, and NaN ==? null returns null. The isNaN() function may be helpful here.