- Import a module:
queue = import("/core/std/queue")(you can also import from external sources like GitHub). - Primitive types:
int,float,char,string,byte,bool,error,type,nothing. - Bindings:
my_var:int = 19(type is optional, everything is immutable). - Sequence:
my_array = [1, 2, 3](type ofmy_arrayis[int]which means a sequence of integers). - HashMap:
my_map = ["A":1, "B":2, "C":3](type ofmy_mapis[string:int], which is a map of string to integer) - Named type:
MyInt = int(Defines a new typeMyIntwith same binary representation asint). - Type alias:
IntType : int(A different name for the same type). - Struct type:
Point = struct{x: int, y:int, data: float}(Like Cstruct). - Struct literal:
location = Point{x:10, y:20, data:1.19}. - Union type:
MaybeInt = int | nothing(Can store either of two types, note that this is a named type). - Function:
calculate = fn(x:int, y:int -> float) { x/y }(Functions are all lambdas, the last expression in the body is return value). - Concurrency:
my_data := processData(x,y,z)(Start a new micro-thread and evaluate an expression in parallel). - Generic Types:
ValueKeeper = fn(T: type -> type) { struct{data: T} }(Generic types are represented using functions that returns a type) - Generic Functions:
push = fn(x: T, stack: Stack(T), T: type -> Stack(T)) { ... } - Enum:
Weekdays = enum [monday, tuesday, wednesday, thursday, friday] - Errors:
result = validateData(a,b,c)@{makeError(InvalidArgument)}(If call to validateData returns an error, then evaluate the expression inside brackets and return the result immediately).
#Comment.Access struct members (customer.name)()Function declaration and call (process(customer)){}Code block, multiple selections from module namespace, error check, struct declaration and literals[]Sequence and hashMap (data=map["CA"])|Union data type (x:int|float|string)->Function declaration (process = fn(...->...))//Nothing-check operator (result=a//bevaluates to a if it is notnothing,else b):Type declaration (binding, struct field and function inputs), type alias, struct literal (x:int)=Binding declaration, named type (x=12)_Place-holder (lambda creator and assignment) (partial = process(customer,_,_)::Function call composition (result = id :: findCustomer :: printCustomer)@Error check (data = process@)?If operator (x=data==10 ? "A"if data is 10, then x will be "A" otherwisenothing)&Type inference for struct literals (When type can be inferred from context:&{x:0,y:20}):=Parallel execution..Access inside module (data = module1..func1(1,2,3))
Primitive data types: int, float, char, byte, bool, string, nothing, type,error
Logical Operators: and, or, not
Data type identifiers: fn, struct, enum
Reserved identifiers: true, false, import
- Use 4 spaces indentation.
- You must put each statement on a separate line. Newline is the statement separator.
- Naming:
SomeDataType,someFunction,some_data_binding,some_module_alias. - If a function returns a type (generic types) it should be named like a type.
- If a binding is a reference to a function, it should be named like a function.
- You can use
0xprefix for hexadecimal numbers and0bfor binary. - You can use
_as digit separator in number literals.
Operators are mostly similar to C language:
-
Conditional operators:
and, or, not, ==, !=, >=, <= -
Arithmetic:
+, -, *, /, %, %%, >>, <<, ** -
Note that
==will do a comparison based on contents of its operands. -
A // Bwill evaluate to A if it is notnothing, else it will be evaluated to B (e.g.y = x // y // z // 0). -
A ? Bwill evaluate boolean expression A first, if true will evaluate to B, otherwise will evaluate tonothing. This can be mixed with//to provide ifElse construct. -
Example:
home_dir = (is_root ? "/root") // (is_default_user ? "/default") // (is_unknown ? "unknown") // "/tmp" -
Conditional operators return
trueorfalsewhich are equal to1and0respectively when used as index of a sequence. -
Comments can appear anywhere in the code and start with
#. Anything after#till end of the line is comment. -
Meta comments start with
##as first two characters of the line and can be defined for a binding, type or function. These will be scanned with tools to automatically generate documentation. If##is the only thing in the line, it starts a block comment until another##appears in the file.## some docs about this function x:int - comments about this input -> string - comments about the output ## process = fn(x:int -> string) { ... } ##Meta comment in one line x = 12 ## some docs about this type x:int - comments about this field y: string - comments about the y ## DataTypeX = struct {x:int, y:string}