# langur

## operators, precedence, and associativity

Langur uses the following, in order of descending precedence.

category operators associativityL/R
after (function calls and indexing) ()
[]
leftL
prefix -
exponent ^ ^/ rightR
product x / \ //
rem mod
leftL
sum + - leftL
range .. to 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

See the numbers page for math operator descriptions.

## 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.