Skip to content

Commit

Permalink
docs/controllers: Explain many things, and add railroad.
Browse files Browse the repository at this point in the history
  • Loading branch information
MostAwesomeDude committed Dec 22, 2020
1 parent 8dd2678 commit 2f35249
Showing 1 changed file with 32 additions and 9 deletions.
41 changes: 32 additions & 9 deletions docs/source/controllers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -42,23 +42,46 @@ We see that controllers must be ``DeepFrozen``, and that each code block, which
we'll call a "lambda-block", corresponds to a ``.control/4`` call, with a
``.controlRun()`` to indicate the end of blocks.

.. syntax:: controller

Ap("Controller",
NonTerminal("identifier"),
OneOrMore(
Ap("params",
Brackets("(", SepBy(NonTerminal("expr"), ","), ")"),
Sigil("COMMAND", ZeroOrMore(NonTerminal("pattern")),
Brackets("{", NonTerminal("expr"), "}")))))

Control with Lambda-Blocks
--------------------------

The power of controllers is locked within the lambda-blocks. Each block is a
function which returns an ``[args, lambda]`` pair. The controller can choose
how many times it wants to call the block, and similarly, the block can return
new arguments every time it is called. Indeed, note above that ``cond()`` is
called every time its containing lambda-block is called.
The `.control/4` method takes a parsed bareword, called a *command*, and the
arities of the command's parameters and patterns, as well as a lambda-block.
Lambda-blocks are thunks which return ``[args :List, lambda]`` pairs. The
first arity indicates how many parameters will be evaluated, and thus how
large ``args`` is. The other arity indicates how many arguments ``lambda``
wants to receive.

What are the other arguments to ``.control(verb :Str, argCount :Int, paramCount
:Int, block)``? The control verb is the bare word preceding each block. The
argument count specifies how many arguments will be returned by the block.
Where are the parameters?
The power of controllers is locked within the lambda-blocks. As each block is
defined, the controller receives the corresponding command and interprets it.
Each block might be called multiple times, and can return a different
``lambda`` each time. Each call will re-evaluate the parameter expressions,
too. Indeed, note above that ``cond()`` is called every time its containing
lambda-block is called.

Let us imagine another hypothetical controller::

m (action) do x { f(x) }

In this situation, ``x`` is the one and only parameter, and so the controller
receives a parameter count of ``1``.

Lambda Refusal
--------------

A ``lambda`` might not like the arguments which it receives. While it could
throw an exception, it could also politely refuse by triggering an ejector. To
facilitate this, an extra parameter is implied by the compiler to exist
whenever the third argument of `.control/4` is non-zero. In those situations,
the controller should pass an ejector along with the other arguments, at the
end of the argument list.

0 comments on commit 2f35249

Please sign in to comment.