V (Vlang) 0.2 was released. The author announced that this is the first major version. The update focuses on improving stability and optimizing compile-time memory management.
Some update highlights
-autofree
Manage compile-time memory by enabling parameters (planned to be enabled by default in 0.3)- Provide early support for iOS and Android
- Introduce IO stream
- Introduce channel and lock
- Introduce inline structure (Struct embedding)
- Supports automatic build and deployment of V binary files for Linux/Windows/macOS through GitHub Actions
- Support for C++ compiler: The code generated by the C backend can now be compiled by the C++ compiler
- Generic syntax is more concise, such as using
foo(5)
insteadfoo<int>(5)
- V can now be run in the browser via WASM
- Improve documentation
- ……
For details, please check https://github.com/vlang/v/discussions/7474
V 0.3 Roadmap: https://github.com/vlang/v/blob/master/0.3_roadmap.txt
V is a static language that combines the simplicity of Go and the security features of Rust. The author stated that V is very similar to Go. If you know Go, you already know 80% of V. V improves on the basis of Go: https://vlang.io/compare#go .
V main features
- Simple (the author claims to be able to learn V in less than an hour)
- Fast compilation (the compiler is only 400kb, and there is no third-party dependency)
- Easy to develop: V compiles in less than a second
- Security: no null, no global variables, no undefined values, boundary detection, Immutable structure is used by default
- Support C/C++ conversion
- Easy to use cross compilation
- Provide cross-platform UI library
- Built-in graphics library
- Built-in ORM
- Built-in web framework
- ……
Sample code
Database access:
struct User { /* ... */ }
struct Post { /* ... */ }
struct DB { /* ... */ }
struct Repo <T> {
db DB
}
fn new_repo<T>(db DB) Repo {
return Repo<T>{db: db}
}
fn (r Repo) find_by_id(id int) T? { // `?` means the function returns an optional
table_name := T.name // in this example getting the name of the type gives us the table name
return r.db.query_one<T>('select * from $table_name where id = ?', id)
}
fn main() {
db := new_db()
users_repo := new_repo<User>(db)
posts_repo := new_repo<Post>(db)
user := users_repo.find_by_id(1) or {
eprintln('User not found')
return
}
post := posts_repo.find_by_id(1) or {
eprintln('Post not found')
return
}
}
Web development:
struct Story {
title string
}
// Fetches top HN stories in 8 coroutines
fn main() {
resp := http.get('https://hacker-news.firebaseio.com/v0/topstories.json')?
ids := json.decode([]int, resp.body)?
mut cursor := 0
for _ in 0..8 {
go fn() {
for {
lock { // Without this lock the program will not compile
if cursor >= ids.len {
break
}
id := ids[cursor]
cursor++
}
resp := http.get('https://hacker-news.firebaseio.com/v0/item/$id.json')?
story := json.decode(Story, resp.body)?
println(story.title)
}
}()
}
runtime.wait() // Waits for all coroutines to finish
}