Skip to content

Latest commit

 

History

History
94 lines (76 loc) · 5.23 KB

File metadata and controls

94 lines (76 loc) · 5.23 KB

Overview

Main Features

  1. Import a module: queue = import("/core/std/queue") (you can also import from external sources like GitHub).
  2. Primitive types: int, float, char, string,byte, bool, error, type, nothing.
  3. Bindings: my_var:int = 19 (type is optional, everything is immutable).
  4. Sequence: my_array = [1, 2, 3] (type of my_array is [int] which means a sequence of integers).
  5. HashMap: my_map = ["A":1, "B":2, "C":3] (type of my_map is [string:int], which is a map of string to integer)
  6. Named type: MyInt = int (Defines a new type MyInt with same binary representation as int).
  7. Type alias: IntType : int (A different name for the same type).
  8. Struct type: Point = struct{x: int, y:int, data: float} (Like C struct).
  9. Struct literal: location = Point{x:10, y:20, data:1.19}.
  10. Union type: MaybeInt = int | nothing (Can store either of two types, note that this is a named type).
  11. Function: calculate = fn(x:int, y:int -> float) { x/y } (Functions are all lambdas, the last expression in the body is return value).
  12. Concurrency: my_data := processData(x,y,z) (Start a new micro-thread and evaluate an expression in parallel).
  13. Generic Types: ValueKeeper = fn(T: type -> type) { struct{data: T} } (Generic types are represented using functions that returns a type)
  14. Generic Functions: push = fn(x: T, stack: Stack(T), T: type -> Stack(T)) { ... }
  15. Enum: Weekdays = enum [monday, tuesday, wednesday, thursday, friday]
  16. 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).

Symbols

  1. # Comment
  2. . Access struct members (customer.name)
  3. () Function declaration and call (process(customer))
  4. {} Code block, multiple selections from module namespace, error check, struct declaration and literals
  5. [] Sequence and hashMap (data=map["CA"])
  6. | Union data type (x:int|float|string)
  7. -> Function declaration (process = fn(...->...))
  8. // Nothing-check operator (result=a//b evaluates to a if it is not nothing,else b)
  9. : Type declaration (binding, struct field and function inputs), type alias, struct literal (x:int)
  10. = Binding declaration, named type (x=12)
  11. _ Place-holder (lambda creator and assignment) (partial = process(customer,_,_)
  12. :: Function call composition (result = id :: findCustomer :: printCustomer)
  13. @ Error check (data = process@)
  14. ? If operator (x=data==10 ? "A" if data is 10, then x will be "A" otherwise nothing)
  15. & Type inference for struct literals (When type can be inferred from context: &{x:0,y:20})
  16. := Parallel execution
  17. .. Access inside module (data = module1..func1(1,2,3))

Reserved Keywords

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

Coding Style

  1. Use 4 spaces indentation.
  2. You must put each statement on a separate line. Newline is the statement separator.
  3. Naming: SomeDataType, someFunction, some_data_binding, some_module_alias.
  4. If a function returns a type (generic types) it should be named like a type.
  5. If a binding is a reference to a function, it should be named like a function.
  6. You can use 0x prefix for hexadecimal numbers and 0b for binary.
  7. You can use _ as digit separator in number literals.

Operators

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 // B will evaluate to A if it is not nothing, else it will be evaluated to B (e.g. y = x // y // z // 0).

  • A ? B will evaluate boolean expression A first, if true will evaluate to B, otherwise will evaluate to nothing. 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 true or false which are equal to 1 and 0 respectively 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}