
=========
Modifiers
=========

Nonstraightforward has modifiers for declarations. They have a
specific order that is shown below. Any of these modifiers can be omitted.

.. code-block:: text
    :caption: modifier orders

    visibility stability mutability rw-perms

####################
Visibility modifiers
####################

Visibility modifiers are just ``private`` and ``public``. By default if no
visibility specifier is specified, then functions/subroutines, variables, and
classifications are private while class components and methods are public.

If ``public`` is specified for declarations outside a classification body, then
``nondefault``/``default`` can be specified as well. ``default`` makes the item
into a default export (I think one that can be imported without braces, like
``import defaultExport from "./module.js";``) ``nondefault`` is implicit.

###################
Stability modifiers
###################

.. code-block:: text
    :caption: The stability modifiers, ordered from most to least stable.

    stable
    unstable
    volatile
    hazardous
    biohazard
    radioactive

The default stability modifier is ``stable``. Currently, these serve no purpose
aside from maybe signaling to the programmer to not use a function or variable.


########################
Mutablility and RW-perms
########################

The mutability modifiers are ``mutable`` and ``immutable``, with ``mutable``
being the default. They refer to the ``const``-ness of a declaration, so it only
has an effect on variable declarations where it makes a variable ``const``.

The Read/write permissions modifiers are ``readonly``, ``readwrite``, and
``writeonly``, where ``readwrite`` is the default. They refer to the
**mutability of the value**. ``readonly`` calls ``Object.freeze`` on the value
of the declaration, so the value it holds cannot be modified.

``immutable readwrite constant`` and ``mutable readonly variable``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. code-block:: text

    mutable readonly variable x = { message: "Hello, world!" };
    x.message = "Goodbye, world!";  // the value of x is unchanged
    console.log(x);                 // { message: "Hello, world!" }
    x = { message: "1 == -1" };
    console.log(x);                 // { message: "1 == -1" }

In the example above, ``x`` is mutable and readonly. Since ``x``'s value is
frozen by ``readonly``, modifying its value does not work. However, ``x`` is
a mutable reference so changing the reference itself works.

.. code-block:: text

    immutable readwrite constant x = { a: 3, b: 6 };
    // x = { message: '"Hello, world!" is so generic...' }; // this would throw a runtime error
    console.log(x);                 // { a: 3, b: 6 }
    x.a = -3;
    console.log(x);                 // { a: -3, b: 6 }

Likewise, in the example above ``x`` is ``const`` but the value is mutable.
In JavaScript, ``const`` is a constant reference to a value, so modifying the
reference is an error, but modifying the value itself works.
