V (/ˈviː/, as in the letter v) also known as vlang, is a statically typed compiled programming language created by Alexander Medvednikov in early 2019. It was mostly inspired by the Go programming language, but was also influenced by C, Rust, and Oberon-2. It is free and open-source software, in active development at GitHub, and released under the MIT license.
The foremost goal of V is to be easy to use, and at the same time, to enforce a safe coding style through elimination of ambiguity. For example, variable shadowing is not allowed; declaring a variable with a name that is already used in a parent scope will cause a compilation error.
History
The new language was created as a result of frustration with existing languages being used for personal projects. Originally the language was intended for personal use, but after it was mentioned publicly and gained interest, it was decided to make it public. Initially, the name was the same as a product known as Volt. The V language was created in order to develop it, along with other software applications such as Ved (also called Vid). As the extension in use was already ".v", to not mess up the git history, it was decided to name it "V". Upon public release, the compiler was written in V, and could compile itself. Along with Alexander Medvednikov, the creator, its community has a large number of contributors from around the world who have helped with continually developing and adding to the compiler, language, and modules. Key design goals behind the creation of V: easier to learn and use, higher readability, fast compilation, increased safety, efficient development, cross-platform usability, improved C interop, better error handling, modern features, and more maintainable software.
Features
Safety
Usage of bounds checking
Usage of Option/Result
Mandatory checking of errors
No usage of values that are undefined
No shadowing of variables
No usage of null (unless in unsafe code) No usage of global variables (unless enabled via flag) Variables are immutable by default Structs are immutable by default Function args are immutable by default Sum types can be used Generics can be used
Performance
Fast like C (human-readable C compiled by backend) Added features for safety, if desired, can be disabled or bypassed for greater performance C interop Allocations kept to minimal Serialization with no runtime reflection Native binaries compiled with no dependencies
Fast build
V is written in itself and can compile within a second.
Memory management options
Allocations handled by an optional GC, that is the default, which can be disabled Manual memory management (-gc none) Autofree (-autofree), handles most objects via free call insertion Remaining percentage freed by GC Arena allocation with (-prealloc)
Source code translators (code transpilation)
C source code conversion: V (via module) can translate an entire C project into V code.
Working translators (under various stages of development) exist for Go, JavaScript, and WASM.
Syntax
Hello world
fn main() {
println('hello world') }
Structs
struct Point {
x int
y int
}
mut p := Point{
x: 10
y: 20
}
println(p.x) // Struct fields are accessed using a dot
// Alternative literal syntax for structs with 3 fields or fewer
p = Point{ 10, 20}
assert p.x == 10
Heap structs
Structs are allocated on the stack. To allocate a struct on the heap and get a reference to it, use the & prefix: struct Point { x int y int }
p := &Point{ 10, 10}
// References have the same syntax for accessing fields
println(p.x)
Methods
V doesn't have classes, but you can define methods to types. A method is a function with a special receiver argument. The receiver appears in its own argument list between the fn keyword and the method name. Methods must be in the same module as the receiver type.
In this example, the is_registered method has a receiver of type User named u. The convention is not to use receiver names like self or this, but preferably a short name.
struct User {
age int
}
fn (u User) is_registered() bool {
return u.age > 16
}
user := User{
age: 10
}
println(user.is_registered()) // "false" user2 := User{ age: 20 } println(user2.is_registered()) // "true"
Error handling
Optional types are for types which may represent none. Result types may represent an error returned from a function.