A minimal but powerful programming language based on C, Go and Haskell
type
. Bindings of this value (which should be named like a type), can have any possible “type” as their value.type
must have a compile time literal value.type
arguments and return a type
.type
must be) (Example A).T|U
means caller can provide a union binding which has at least two options for the type, it may have 2 or more allowed types.type
arguments but their output is not type
(Example B).Examples
#A
LinkedList = fn(T: type -> type)
{
Node = struct (
data: T,
next: Node|nothing
)
Node|nothing
}
process = fn(x: LinkedList(int) -> int)
process = fn(T: type, ll: LinkedList(T) -> ...
process = (T: type, data: List(T) -> float) ...
#type of pointer is fn(int, List(int)->float)
pointer = process(int, _)
process = fn(T: type, x: [T], index: int -> T) { x[index] }
#B
push = fn(data: T, stack: Stack(T), T: type -> Stack(T)) {...}
result = push(int_var, int_stack)
.
or ..
it is a relative path (Example A), if it start with /
it is based on project root (Example B)...
notation to access definitons inside module...{}
notation to only access some of module’s symbols (Examples C and D).@
notation to indicate required tag or branch name. This part allows using +
and *
to indicate versions equal or higher to x or any version are acceptable (Example E).Syntax
ModuleName = import("/path/to/module")
Examples
#A
Socket = import("../core/st/socket")
#B
Socket = import("/core/st/socket")
base_cassandra = "/path/to/cassandra"
#you can use a string literals expression for import path
Module = import(base_cassandra + "/path/module")
Set = import("/core/set")..SetType
process = fn(x: Set -> int) { ... }
my_customer = import("/data/customer")..Customer(name:"mahdi", id:112)
#E
T = import("/https/github.com/uber/web/@v1.9+.*/request/parser")
T = import("/https/github.com/uber/web/@new_branch/request/parser")
T = import("/https/server.com/web/@v1.9+.*.zip/request/parser")
#C
Set, process, my_data = import("/core/set")..{SetType, processFunc, my_data}
#D
Set, process, my_data = imported_module..{SetType, processFunc, my_data}
result := expression
notation will initiate a new parallel task (green thread) as a child of the current task. Any access to the result result
will block current process until the child is finished.select
are implemented as functions in std.Examples
_ := process(10, 20)
channel = createChannel(int, 10)
#pass channel to a task
int_result := process(10, channel)
#write data into the channel (blocks if channel is full)
channel.write(100)
#read data from channel (blocks if there is nothing to read)
data = channel.read()
error
with a binding of the same name representing a null-op error.error = struct (key: type|nothing, message: string|nothing, location: string|nothing, cause: error|nothing)
expression@
(return the error itself if expression evaluates to an error) or expression@{expression}
(return right-hand side expression in case of error in the left-hand side expression)error
runtime will automatically populate its cause
with original error.{}
will not be evaluated until the expression before @
evaluates to an error.Examples:
result = process(1,2)@ + process(3,4)@
result = process(1,2)@{nothing} + process(3,4)@{nothing}
data = validateInput(a,b)@{getDefaultReturnValue()}