miller/docs/src/reference-dsl-operators.md
John Kerl e0ed7e469c
Publish an epub of the docs on Read the Docs (#1835) (#2166)
* Publish an epub of the docs on Read the Docs (#1835)

Read the Docs' built-in formats support (the existing formats: all in
.readthedocs.yaml) only produces epub/PDF for Sphinx projects, and is a
silent no-op for MkDocs ones. Instead, per RTD's documented
build-customization path, generate the epub ourselves in a post_build
job and place it in $READTHEDOCS_OUTPUT/epub/, which RTD then publishes
on the project Downloads page and in the docs flyout menu.

The epub itself is built by the new docs/build-epub.sh: it takes the
committed, generated Markdown pages in docs/src in mkdocs.yml nav
order, strips the HTML-only quicklinks header from each page, and runs
pandoc (installed on RTD via build.apt_packages). Locally, `make -C
docs epub` does the same for anyone with pandoc installed; nothing here
is part of `make dev` or any default build path.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix misrender

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 14:55:36 -04:00

5.9 KiB

Quick links:   Flags   Verbs   Functions   Glossary   Release docs
# DSL operators

Detailed listing

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

Operator precedence

Operators are listed in order of decreasing precedence, from highest to lowest.

Operators Associativity
() {} [] left to right
** right to left
??? left to right
?? left to right
! ~ unary+ unary- right to left
. 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
`
? : right to left
= N/A for Miller (there is no $a=$b=$c)

See also the section on parsing and operator precedence in the REPL for information on how to examine operator precedence interactively.

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, AND, and XOR 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 an 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",
    "headers": {
      "host": "bar.baz",
      "user-agent": "browser"
    }
  },
  "res": {
    "status_code": 200,
    "header": {
      "content-type": "text",
      "content-encoding": "plain"
    }
  }
}
mlr --json --from data/server-log.json put -q '
  print $req["headers"]["host"];
  print $req.headers.host;
'
bar.baz
bar.baz

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

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

A few caveats:

  • This is why . has higher precedence 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