Language Reference¶
The syntax and grammar is a mix of Bash and Python. It relies on pipes to pass strings between commands. Statements are mainly separated by whitespace and semicolons.
There are build-in methods and user-defined functions. Methods such as print
are bound to methods with the name do_print
. Functions can be either one-liners or multiline functions.
For examples, see src.lib.math.sh. The AST can be found here.
[toc]
By Type¶
Standard Expressions¶
Example |
Description |
---|---|
|
Run the method |
|
Print separated arguments on new lines. |
|
Run multiple methods. |
|
Pipe the output of one expression to another expression. |
Conditions and Branches¶
Example |
Description |
---|---|
|
Run a command conditionally. |
|
Conditional variable assignment |
|
Nested if-then-else statement |
Multiline if-then-else statement
if 10 < 1 then
if 5 < 1 then
print a
else if 1 < 1
print b
else
print c
Maps and Loops¶
Example |
Description |
---|---|
|
Run a command for each line of the output of the previous expression. |
|
Insert each line of the previous output into a new expression. |
|
|
|
Iterate over a directory. |
Shell Interop¶
Commands can be chained, similar to Bash. The main output stdout
is used.
Example |
Description |
---|---|
|
Invoke a system shell and run |
|
Pipe the output of |
|
Write the output of an expression to a file |
|
Append the output of an expression to a file |
Environment Variables¶
The operator =
is used for variable assignment. The operator <-
is used for post-evaluation assignment (borrowed from R). $
-referenced variables are expanded immediately, prior to function invocation.
Example |
Description |
---|---|
|
Assign the value |
|
Assign the values |
|
Assign the result of the left-hand-side expression to the variable |
|
Assign the result of the right-hand-side expression to the variable |
|
Pass the values of the variables |
Environments¶
An environment is a key-value map.
Command |
Description |
---|---|
|
Show all environment variables. |
|
Copy the current environment to a file. |
|
Reload the default environment. |
Globbing¶
Example |
Description |
---|---|
|
|
|
|
|
Create a range. |
Functions¶
Inline Functions¶
Example |
Description |
---|---|
|
Identity function. Echo the input. |
|
Repeat a term. |
|
Arithmetic. |
|
Combine positional arguments with environment variables. |
|
A function that iterates over a loop. |
|
Aggregate a sequence using a reduction operator. |
Multiline Functions¶
Using the return
keyword.
b = 10 # a global variable
f (x):
# a magic formula
x <- math $x * 3 # a local variable
if x > 2:
return $x
return math 2 * $x + $b
# call the function with argument '10'
f 10
Built-in Commands¶
Command |
Description |
---|---|
|
Show info. |
|
Show the usage of the command |
|
Show details of the last error message. |
|
Return the input. |
|
Print the words |
|
Print the words |
|
Evaluate math expressions. |
Symbol Reference¶
Variable assignment
=
->
<-
$
Function definition
function_name ( ):
Globbing
*
?
{
}
Pipes (Bash)
|
>-
>>
Pipes (Python)
|>
>>=
Comparison Operators
==
!=
>
<
Keywords¶
if
then
else
return
Built-in Functions¶
Logical operators: and
or
not
Other operators: map
math
foreach
Proposals¶
Proposals for future changes.
Predicate logic
a and b => not c
x > 1 for all x in X
x + y == 1 for any x in X, y in Y
Basic Functions
Inf loop: f x = f x |> repeat x
TODO: Decide on whether states should be mutable or immutable.
Unpack sequences
Proposal: Never expand LHS *
symbols.
a b = println 10 20
print a # 10
a *b = {1..10} # a = 1, b = 2-10
Alternative syntax:
head x @xs = x
tail x @xs = xs
end @xs x = x
TODO: Decide on whether to support lazy evaluation
Math
Numbers: int 1
, float 1.0
Shorthand notation: a = $100.0
, b = $2e3
, c = $2^2
Performance & Parallelization
Benefit
Simplicity of Python and performance of Haskell and Erlang
# inf streams
a *b = list_natural_numbers
# pure functions can be executed in parallel, using a thread pool
range 10 >>= math 10 * $ + 1 |> reduce sum
Queries¶
Show tabular data¶
“Show the users”
- SELECT * FROM users
+ show users
| | email | name |
|-----:|:-------------------|:-------|
| 1000 | name.0@company.com | name_0 |
| 1001 | name.1@company.com | name_1 |
| 1002 | name.2@company.com | name_2 |
Inner join¶
“Find users that own a at least one document”
- SELECT name FROM users INNER JOIN documents ON users.id == document.owner
+ {users | users.id in {documents.owner}} >>= show $1.name
“Show documents of each user”
- SELECT users.name, documents.name FROM users LEFT JOIN documents ON users.id == document.owner
+ { users documents | users.id = documents.owner } >>= show $1.email $2.name
Note the similarity to ranges
{1..3}
1 2 3