Language reference

AUSTRA is a small functional language designed to handle financial series and common econometric models. It also implements vectors, matrices and the most frequently used operations from linear algebra, statistics, and probabilities.

AUSTRA formulas are efficiently parsed by a .NET Engine, and they are translated into fast-running native code that calls routines also implemented in .NET that take advantage of multicore systems and SIMD extensions.

This topic introduces the basic syntax of the language.

Lexical syntax

The lexical syntax of AUSTRA is very similar to most programming languages:

  • White space, including line returns, are completely ignored.
  • Identifiers and keywords are key insensitive.
  • Unicode characters are allowed in identifiers. So, yes: τ = 2*π is a valid expression. Of course, pi is also allowed, and the code editor helps while typing Greek characters.
  • Semicolons (;) are mandatory for separating statements, but not as statement terminators.

Numeric literals

Integer and real numbers are represented as in most programming languages. Here are some examples:

Austra
2023;
1.0;
-0.1E-16

Number literals can be suffixed with a lower-case i to represent an imaginary value:

Austra
2.0i;
-3i

The identifier i, by its own, represents the imaginary unit:

Austra
1-3i = 1 - 3 * i

Complex numbers can also be created using the complex function:

Austra
complex(1, -3) = 1 - 3 * i;
complex(3) = 3 + 0i

Since i is not a keyword, you must be careful because it can be redefined as a user variable.

Complex can also be built using the polar notation:

Austra
polar(1, pi/2) -- Another way to write the imaginary unit.

String literals

String literals are enclosed by double quotes and cannot cross line boundaries.

Austra
"A simple string literal";
"A string literal with a quote: ""Wow!"". That was the quote."

Date literals

Date literals come in two flavours. A simple literal only includes the month and year, assuming the first day of the month:

Austra
jan20;
jul2021

Two-digit years are first interpreted as a year inside the XXI century. If the resulting date is more than 20 years ahead, 100 years are subtracted to that date. For instance:

Austra
jan20; -- January 1st, 2020
may42  -- May 1st, 1942

A day can be added using this syntax:

Austra
6@jan20;
31@jul2021

Comments

Though we do not expect anyone to write hundreds of pages of AUSTRA script, we still support line comments for better documentation. Comments always starts with two consecutive hyphens and extends to the next line feed or the end of the expression, whatever comes first:

Austra
-- A verbose version of math::min()
if
aapl.mean < msft.mean then aapl.mean -- Another comment.
else
msft.mean

Root objects

Every AUSTRA expression must start with a root object. It could be either a global variable, a local variable, a class method, a class variable, or a code definition.

Global variables

Global variables come in two flavours: persistent variables and session variables. Persistent variables come mostly from an external source, like a JSON file, a database or an external service. In this AUSTRA version, those persisted variables are always time series, because they have a predictable serialization format. This design decision, of course, may change at some point of the evolution of the library.

For instance, when I open the AUSTRA application in my system, it automatically loads a set of series and definitions that are stored in a subfolder Austra of my Documents folder, in a file named data.austra, and its main windows looks something like this:

w 001

Persistent series are shown below a Series node. I can type the name of any of these variables in the Code Editor:

Austra
aaa

When I press F5, AUSTRA translates the expression and immediately shows the content of the aaa series:

w 002

Session variables

Session variables, as the name indicates, are defined inside a user session, and die with the session. They are defined and removed using the set statement:

Austra
set v1 = [1, 2, 3, 4, 5];
set v2 = v1.map(x => 1 / x);
v2.plot;
-- v1 is removed now:
set
v1; -- v2, however, persist for the rest of the session. v2.plot; -- More than one variable can be assigned in a single statement.
set
pi2 = 2 * pi, pi3 = 3 * pi

Only the value of the variable is stored, but not the formula that was used to calculate that value. This means, for example, that every use of the session variable will return the same value, even if the value was created using a random number generator:

Austra
-- v1 is created using random numbers:
set
v1 = vec::random(10); -- Every use of v1 returns always the same vector: v1 = v1; -- This is in contrast with the behavior of local variables.
let
v2 = vec::random(10); -- This expression will return false: v2 = v2

Local variables are explained here.

Session variables appears in the Variables panel, each one inside a node according to their types:

v 001

Class methods and class constants

Class methods in AUSTRA correspond both to constructors and static methods in traditional OOP languages, like C#.

Let's start with some variables:

Austra
i = math::i;
e = math::e;
pi = math::pi and pi = math::π

The same equivalence is valid for what we normally would consider "global functions":

Austra
exp(π*i);
math::exp(math::pi * math::i)

Those global functions and constants are considered as belonging to the math for avoiding problems if any of these symbols is redefined as a persistent or session variable.

Of course, there are more classes than math, and we can use their class methods for creating new objects:

Austra
matrix::random(10);
vec::new(10);
vec(10)

As the last example shows, when you call a new method on a class, you can omit the ::new part and use just the class name as synonym.

This convention applies to every data type handled by AUSTRA.

See Also