Syntax
Basic syntax of flow

Basic Syntax of Flow

Basics of Flow

In Flow, you use -> to describe a unidirectional flow.

a -> b -> c -> d

Example:

> "Hello, world!" -> output
Hello, world!
Hello, world!.

Items connected by -> are called nodes. In a -> b, a is called the upstream node, and b is the downstream node. Here, "Hello, world!" is the upstream node, and output is the downstream node.

The "Hello, world!" node continuously sends the string Hello, world! to the downstream node. The output node displays the data received from the upstream node on the screen.

When data is displayed, the program waits for user input. If Enter is pressed without typing anything, the program resumes, and the next "Hello, world!" is displayed again. If the user types something (e.g., .) and presses Enter, the program stops.

Multiple Outputs

By using parentheses, you can specify multiple outputs from a single node.

a (-> b) (-> c)

Example:

> 1 -> copy (-> output) (-> + 1 -> output)
1
2
1
2.

The copy node can have multiple outputs and sends the data from its upstream node to all downstream nodes. One output connects directly to an output node, while the other connects to + 1 (more on + 1 later).

Since the 1 node continuously sends the value 1 to the copy node, both 1 and 2 are output repeatedly.

Advanced: Parentheses Usage

In Flow, a -> b -> c is interpreted as a (-> b (-> c)). In other words:

"Hello, world!" -> output

is equivalent to

"Hello, world!" (-> output)

and

1 -> copy (-> output) (-> + 1 -> output)

is equivalent to

1 (-> copy (-> output) (-> + 1 (-> output)))

Multiple Inputs

Nodes can also handle multiple inputs.

(a ->) (b ->) c

Example:

> (1 ->) (2 ->) + -> output
3
3.

The + node receives multiple inputs from upstream nodes and sends the sum downstream.

The + node supports a variable number of inputs:

> (1 ->) (2 ->) (3 ->) + -> output
6.
> (1 ->) + -> output
1.

Advanced: Input or Output?

The program "Hello, world!" -> output can be interpreted as either "output receives the output of "Hello, world!"" or ""Hello, world!" is the input of output." As mentioned earlier, Flow interprets "Hello, world!" -> output as "Hello, world!" (-> output), so "output receives the output of "Hello, world!"" is the more syntactically faithful expression.

However, the following produces the same result:

> ("Hello, world!" ->) output
Hello, world!.

Syntactically different, but semantically equivalent (they are the same in Flow's intermediate representation).

Named Outputs and Inputs

You can explicitly name inputs and outputs. For example, consider the following program. The - node takes two inputs and subtracts them.

> (5 ->) (3 ->) - -> output
2.

Here, 5 is the first argument, and 3 is the second argument.

You can name an input by specifying ->:name:

> (5 ->:arg1) (3 ->:arg0) - -> output
-2.

Similarly, you can name an output using name:-> (this will be shown later in the if section).

In fact, all inputs and outputs in Flow have names. If omitted, the system infers the names automatically.

Overall, the structure looks like this. [ ... ] indicates optional parts:

(... ->[:input1]) ... (... ->[:inputn]) node ([output1:]-> ...) ... ([outputn:]->...)

Conditional Branching: Just Multiple Outputs of a Node

In Flow, conditional branching is handled using the if node. The if node sends data to the then output if the upstream value is True (and nothing to else), and to else otherwise.

> 1 == 1 -> if (then:-> "True!" -> output) (else:-> "False!" -> output)
True!.
terminated
> 1 == 0 -> if (then:-> "True!" -> output) (else:-> "False!" -> output)
False!.
terminated

We haven't explained nodes like "True!" and "False!".
These nodes have an upstream and are called passive immediates. Unlike nodes without upstream (like "Hello, world!" -> output) which always send values downstream, passive immediates only send their value downstream when they receive an upstream input.

In Flow, control structures like this are treated just as nodes.
When a node has multiple outputs, it does not necessarily send data to all outputs each time it receives an input. Generally, nodes have inputs and outputs, but they do not always behave like functions or multivalued functions.

Note: Omitting Names in if Nodes

Earlier, we mentioned that names are inferred if omitted. The same applies to if nodes, so you can omit then: and else::

> 1 == 1 -> if (-> "True!" -> output) (-> "False!" -> output)
True!.

In the interpreter, then is inferred preferentially.

However, omitting names can sometimes reduce code readability, so this is not recommended.