Heterogeneous lists of values, represented as an opening square
bracket "[", followed by a series of comma-separated values,
ending with a closing square bracket "]".

The following escape sequences are recognised in a text string:

\n - newline

\r - carriage return

\t - horizontal tab

\\ - backslash

\" - double quote

\uxxxx - Unicode character from the basic multilingual
plane, encoded as four hexadecimal digits

\uxxxx\uxxxx - Unicode character from an astral plane,
as two hexadecimal-encoded UTF-16 surrogates

String interpolation

Strings support interpolation, so that you can dynamically
construct a string based on data in your configuration or the OS
environment.

If a string value contains the special sequence "$(foo)" (for
any name foo), then the name foo will be looked up in the
configuration data and its value substituted. If that name cannot
be found, it will be looked up in the OS environment.

For security reasons, it is an error for a string interpolation
fragment to contain a name that cannot be found in either the
current configuration or the environment.

To represent a single literal "$" character in a string, double
it: "$$".

Grouping directives

It is possible to group a number of directives together under a
single prefix:

my-group
{
a = 1
# groups support nesting
nested {
b = "yay!"
}
}

The name of a group is used as a prefix for the items in the
group. For instance, the value of "a" above can be retrieved
using lookup by supplying the name "my-group.a", and "b"
will be named "my-group.nested.b".

Importing files

To import the contents of another configuration file, use the
import directive.

import "$(HOME)/etc/myapp.cfg"

Absolute paths are imported as is. Relative paths are resolved with
respect to the file they are imported from. It is an error for an
import directive to name a file that does not exist, cannot be read,
or contains errors.

If an import appears inside a group, the group's naming prefix
will be applied to all of the names imported from the given
configuration file.

Look up a name in the given Config. If a binding exists, and
the value can be converted to the desired type, return the
converted value, otherwise throw a KeyError.

Notification of configuration changes

To more efficiently support an application's need to dynamically
reconfigure, a subsystem may ask to be notified when a
configuration property is changed as a result of a reload, using
the subscribe action.

Forcibly reload a Config. Throws an exception on error, such as
if files no longer exist or contain errors. If the provided Config is
a subconfig, this will reload the entire top-level configuration, not just
the local section.