Control flow ************ The unique power of Comefrom0x10 arises from its approach to control flow. It has only one control flow construct, the ``comefrom`` statement. Control flow jumps to wherever you place a comefrom statement: +------------------------------------------------+------------------------------------------------+ | Program | Output | +================================================+================================================+ | :: | .. code-block:: none | | | | | 1 | 1 | | | 3 | | 2 | | | comefrom | | | 3 | | | | | +------------------------------------------------+------------------------------------------------+ As previously seen, Cf0x10 is designed on the principle that *all* your code matters, including blank lines. Think of a blank line as a yield point, where the program is allowed to jump to an eligible ``comefrom``. If more than one is eligible, it jumps to the last: +------------------------------------------------+------------------------------------------------+ | Program | Output | +================================================+================================================+ | :: | .. code-block:: none | | | | | 1 | 1 | | | 4 | | 2 | | | comefrom | | | 3 | | | comefrom | | | 4 | | | | | +------------------------------------------------+------------------------------------------------+ Conditionals ============ Comefrom statements may optionally include an ``if`` condition. Conditionals are more specific than bare ``comefrom`` statements, so they supercede the last-wins rule shown above (remember than non-zero numbers are truthy): +------------------------------------------------+------------------------------------------------+ | Program | Output | +================================================+================================================+ | :: | .. code-block:: none | | | | | 1 | 1 | | | 3 | | 2 | 4 | | comefrom if 1 | | | 3 | | | comefrom | | | 4 | | | | | +------------------------------------------------+------------------------------------------------+ Another distinction of ``comefrom if`` is that jumps are eligible when a variable changes; that is, consider assignments to be yield points. +------------------------------------------------+------------------------------------------------+ | Program | Output | +================================================+================================================+ | :: | .. code-block:: none | | | | | foo = 'truthy' | 2 | | 1 | | | comefrom if foo | | | 2 | | | | | +------------------------------------------------+------------------------------------------------+ .. hint:: It may help to understand this as analogous to "pub-sub" frameworks. You can think of an assignment like ``foo = 1`` as publishing a "foo changed" event and ``comefrom if foo`` as subscribing to the "foo changed" event. Most languages require libraries to achieve this kind of action at a distance, but Comefrom0x10 builds it right in. Assignments only cause jumps to conditional comefroms that refer to the variable being changed. This is handy to avoid infinite loops in many situations, for example:: comefrom if x 'x is ' x x = 'foo' The first time ``x = foo`` runs, ``x`` changes from ``undefined`` to "foo". The second time, however, ``x`` does not change, so the assignment does not trigger a jump back to the first line. This program outputs:: x is x is foo Recall that string concatenation coerces ``undefined`` to the empty string. Of course, assignment never jumps to an unconditional comefrom. Loops ===== Thanks to the incredible power of ``comefrom``, Cf0x10 needs no loop keywords at all: +------------------------------------------------+------------------------------------------------+ | Program | Output | +================================================+================================================+ | :: | .. code-block:: none | | | | | comefrom if i < 4 | 1 | | i | 2 | | i = i + 1 | 3 | | | | +------------------------------------------------+------------------------------------------------+