The Basics
This section covers the fundamentals of Regle Query Language (ReQL).
Feature
Features in ReQL is created via a LET
statement.
LET <feature_name> = <expression>;
Features is what other programming languages typically refer to as variables.
Feature name must be capitalized in tw
.
Features in tw
is typed but you do not need type annotation except when dealing with functions that can return multiple types (see Type System to learn more)
LET StringLiteral = "Hello World";
LET RandomNumber = random();
Features are immutable once created. Feature names cannot be reused.
Function
Function names in ReQL is always camelcase and a function call is identified by round brackets - ex. random()
.
ReQL does not support user defined functions. Instead, ReQL provides a rich set of built-in functions (see Built-in Functions) to manipulate features.
Function calls in ReQL serve 2 broad purposes
1) Data transformation
- ex.
ipToCountry
takes an IP and returns the geo-located country string
2) Interacting with External Services
- ex.
getCount
returns the value from a counter database
Rule
Rule is created via RULE
statement with the following syntax
RULE <rule_name>
LABEL <token(s) separated by comma> AS <label>
WHERE <boolean_condition>;
RULE "example_rule"
LABEL FeatureA, FeatureB AS "example_label"
WHERE true;
Rule names and label can contain any lower case alphanumeric ASCII characters and "_" symbol.
If-Else Clauses
ReQL support conditionals through if and else clauses.
<expression> if <boolean_condition> else <expression>;
Else clause is optional, as demonstrated by the example below.
# flip a coin
LET CoinFlip = 1 if random() > 0.5 else 0;
# increase the counter "coin_flip" key under "namespace"
incCount("namespace", "coin_flip") if CoinFlip == 1;
List Comprehension
ReQL does not have loops. Instead, ReQL has list comprehension similar to python's list comprehension.
The general syntax is of the form
[ <expression with ITER> FOR Iter IN <array_feature> ]
LET OddNumbers = [1, 3, 5, 7, 9];
LET EvenNumbers = [Iter + 1 FOR Iter IN OddNumbers];
Input Statement
When designing package to share with others, you can optionally specify a list of features that your package depend on.
This is accomplished via INPUT
statement
OPTIONAL <feature_name> DOC "<doc_string>";
REQUIRE <feature_name> DOC "<doc_string>";
An input statement must have a DOC
clause describing the feature.
An optional input created with OPTIONAL ...
will have a default value of NULL
.
REQUIRE UserLoginIp DOC "User login IP";
OPTIONAL UserEmail DOC "User login email";
This example declares a package with two input features, one required and one optional.
Import Statement
You can use IMPORT
keyword to load other files or packages. Once a file or a package is imported, its features can be accessed via the dot operator .
.
IMPORT <package_or_file>
WITH <input1> = <expr>,
WITH <input2> = <expr>,
...
WITH <inputN> = <expr>
;
where package_or_file
is the location of the package and input1
, input2
etc. are used to specify the exposed input of a given package.
Importing downloaded packages
When downloading packages using regle
CLI tool, a folder called regle_pkg
is created in the root of the rule directory.
Suppose our directory setup looks like this
./example_package
├── main.tw
├── other.tw
├── regle_pkg
│ └── github.com
│ └── regle_std_lib
│ └── ato_package
│ └── main.tw
└── regle_pkg.json
You can import ato_package
package inside main.tw
via
IMPORT "regle_pkg/regle_std_lib/ato_package";
Importing other tw files
Other tw files can also be imported by referencing the filename without the .tw
extension
./example_package
├── main.tw
├── other.tw
└── regle_pkg.json
To import other.tw
inside main.tw
IMPORT "other";
# we can now access features defined inside other file
LET OtherFeatureX = other.FeatureX;