This is the draft release notes for 0.17.0, scheduled to be released on
2022-01-01.

# Breaking changes

-   Attempting to assign to a read-only variable (e.g. `set nil = x`) is now a
    compile-time error rather than an exception.

# Deprecated features

Deprecated features will be removed in 0.18.0.

The following deprecated features trigger a warning whenever the code is parsed
or compiled, even if it is not executed:

-   The `dir-history` command is deprecated. Use `store:dirs` instead.

-   The legacy assignment form is deprecated. Depending on whether the left-hand
    variable already exists or not, use `var` or `set` instead. Use the
    [upgrader](https://go.elv.sh/u0.17) to migrate scripts.

-   The lambda syntax that declares arguments and options within `[]` before `{`
    has been deprecated. The new syntax now declares arguments and options
    within a pair of `|`, after `{`. Use the [upgrader](https://go.elv.sh/u0.17)
    to migrate scripts. See ([#664](https://b.elv.sh/664)).

-   Use of the special namespace `local:` is deprecated.

    -   If you are using `local:` to reference variables (e.g. `echo $local:x`),
        `local:` is never necessary in the first place since Elvish always
        resolves local variables first, so just remove it.

    -   If you are using `local:` when assigning variables (e.g.
        `local:x = foo`), `local:` makes sure that a new variable is created;
        use the `var` special command instead.

-   Use of the special namespace `up:` is deprecated.

    -   If you are using `up:` to access a non-shadowed variable in an outer
        scope, `up:` is not necessary; just remove it.

    -   If you are using `up:` to access a shadowed variable in an outer scope,
        rename the variables to have different names.

-   Use of a leading empty namespace in a variable name (e.g. `$:x`) is
    deprecated. Since `$:x` is always equivalent to `$x` anyway, just remove the
    `:` prefix.

# Notable new features

New features in the language:

-   A new special command `pragma`. The only supported pragma now is
    `unknown command`; using `pragma unknown command = disallow` turns off the
    default behavior of treating unknown commands as external commands.

-   A new special command `coalesce`.

New features in the interactive editor:

-   Editor modes now form a stack, instead of being mutually exclusive. For
    example, it is now possible to start a minibuf mode within a completion
    mode, and vice versa.

New features in the standard library:

-   The `store:` module now exposes all functionalities of Elvish's persistent
    store.

-   New `compare` command to compare numbers, strings, and lists
    ([#1347](https://b.elv.sh/1347)), in a consistent way as the `order`
    builtin.

Performance improvements:

-   The overhead of executing pipelines consisting of a single form (i.e. a
    simple command with no pipes) has been reduced. A code chunk containing just
    `nop` command now executes 4 times as fast as before. Thanks to kolbycrouch
    for suggesting this optimization!
