Pipes are channels used to pass values from one function to another. Also pipes can be used to transfer data between threads. Pipes work as a FIFO queue. Pipe can pass any type, including functions and other pipes.

Declaring the pipe

Pipes can be declared in a next way:

var p1 := pipe(int);                       # pipe of ints
var p2 := pipe(struct(a: int, b: float));  # pipe of structs

There are no way to declare pipe as const or set it default value.


To to check are there any data in the pipe unary operation @. Works in the same way as lists but returns bool value. If result is true then pipe is not empty.

if (@pipe)
    # there is smth in pipe

Also pipes can be compared with = and <> operations. Pipes are equal when it is the same pipe.

var p1: pipe(int);
var p2: pipe(int);
log p1 = p2;            # returns false, pipes are different
p1 := p2;               
log p1 = p2;            # returns true, p2 is now p1

Working with pipes

To work with pipes there is an operation ~. It can be used as prefix or as a suffix. Depends on what we want to do.

Pushing values to the pipe

To push value to pipe place ~ operator after pipe.

var p: pipe(int);
p~ := 5;           # add 5 to pipe

This operations creates new default value depending on pipe type, pushes it to pipe and returns, so new value can be assigned.

log p~             # 0 will be logged and added to pipe

Popping values from pipe

To pop value from pipe place ~ before pipe. If the pipe is empty, exception will be thrown

var p: pipe(string);
p~ := "foo";
p~ := "bar";
log ~p;           # bar is printed
log ~p;           # foo is printed
log ~p;           # exception is thrown, values left in pipe