Basic Types

Venus comes with built-in types like numbers, booleans, arrays, strings and dicts, and you can create your own type with the type statement. We'll introduce the built-in types first, which would cover most common tasks hopefully. And then you will see how to define your own type.

Numbers

Venus handles numbers similar to C/C++/D, but has some differences.

Venus has these number types with different bitwidth:

Type Alias Bit Width Desc
i8 byte 8 8 bit integer
i16 short 16 16 bit integer
i32 int 32 32 bit integer
i64 long 64 64 bit integer
u8 ubyte 8 8 bit unsigned integer
u16 ushort 16 16 bit unsigned integer
u32 uint 32 32 bit unsigned integer
u64 ulong 64 64 bit unsigned integer
f32 float 32 32 bit float number
f64 double 64 64 bit float number

Number literals

you can write numbers in the code so that the compiler gets its type directly:

val a = 123 // default type: int
val b uint = 123 // declare it is an uint
val c = 1000L // long integers tails with a capital 'L'
val d = 0x1F // hex numbers starts with '0x'
val big_number = 1_000_000_000 // for long numbers, you can add '_' anywhere to make it clearer
val e = 0b10001 // binary numbers starts with '0b'
val e1 = 0b_10001 // because '_' can be anywhere (but not '0_b'), you might want it after '0b' to make it more clear.

val f = 0.23 // default to doubles
val g = 12. // also double
val h = 0.9e12 // scientific
val i = 0.12f // floats

Type conversions

Implicit conversions are allowed only when there is no precision loss, otherwise you have to explicitly convert it.

val a short = 123 
val b int = a // OK, implicit conversion with no loss
val c byte = b // Error! Might lose precision

import std.conv  // explicit conversion functions are defined in std.conv module
val d byte = a.to!byte // OK, explicit conversion

Booleans

Boolean type has two values : true and false. In memory it is stored as one bit, with true==1 and false==0.

val a bool = true
val b bool = false
assert(bool.init == false) // default value of bool is false

Numbers can convert to boolean type implicitly because there would be no precision loss. Boolean can convert to number types with true => 1 and false => 0.

val a int = 100
val b bool = a // b is now true
val c int = 0
val d bool = c // c is now false
val e int = d // e is now 0
val f int = b // f is now 1, NOTE: not 100!

Arrays and other list-like containers

We use [ and ] to contain an array of objects:

val arr = [1, 2, 3, 4] // type: std.array[int]

for n in arr {
  print(n)
}
// output: 1, 2, 3, 4

Get an element in the array with the apply operator ()

val arr = [1, 2, 3, 4]
val e = arr(0) // e == 1, because array index starts with 0

val e = arr[0] // ERROR! unlike C or D, we don't support `[]` slice operator because it would conflict with other parts of the language

We also have a tuple type, quoted with '()' brackets:

val elems = (1, 2, 3, 4, 5) // type: std.tuple[int] which behaves very much like static array in C, but it is immutable.

for e in elems {
  print(e)
}

val arr array[int] = elems // tuple are implicitly convertable to array so you can use it just like it is an array.

val pair = (1, "b") // type: std.tuple[int, string]

val (c , d) = pair // c == 1, d == "b"; you can assign values with a tuple syntax to apply value one by one

val big = 10000
val small = 2

(big, small) = (small, big)  // swap without a temprary object

big, small = small, big // you can omit the brackets when there is no ambiguation (NOTE: need further check)

Strings and characters

Strings are acutally array of characters. Character is also a basic type, which has the same number of bits as a byte.

val c char = 'a' // 'a' is an ascii character, it's integer value is 97
val n uint = c // n == 97

// single line string literals are quoted with `"` or `'`
val  s string = "abc" // string is actually an array('a', 'b', 'c')
val  s1 string = 'xyz' // another way to quote strings, but are only used when using `"` is cumbersome because we have `"` in the string

val s2 string = "a\"b\"c" // `"` in the string content need to be escaped with `\"`
val s3 string = 'a"b"c' // here we use `'` to make things easier
val c2 = 'A' // type: char.  A character literal quoted with `'` is infered as char


// multiline line string literals are quoted with `"""`
val string t = """
    good morning
    sunshine!
    "quoting is also ok here"
"""

// for large text that may still contain `"""`, we also provide `[=[`, `]=]`, `[==[`, `]==]`, `[===[`, `]===]` and the like.
var string u = [=====[
    here """ is ok,
    and you rarely need to contain ]===] in a string, and if that really happens, you quote it with a longer one
]=====]

String template

We can embed objects into a string with string template. Object placeholders in a string template are defined as $name, or ${complex-expression}, for example:

val n = 5
val str = "n = $n" // s is "n = 5"

val s = "hello"
val str = "$s.length is ${s.length}" // s1 is "hello.length is 5"

Dictionary literal

Dictionary is called Associated Array, Map, dict or table in other languages. It is a container that maps keys to values that we can lookup with efficiency. In Venus, a dictionary is called a dict for simplicity, just like in Python. We don't call it a map because it would conflict with the functional operator map (as in Map/Reduce).

Venus comes with two types of dict:

  • hash dict: use a hash to store data, its pairs order are not defined.
  • tree dict: use an internal tree to store data, the key/value pairs are sorted by key. Tree dict is usually slower than hash dict.

dict literals are in the form of { key : value }

// dict literals default to hash dict
val ages dict = {
    "Ann" : 12,
    Ben : 20, // for symplicity, string keys can omit the `"` quote if it has no white space.
    Colt : "hello", // leaving a ',' at the last pair is not an error because this will make it very easy to modify dict literals
}

Because all the keys are of type string, and values are of type int and string, the inferre type is dict[string, any]

// You can also specify the type of the dict
var scores = tree {
    15 : "low",
    60 : "ok",
    98 : "good"
}

// or even with the types of elements
var ids = hash[int, string] {
    1 : "Ann",
    2 : "Ben",
    3 : "Colt"
}

The apply operator () is used to look an item up:

var ids = hash[int, string] {
    1 : "Ann",
    2 : "Ben",
    3 : "Colt"
}

val ann = ids(1)

Adding a pair is also easy:

// because the lookup will return a reference to the pair data (and will create one if it does not exist)
ids(5) = "John"

// or
ids.set(5, "John")

Note: you can easily create your own type of dict and it will look very similar to the built-in ones.

See dicts.

JSON support

With array and dict literals, Venus support JSON syntax directly in the language

var people json = [{
    "ids" : [1, 2, 3, 4, 5],
    "names" : {
        "James": ["LeBron", "Harden"],
        "Paul" : ["Pierce", "Chris"]
    }
}]