Introduction to Sircle
What is Sircle?
Sircle is a powerful DSL for defining tasks. It is in functional style, supporting first-class functions and currying.
Example
1 |
|
This will create a task with executable main.py
and arguments. It may be executed by the runner with something like
1 |
|
{ "base_model" -> "GCN" }
here, is the tag. It is used to identify the task, and is needed to aggregate and display task results.
The above Task
datatype consists of three elements,
- Executable, which is the actual computational task. In most cases it is a Python script.
- Arguments, which specify the argument passed to the executable.
- Tag, which identifies the task and helps experiment results handling.
Apart from the above constructor, we can also construct a Task
with two operators:
task1 >> task2
, which defines a task wheretasks1
is executed first, thentask2
.task1 || task2
, which defines a task wheretask1
andtask2
can be executed in paralell.
Sircle DSL is highly expressive for defining computational tasks. For a real-world example, considering the conifig
1 2 3 4 5 |
|
1 2 3 4 5 |
|
On the other hand, from the short example above, we can see some basic properties of Sircle.
A first glance at Sircle
Function application
The function application in Sircle follows the ML style, where brackets are omitted. In other words, instead of writing
1 |
|
1 |
|
On of the greatest benefits of such style is that it can integrate well with currying. For example, we can write
1 2 |
|
[2, 3, 4]
.
Name Binding
In sircle, we can use the def
keyword to bind a name. For example,
1 |
|
1 |
|
1 |
|
Actually, when we omit the type annotation in the binding, the type is assumed Any
, which will be consistent with any value types.
In Sircle source, name bindings can happen both at global level and in block expressions. For instance,
1 2 3 4 5 6 7 |
|
- Binding. Example:
def y = x + 1
. This will bind valuex + 1
to namey
and evaluate to the binded value. - Reassignment. Example:
y = 2 * y
. This will assign a new value2 * y
to the namey
and evaluate to the new value. - Eval. Example:
y
. This is simply a pure expression and will evaluate to a value.
The block expression will evaluate the effects one by one, with possibly modification to variable environments, and return the value of the last effect. This style is similar to Scala.
The global bindings, unlike bindings in the block expressions, are immutable.
The Mapping
Datatype
The expression
1 2 3 4 5 |
|
Mapping
value, which is similar to dict
in Python and something called map in other languages. It is a key-value mapping, with keys must being String
types. Mapping
s are used in Sircle to describe task arguments and tags.
It is possible to access the Mapping
values by
1 2 |
|
1 2 |
|
More details on datatypes will be discussed later.
Lambdas
The expression
1 |
|
1 |
|
Note that we can use annotations to specify the argument type. The above definition is mostly equivalent to the code in other programming languages:
Example
1 2 |
|
1 |
|
1 2 |
|
Generally, we can define a \(n\)-arg function with
1 |
|