AuQL DSL Syntax¶
AuQL Script is the Domain Specific Language (DSL) for scripting the Aunsight platform. Internally, this language is parsed into a JSON object that is interpreted by Aunsight's script engine service, but the abstraction provided by the DSL makes it easier to read, write, and maintain scripts. Because AuQL scripts are interpreted before being evaluated by the script engine, AuQL is an abstraction or high-level language that provides a convenient wrapper around the requirements of the Script Engine service. The present article explains the basic syntax of the AuQL scripting language.
Basic Structure: Functions, Operations, and Outputs¶
All statements within an AuQL script are organized within functions. Every function requires three parts: a function declaration, zero or more operations, and an output in the form of a return()
statement.
Consider this very simplest of AuQL functions:
function main(){
my_string = str("Hello World!")
return(message = my_string)
}
When this script is executed, it will simply return the key/value pair message: "Hello World!"
.
Declaring a Function¶
A function is declared with the "function" keyword followed by the function name much as in JavaScript.
function main()
The Aunsight Script Engine begins execution by evaluating the first function declared in an AuQL script, which is conventionally named main()
. This main()
function can be thought of as the entry-point for script execution. User-defined functions can be written in separate function blocks after the main()
function and called from within the main()
function by calling it as a subscript.
Functions can be passed parameters by enclosing a list of function parameters within the parentheses that follow the function name. Parameters are indicated at the very minimum by a list of data type declarations which take the form of a name/value pair where the name is the name used to refer to that parameter within the function and the value is a data type declaration:
function main(first_name = str(), last_name = str(), age = int())
The function takes a first_name
and last_name
of the String
type, and an age
parameter of the Integer
type.
Valid parameter types are:
- String (String()
or str()
)
- Integer (Integer()
or int()
)
- Floating point number (Float
, float()
, Number()
, or num()
)
- Boolean (Boolean()
or bool()
)
- Array (Array()
)
- Object (Object()
)
Parameters may specify a default value by enclosing it within the parentheses: int(100)
or str("Hello World!")
.
Comments and Docstring¶
There are two type of comments: single-line and multiline. Single-line
comments start with #
or //
and end with a newline character. In
contrast, a multiline comment or comment block starts with /*
and ends
with */
.
/*
This is a comment block.
It can span multiple lines and be placed anywhere in the script.
*/
function main(){
# this is a one-line comment. It terminates with a newline character.
number = int(30)
// Here is another comment
return(value = number)
}
Also, Docstring style comments can also be placed directly before the function definition within triple quotes:
""" Simple AuQL script always returns result = True"""
function main(){
# Nothing to do; returning True
result = bool(1)
return(value = result) # Return "True"
}
Expressions¶
Immediately following a function declaration, AuQL requires a pair of curly braces ({ }
) to delimit the function. Everything within these braces that is not a comment is interpreted as an expression.
At its simplest, an expression can be the assignment of a literal value to the name of a variable as in the following examples that create an array variable from a literal array and a string from a literal string: my_array = [1,2,3,4]
; message = "Hello World!"
function main(){
data0 = [1,2,3,4]
sum = Math.Sum(data0)
return(total = sum)
}
Because AuQL expressions are ultimately translated into a graph of functions, all expressions must involve an assignment from either a literal value or the name of a function that produces some output. E.g. sum = Math.Add(2, 2)
or message = String.Join("Hello ", "World!")
.
Note
AuQL scripts describe a graph of functions whose inputs and outputs are connected together. Assignments in AuQL are a syntactical way of representing these relations between the results of one function and the inputs of another in a graph of operations, (e.g. the output "variable" from one function is connected as input for another function). This is not dissimilar to how shell scripts connect the input and output of shell commands by means of "pipes".
AuQL provides a large number of built-in functions to provide both basic operations (E.g. arithmetic, string manipulation, and binary operators) and a way of interacting with the Aunsight platform and its resources. However, script creators can also define their own functions and invoke them as subscripts from within the script's main()
function or Promises in Javascript connect the future value of a function to that variable.
Most functions require arguments to be passed to them when making a call. Function arguments can be:
- Named Arguments (e.g.
sum = Math.Add(left = 2, right = 4)
) - Positional Arguments (e.g.
sum = Math.Add(2, 4)
)
Arguments can be of any AuQL datatype (strings, integers, floats, boolean, arrays, objects, and functions). Passing functions can be done by means of the function object returned by Util.Function()
which takes the function ID (the name of the function as a string) and returns the function of that name.
Script Output¶
Every function must end with a return statement. Multiple keys/values can be returned using different names for the keys. Functions can return values of any datatype.
function main(){
sum1 = Math.Add(1, 2)
sum2 = Math.Add(3, 4)
return(value1 = sum1, value2 = sum2)
}
Subscripts¶
Subscripts are user define inside an AuQL Script that can be called by the main()
function. A function is imported to another
function using Util.Invoke
with the name of the function as its argument. Modularizing code in this way provides flexibility and allows for greater organization when writing large scripts.
result = Util.Invoke("my_custom_function", {"argument1": "value1", "Argument2": "value2"})
.
Note
Util.Invoke
takes a String ID as its argument; the actual function object refered to by the ID is not passed as an argument.
Some functions take as a function object as a datatype for one or more of their arguments (as is common in Javascript). In this case, the Util.Function
function will return an AuQL function object refered to by the ID (string) passed to it as an argument. Consider the following example:
function main(){
input = Array([1,2,3,4,5])
mapper = Util.Function("mapper")
mapped = Util.MapArray(input, mapper)
return(mapped = mapped)
}
function mapper(value = int()){
product = Math.Multiply(2, value)
return(value = product)
}
Because the Util.MapArray
function requires a function as an argument, this script first looks up the function by ID using the Util.Function
function and assigns it to the mapper
variable. This variable is then passed as the second argument to Util.MapArray. It is also possible, but less readable, to write this as a one-liner:
mapped = Util.MapArray(input, Util.Function(str("mapper")))
The second function in this script defines the actual mapper function used by Util.MapArray()
. In this case, the user-defined function mapper()
takes an input value
variable, multiplies it by 2, and returns the result.
Warning
Although main()
functions can return any number of key/value pairs, subscripts must always return a single variable which must be called value
. If you need to pass more complex data back to the calling function, it is possible to pass an Object
datatype as the value of value
and subsequently unpack the results in the main()
function.