# langur

## operators, precedence, and associativity

Langur uses the following, in order of descending precedence. With 0.12 or higher, exponents now have higher precedence than prefix minus.

See the numbers page for math operator descriptions.

category operators associativityL/R
after (function calls and indexing) ()
[]
leftL
exponent ^ ^/ rightR
prefix -
product x / \ //
rem mod
leftL
sum + - leftL
range .. leftL
concatenate ~ (tilde) leftL
boolean < <=
> >=
<? <=?
>? >=?
div ndiv
div? ndiv?
leftL
logical negation not not?
not=
not?=
equality == !=
==? !=?
leftL
logical and and nand
and?
nand?
leftL
logical equivalence xor nxor
xor?
nxor?
leftL
logical or or nor
or? nor?
leftL
assignment = rightR

## append operator

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.

## combination operators

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.

## null-propagating operators

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.

## short-circuiting operators

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.

## composite comparisons

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.

## NaN comparison

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.