Share this page

Learn X in Y minutes

Where X=V

V is a statically typed compiled programming language designed for building maintainable software.

It’s similar to Go and its design has also been influenced by Oberon, Rust, Swift, Kotlin, and Python.

The language promotes writing simple and clear code with minimal abstraction.

Despite being simple, V gives the developer a lot of power. Anything you can do in other languages, you can do in V.

// Single Line Comment.
/*
    Multi Line Comment
*/

struct User { // Cannot be defined in main, explained later.
    age  int
    name string
    pos int = -1 // custom default value
}
// struct method
fn (u User) can_register() bool {
    return u.age > 16
}

struct Parser {
    token Token
}

// c like enums
enum Token {
    plus
    minus
    div
    mult
}

// 1. functions
// language does not use semi colons
fn add(x int, y int) int {
    return x + y 
}
// can return multiple values
fn foo() (int, int) {
    return 2, 3
}

// function visibility 
pub fn public_function() { // pub can only be used from a named module.
}

fn private_function() {
}



// Main function
fn main() {
    // Anonymous functions can be declared inside other functions:
    double_fn := fn (n int) int {
        return n + n
    }
    // 2. Variables: they are immutable by default
    // implicitly typed
    x := 1
    // x = 2 // error
    mut y := 2
    y = 4
    name := "John"
    large_number := i64(9999999999999)
    println("$x, $y, $name, $large_number") // 1, 4, John, 9999999999999

    // unpacking values from functions.
    a, b := foo()
    println("$a, $b") // 2, 3
    c, _ := foo() // ignore values using `_`
    println("$c") // 2

    // Numbers
    u := u16(12)
    v := 13 + u    // v is of type `u16`
    r := f32(45.6)
    q := r + 3.14  // x is of type `f32`
    s := 75        // a is of type `int` 
    l := 14.7      // b is of type `f64` 
    e := u + s     // c is of type `int`
    d := l + r     // d is of type `f64`

    // Strings
    mut bob := 'Bob'
    assert bob[0] == u8(66) // indexing gives a byte, u8(66) == `B`
    assert bob[1..3] == 'ob'  // slicing gives a string 'ob'
    bobby := bob + 'by' // + is used to concatenate strings
    println(bobby) // "Bobby"
    bob += "by2" // += is used to append to strings
    println(bob) // "Bobby2"

    //String values are immutable. You cannot mutate elements:
    //mut s := 'hello 🌎'
    //s[0] = `H` // not allowed

    //For raw strings, prepend r. Escape handling is not done for raw strings:
    rstring := r'hello\nworld' // the `\n` will be preserved as two characters
    println(rstring) // "hello\nworld"

    // string interpolation
    println('Hello, $bob!') // Hello, Bob!
    println('Bob length + 10: ${bob.len + 10}!') // Bob length + 10: 13!

    // 3. Arrays
    mut numbers := [1, 2, 3]
    println(numbers) // `[1, 2, 3]`
    numbers << 4 // append elements with <<
    println(numbers[3]) // `4`
    numbers[1] = 5
    println(numbers) // `[1, 5, 3]`
    // numbers << "John" // error: `numbers` is an array of numbers
    numbers = [] // array is now empty
    arr := []int{len: 5, init: -1}
    // `arr == [-1, -1, -1, -1, -1]`, arr.cap == 5

    number_slices := [0, 10, 20, 30, 40]
    println(number_slices[1..4]) // [10, 20, 30]
    println(number_slices[..4]) // [0, 10, 20, 30]
    println(number_slices[1..]) // [10, 20, 30, 40]

    // 4. structs and enums
    // struct User {
    //  age  int
    //  name string
    //  pos int = -1 // custom default value
    // }
    mut users := User{21, 'Bob', 0}
    println(users.age) // 21

    // enum Token {
    //  plus
    //  minus
    //  div
    //  mult
    // }

    // struct Parser {
    //  token Token
    // }
    parser := Parser{}
    if parser.token == .plus || parser.token == .minus 
    || parser.token == .div || parser.token == .mult {
        // ...
    }


    // 5. Maps
    number_map := {
        'one': 1
        'two': 2
    }
    println(number_map) // {'one': 1, 'two': 2}
    println(number_map["one"]) // 1
    mut m := map[string]int{} // a map with `string` keys and `int` values
    m['one'] = 1
    m['two'] = 2
    println(m['one']) // "1"
    println(m['bad_key']) // "0"
    m.delete('two')

    // 6. Conditionals
    a_number := 10
    b_number := 20
    if a_number < b {
        println('$a_number < $b_number')
    } else if a_number > b {
        println('$a_number > $b_number')
    } else {
        println('$a_number == $b_number')
    }
    num := 777
    even_odd := if num % 2 == 0 { 'even' } else { 'odd' }
    println(even_odd)

    match even_odd {
        'even' { println('even') }
        'odd' { println('odd') }
        else { println('unknown') }
    } 

    // 7. Loops
    loops := [1, 2, 3, 4, 5]
    for lp in loops {
        println(lp)
    }
    loop_names := ['Sam', 'Peter']
    for i, lname in loop_names {
        println('$i) $lname')
        // Output: 0) Sam
        //         1) Peter
    }
    // You can also use break and continue followed by a 
    // label name to refer to an outer for loop:
    outer: for i := 4; true; i++ {
        println(i)
        for {
            if i < 7 {
                continue outer
            } else {
                break outer
            }
        }
    }
}

Further reading

There are more complex concepts to be learnt in V which are available at the official V documentation.

You can also find more information about the V language at the official website or check it out at the v playground.


Got a suggestion? A correction, perhaps? Open an Issue on the GitHub Repo, or make a pull request yourself!

Originally contributed by Maou Shimazu, and updated by 1 contributor.