Language Syntax

Here we present the language syntax, from data types to the way expressions look like and function.

Current Data Types

There are some data types defined below:

  • bool

  • int

  • @array

Structure

Expressions

The most atomic part of the language is an expression. For instance, it can be a literal, a function, or a variable. Each expression interacts with the other through a special operator: the pipe :. It enables the data to pass from the left-side to the right-side expressions. A group of expressions can form single, sequential, concurrent, or parallel expressions related to scopes and data lifetime.

Scoping

The general structure of the language relies on function scopes. The outer scope is the main [1]. Besides that, scopes can be of four kinds: single, sequential, concurrent, and parallel. Single expressions are without branching; one expression receives an input, produces an output, and passes it to the following expression. Sequential scopes may have one or more expressions that will be executed in order, one after the other. It is given by the syntax sugar .[ ]. Concurrent scopes have the same properties as the sequential ones, but they execute each expression concurrently, prioritizing the written expression’s order. Its syntax sugar is .( ). Parallel scopes have their expressions executed in parallel. The syntax sugar is then .{ }.

Data Lifetime

Ordinary data can only survive one pipe operator. The expression gets it as input and produces a new output, whether it is identical data or not. However, variables live from their assignment until the end of the scope it was created; when it is the last expression in the scope, it will make part of the upper scope. This process guarantees no active garbage collector or user data management is needed. It was inspired by the Resource Acquisition Is Initialization (RAII) from C++.

Syntax Examples

.[1 1]:sum:print

One main single expression containing a sequential scope expression .[1 1] with two literal elements (a 2-element array), piped to the expression sum, piped to the expression print, resulting in a printed output 2 on the terminal.

.[5 10]:.(sum times):print

The sequential scope expression containing literal elements, piped to a concurrent scope expression containing two function elements, piped to the last expression. The result is a 2-element array printed on the terminal 15 50.

.[8 8]:.(sum:n times(n):m):print

Similar to the code above, now with variables n and m. times(n) waits for sum:n to be completed and then starts executing, due to its dependency on an expression-external resource (a variable in this case). The behavior of times(n) is slightly different from times. Now, n is multiplied by each array element that is piped to times(n), resulting on an array of the same length as the input. In this case, print will print a 3-element array, 16 64 64, with n storing 16 and m storing 64 64.