V | |
---|---|
![]() The official V logo | |
Paradigms | Multi-paradigm: functional, imperative, structured, concurrent |
Designed by | Alexander Medvednikov [1] |
First appeared | 20 June 2019 [2] |
Stable release | |
Typing discipline | static, strong, inferred |
Memory management | optional (automatic or manual) |
Implementation language | V |
Platform | x86-64 |
OS | Linux, macOS, Windows, FreeBSD, OpenBSD, NetBSD, DragonflyBSD, Solaris |
License | MIT |
Filename extensions | .v , .vsh |
Website | vlang |
Influenced by | |
Go, Kotlin, Oberon, Python, Rust, Swift |
V, also known as vlang, is a statically typed, compiled programming language created by Alexander Medvednikov in early 2019. [4] It was inspired by Go, and other programming languages including Oberon, Swift, and Rust. [5] [6] [7] It is free and open-source software released under the MIT License, and currently in beta. [8]
The goals of V include ease of use, readability, and maintainability. [9] [10] [11]
The new language was created as a result of frustration with existing languages being used for personal projects. [12] It was originally intended for personal use, but after being mentioned publicly and increasing interest, it was decided to make it public. V was initially created to develop a desktop messaging client named Volt. [6] On public release, the compiler was written in V, and could compile itself. [4] [12] Key design goals in creating V were being easy to learn and use, higher readability, fast compiling, increased safety, efficient development, cross-platform usability, improved C interoperability, better error handling, modern features, and more maintainable software. [13] [14] [10] [15]
V is released and developed through GitHub, [16] [6] and maintained by developers and contributors internationally. [4] It is among the languages that have been listed on the TIOBE index. [17]
V has policies to facilitate memory-safety, speed, and secure code, [13] [19] [6] including various default features for greater program safety. [7] [13] [12] It employs bounds checking, to guard against out of bounds use of variables. Option/result types are used, where the option data type (?
) can be represented by none
(among possible choices) and the result type (!
) can handle any returned errors. To ensure greater safety, error checking is mandatory. By default, the following are immutable: variables, structs, and function arguments. This includes string values are immutable, so elements cannot be mutated. Other protections, which are the default for the language, are: no use of undefined values, variable shadowing, null pointers (unless marked as unsafe), or global variables (unless enabled via flag).
V uses value types and string buffers to reduce memory allocations. [20] [21] [13] The language can be compiled to human-readable C, [7] [4] and in terms of execution and compilation, it's considered to be as performant. [13] [14] [12]
V supports 4 memory management options: [22] [6] [12]
-gc none
).-autofree
).-prealloc
).V supports a source-to-source compiler (transpiler) and can translate C code into V. [14] [23] [10]
Working translators are also being developed for Go, JavaScript, and WebAssembly. [24] [25] [4]
Criticisms directed at V highlight a general pattern of advertising features/libraries before they are suitable for use. Developers have criticized compiler bugs, lack of memory safety, out-of-date documentation and memory leaks in trivial software. [26] [27] [28] These drawbacks may leave software written in V open to software vulnerabilities. Though, as a counterargument, it may be stated that V is currently in beta as of August, 2025. [8]
Beyond the programming language itself, developers have also criticized moderation within the V community, with individuals being kicked out of chat-rooms for criticizing the language. [26]
The "Hello, World!" program in V: [13] [29]
fnmain(){println("Hello, World!")}
Variables are immutable by default and are defined using :=
and a value. Use the mut
reserved word (keyword) to make them mutable. Mutable variables can be assigned to using =
: [30] [29]
x:=1muty:=2y=3
Redeclaring a variable, whether in an inner scope or in the same scope, is not allowed: [30] [29]
x:=1{x:=3// error: redefinition of x}x:=2// error: redefinition of x
structFoo{numberintnamestringscoref32}// Struct fields can be initialized by namevar1:=Foo{number:21name:"baz"score:2.5}// or by positionvar2:=Foo{50,"taz",3.14}
By default, structs are allocated on the stack. When structs are referenced by using the prefix &
or have the [heap]
attribute, they are allocated on the heap instead: [4] [29]
structFoo{numberint}@[heap]structBaz{numberf32}// Structs that are referenced are heap allocatedvar1:=&Foo{2}// Baz is always heap allocated because of its [heap] attributevar2:=Baz{4.5}
Methods in V are functions defined with a 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.
The enrolled_status method (below) has a receiver of type Client
named x
. The convention is not to use receiver names like self or this, but preferably a short name. For example: [9] [10] [29]
structClient{enrolledbool}fn(xClient)enrolled_status()bool{returnx.enrolled}println(Client{enrolled:true}.enrolled_status())// trueprintln(Client{enrolled:false}.enrolled_status())// false
Result types may represent an error returned from a function. Result types are declared by prepending !
: !Type
Optional types may represent none
. Option types prepend ?
to the type name: ?Type
. [9] [7] [22] [29]
fnsomething(tstring)!string{ift=="foo"{return"foo"}returnerror("invalid")}x:=something("foo")or{"default"}// x will be "foo"y:=something("baz")or{"default"}// y will be "default"z:=something("baz")or{panic("{err}")}// z will exit with an errorprintln(x)println(y)