langur

operators, precedence, and associativity

Langur uses the following, in order of descending precedence.

See the numbers page for math operator descriptions.

category operators associativityL/R
after (function calls and indexing) ()
[]
'
leftL
exponent ^
^/
rightR
prefix -
product *
/
\
//
rem
mod
leftL
sum +
-
leftL
range .. leftL
append & leftL
forward -> leftL
boolean <
<=
>
>=
<?
<=?
>?
>=?
div
ndiv
div?
ndiv?
is
is not
in
not in
of
not of
leftL
logical negation 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

the forward operator

The -> operator (forward operator) forwards a value to a function or a pattern. This may be used within a switch to match a value against a pattern.

is/is not operators

The is and is not operators are used with a type as the right operand, such as string or list. See the type page for details.

in/not in and of/not of operators

The in operator tests whether a value exists within a composed value. The in operator can also test whether a value is within a range (of the same type). The of operator tests whether a hypothetical index value is valid for a composed value.

These should not be confused with for in/for of loops, which are automated loops.

nxor operator

The nxor operator is analogous to a mathematical iff operation. That is, the result is true if the two operands are logically equivalent (both equivalent to true or both to false).

append operator

The append operator works between 2 strings, 2 lists, 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.

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.

Boolean multiplication

Values of types which have a zero value (number, string, list, hash, and duration) may be multiplied with a Boolean to receive the original value (if true) or the zero value (if false).

"string" * (value > 10) # yields "string" if expression true and zero-length string if false

combination operators

Infix logical and mathematical operators, and the append 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 *= a + b is the equivalent of x = x * (a + b), not x = x * a + b (which would be different because of operator precedence).

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 (lists, hashes, or ranges) may be directly compared for equality or inequality.