V Programming Language: Simple, Fast, dan Compiled tanpa Garbage Collector
V (Vlang) adalah bahasa pemrograman compiled yang sederhana dan cepat. Dengan autofree memory management, C interop yang mulus, dan compilation speed yang luar biasa, V menawarkan pengalaman programming yang menyenangkan dengan performa tinggi.
📋 Daftar Isi
1. Mengapa V?
V dibuat oleh Alexander Medvednikov pada 2019. Bahasa ini dirancang untuk menjadi "bahasa yang sempurna" — simpel seperti Go, cepat seperti C, dan aman seperti Rust, tanpa complexity yang berlebihan.
- Simpel — Bisa dipelajari dalam beberapa jam, hanya ~30 keyword
- Cepat compile — ~1 detik untuk compile project besar
- Cepat execute — Setara dengan C
- Tanpa GC — Autofree memory management
- C Interop — Panggil C code langsung tanpa wrapper
- Cross-compilation — Compile ke platform apapun
- Built-in tools — Formatter, linter, testing, dan package manager
V berfokus pada kesederhanaan. Tidak ada hidden control flow, tidak ada hidden allocations, tidak ada undefined behavior. Setiap fitur dirancang untuk seminimal mungkin — tapi tetap powerful.
2. Instalasi
# Clone dan build dari source (recommended) git clone https://github.com/vlang/v.git cd v make # Linux/macOS - symlink sudo ./v symlink # macOS (Homebrew) brew install vlang # Windows # Download dari https://vlang.io/download # Atau: git clone && make.bat # Verifikasi v version # V 0.4.x # Buat proyek baru v init my_project cd my_project # Compile dan jalankan v run . # Compile ke binary v -o my_app . # Jalankan file langsung v run hello.v # Format code v fmt -w . # Jalankan test v test . # Self-update v up
3. Dasar-Dasar V
Variables dan Types
module main
import os
fn main() {
// Variables - immutable by default
nama := 'BeebaneLabs'
umur := 25
tinggi := 1.75
aktif := true
// Mutable variables
mut skor := 100
skor += 50
// Type annotations
x := 42
y := 3.14
s := 'hello'
b := true
c := `a` // rune/char
// Explicit types
a := int(42)
f := f64(3.14)
// String operations
println('Nama: ${nama}, Umur: ${umur}')
println(nama.len)
println(nama.to_upper())
println(nama.to_lower())
println(nama.contains('Bee'))
println(nama.replace('Bee', 'B'))
println(nama.reverse())
// String interpolation (menggunakan ${})
msg := 'Hello, ${nama}! Umur: ${umur + 1}'
println(msg)
// Integers: i8, i16, i32, i64, int
// Unsigned: u8, u16, u32, u64
// Float: f32, f64
// Arrays
angka := [1, 2, 3, 4, 5]
println(angka.len) // 5
println(angka.first()) // 1
println(angka.last()) // 5
println(angka.contains(3)) // true
// Mutable arrays
mut list := []int{}
list << 1
list << 2
list << 3
println(list)
// Array operations
doubled := angka.map(it * 2)
evens := angka.filter(it % 2 == 0)
total := angka.reduce(fn (acc int, x int) int { return acc + x }, 0)
// Maps
mut user := map[string]string{}
user['nama'] = 'Andi'
user['email'] = 'andi@email.com'
println(user['nama'])
// Struct
struct Point {
x f64
y f64
}
p := Point{3.0, 4.0}
println('x=${p.x}, y=${p.y}')
// Enums
enum Color {
red
green
blue
}
c := Color.red
// Option type
fn find_user(id int) ?string {
if id == 1 {
return 'Andi'
}
return none
}
user := find_user(1) or { 'Unknown' }
// Result type
fn parse_age(s string) !int {
age := s.int()
if age < 0 || age > 150 {
return error('Umur tidak valid')
}
return age
}
age := parse_age('25') or { 0 }
// Control flow
if umur >= 17 {
println('Dewasa')
} else {
println('Anak-anak')
}
// Match (switch)
match c {
.red { println('Merah') }
.green { println('Hijau') }
.blue { println('Biru') }
}
// For loop
for i in 0 .. 10 {
println(i)
}
// For-in
for item in angka {
println(item)
}
// While
mut i := 0
for i < 10 {
println(i)
i++
}
}
Functions dan Methods
// Basic function
fn tambah(a int, b int) int {
return a + b
}
// Single expression
fn kali(a int, b int) int {
return a * b
}
// Multiple return values
fn min_max(arr []int) (int, int) {
mut min := arr[0]
mut max := arr[0]
for val in arr {
if val < min { min = val }
if val > max { max = val }
}
return min, max
}
// Option return type
fn safe_divide(a f64, b f64) ?f64 {
if b == 0 {
return none
}
return a / b
}
// Error return type
fn read_file(path string) !string {
if !os.exists(path) {
return error('File tidak ditemukan: ${path}')
}
return os.read_file(path)
}
// Default parameters
fn greet(nama string, greeting string = 'Halo') string {
return '${greeting}, ${nama}!'
}
// Variadic arguments
fn jumlah(args ...int) int {
mut total := 0
for arg in args {
total += arg
}
return total
}
// Generic functions
fn first(arr []T) T {
return arr[0]
}
// Method pada struct
struct User {
nama string
umur int
}
fn (u User) greet() string {
return 'Halo, ${u.nama} (${u.umur})'
}
fn (mut u User) set_age(umur int) {
u.umur = umur
}
// Interface
interface Printable {
str() string
}
struct Product {
nama string
harga f64
}
fn (p Product) str() string {
return '${p.nama}: Rp ${p.harga}'
}
4. Memory Management (Autofree)
V menggunakan pendekatan unik untuk memory management: autofree compiler. Compiler secara otomatis menambahkan free() call di tempat yang tepat, sehingga Anda tidak perlu GC atau manual management.
module main
// Compile dengan autofree:
// v -autofree run .
// V secara otomatis men-free memory saat tidak digunakan lagi
fn contoh_autofree() {
// String ini akan otomatis di-free setelah fungsi selesai
nama := 'BeebaneLabs'
pesan := 'Hello, ${nama}!'
println(pesan)
// Compiler menambahkan free(pesan) dan free(nama) di sini
}
// Manual memory management opsional
fn contoh_manual() {
// Manual buffer
buf := unsafe { malloc(1024) }
// ... gunakan buffer
unsafe { free(buf) }
}
// Shared memory antar threads
fn contoh_shared() {
shared counter := 0
lock counter {
counter++
}
rlock counter {
println('Counter: ${counter}')
}
}
// Optionals - tidak perlu null
fn process(data ?string) {
// Option chaining
result := data or { 'default' }
println(result)
// Or-block
match data {
some { println('Ada data: ${data}') }
none { println('Tidak ada data') }
}
}
// Struct ownership
struct Owner {
data string
}
struct Borrower<'a> {
owner &Owner
}
// Error propagation
fn proses_data() !string {
data := read_data()! // propagate error dengan !
validated := validate(data)!
return format(validated)
}
fn read_data() !string {
return 'data'
}
fn validate(data string) !string {
if data.len == 0 {
return error('Data kosong')
}
return data
}
fn format(data string) !string {
return 'Formatted: ${data}'
}
fn main() {
contoh_autofree()
result := proses_data() or { 'Error: ${err}' }
println(result)
}
5. C Interop
V bisa memanggil C library langsung tanpa FFI wrapper. Ini salah satu fitur terkuat V.
module main // Import C header langsung #include#include #include // C function declarations fn C.sqrt(x f64) f64 fn C.pow(base f64, exp f64) f64 fn C.sin(x f64) f64 fn C.cos(x f64) f64 fn C.time(t &int) int fn C.printf(fmt &char, ...void) int // C struct struct C.timespec { tv_sec int tv_nsec int } fn C.clock_gettime(clk_id int, tp &C.timespec) int fn main() { // Panggil C functions langsung println(C.sqrt(144.0)) // 12.0 println(C.pow(2.0, 10.0)) // 1024.0 println(C.sin(3.14159 / 2.0)) // ~1.0 // C variadic function unsafe { C.printf(c'Hello from C: %d\n', 42) } // Using C struct ts := C.timespec{} unsafe { C.clock_gettime(0, &ts) } println('Unix timestamp: ${ts.tv_sec}') // Compile dengan C library: // v -cflags '-lm' run . // Link dengan custom C library: // v -cflags '-L./libs -lmylib' run . } // Wrapper module untuk C library // mylib/wrapper.v: // module mylib // #include "mylib.h" // fn C.my_function(x int) int // pub fn my_function(x int) int { // return C.my_function(x) // }
6. Concurrency
module main
import time
// Spawn - menjalankan function di goroutine-like thread
fn worker(id int) {
for i in 0 .. 5 {
println('Worker ${id}: ${i}')
time.sleep(100 * time.millisecond)
}
}
fn main() {
// Spawn threads
spawn worker(1)
spawn worker(2)
spawn worker(3)
// Wait untuk threads selesai
time.sleep(1 * time.second)
// Channels
ch := chan int{cap: 10}
// Producer
spawn fn (ch chan int) {
for i in 0 .. 10 {
ch <- i
}
ch.close()
}(ch)
// Consumer
for val in ch {
println('Received: ${val}')
}
// Shared state
shared counter := 0
mut threads := []thread{}
for _ in 0 .. 10 {
threads << spawn fn (shared counter) {
for _ in 0 .. 1000 {
lock counter {
counter++
}
}
}(counter)
}
threads.wait()
rlock counter {
println('Counter: ${counter}')
}
// Wait group
mut wg := sync.new_wait_group()
wg.add(3)
for i in 0 .. 3 {
spawn fn (i int, wg &sync.WaitGroup) {
defer { wg.done() }
println('Task ${i} selesai')
}(i, wg)
}
wg.wait()
println('Semua task selesai')
}
7. Web Development (Vweb)
module main
import vweb
import json
struct App {
vweb.Context
}
struct User {
id int @[json: 'id']
name string @[json: 'name']
age int @[json: 'age']
}
['/']
fn (app App) index() vweb.Result {
return app.html('Hello from V!
')
}
['/api/users']
fn (app App) get_users() vweb.Result {
users := [
User{1, 'Andi', 25},
User{2, 'Budi', 30},
User{3, 'Citra', 22},
]
return app.json(users)
}
['/api/users/:id']
fn (app App) get_user(id string) vweb.Result {
user := User{1, 'Andi', 25}
return app.json(user)
}
['/api/users'; post]
fn (app App) create_user() vweb.Result {
user := json.decode(User, app.req.data) or {
return app.json({'error': 'Invalid JSON'})
}
return app.json(user)
}
fn main() {
mut app := &App{}
app.serve_static('/static', 'static/')
vweb.run(app, 8080)
}
8. Cross Compilation
# Cross-compile untuk Linux dari macOS/Windows v -os linux -o myapp . # Cross-compile untuk Windows v -os windows -o myapp.exe . # Cross-compile untuk macOS v -os macos -o myapp . # Cross-compile untuk FreeBSD v -os freebsd -o myapp . # Compile ke JavaScript v -b js_browser -o output.js . v -b js_node -o output.js . # Compile dengan optimasi v -prod -o myapp . # Release mode # Compile dengan debug info v -g -o myapp . # Generate C code (tanpa compile ke binary) v -o main.c -translated . # Compile ke native, output berupa C yang bisa di-compile manual v -o output.c . gcc output.c -o myapp -lm -lpthread # Compile ke WASM (experimental) v -b wasm -o output.wasm .