# DSL operators

## Detailed listing

Operators are listed on the DSL built-in functions page.

## Operator precedence

Operators are listed in order of decreasing precedence, highest first.

Operators Associativity
() left to right
** right to left
! ~ unary+ unary- & right to left
binary* / // % left to right
. left to right
binary+ binary- left to right
<< >> >>> left to right
& left to right
^ left to right
| left to right
< <= > >= left to right
== != =~ !=~ <=> left to right
??? left to right
?? left to right
&& left to right
^^ left to right
|| left to right
? : right to left
= N/A for Miller (there is no \$a=\$b=\$c)

## Operator and function semantics

• Functions are often pass-throughs straight to the system-standard Go libraries.

• The min and max functions are different from other multi-argument functions which return null if any of their inputs are null: for min and max, by contrast, if one argument is absent-null, the other is returned. Empty-null loses min or max against numeric or boolean; empty-null is less than any other string.

• Symmetrically with respect to the bitwise OR, XOR, and AND operators |, &, and ^, Miller has logical operators ||, &&, and ^^.

• The exponentiation operator ** is familiar from many languages, except that an integer raised to an int power is int, not float.

• The regex-match and regex-not-match operators =~ and !=~ are similar to those in Ruby and Perl.

## The double-purpose dot operator

The main use for the . operator is for string concatenation: "abc" . "def" is "abc.def".

However, in Miller 6 it has optional use for map traversal. Example:

cat data/server-log.json
{
"hostname": "localhost",
"pid": 12345,
"req": {
"id": 6789,
"method": "GET",
"path": "api/check",
"host": "foo.bar",
"host": "bar.baz",
"user-agent": "browser"
}
},
"res": {
"status_code": 200,
"content-type": "text",
"content-encoding": "plain"
}
}
}
mlr --json --from data/server-log.json put -q '
'
bar.baz
bar.baz

This also works on the left-hand sides of assignment statements:

mlr --json --from data/server-log.json put '
'
{
"hostname": "localhost",
"pid": 12345,
"req": {
"id": 6789,
"method": "GET",
"path": "api/check",
"host": "foo.bar",
"host": "UPDATED",
"user-agent": "browser"
}
},
"res": {
"status_code": 200,
"content-type": "text",
"content-encoding": "plain"
}
}
}

A few caveats:

• This is why . has higher precedece than + in the table above -- in Miller 5 and below, where . was only used for concatenation, it had the same precedence as +. So you can now do this:
mlr --json --from data/server-log.json put -q '
print \$req.id + \$res.status_code
'
6989
• However (awkwardly), if you want to use . for map-traversal as well as string-concatenation in the same statement, you'll need to insert parentheses, as the default associativity is left-to-right:
mlr --json --from data/server-log.json put -q '
print \$req.method . " -- " . \$req.path
'
(error)
mlr --json --from data/server-log.json put -q '
print (\$req.method) . " -- " . (\$req.path)
'
GET -- api/check