InterviewPitch
V interview questions

V Interview Questions with Answers

Most Asked V Interview Questions for Software Engineer Roles

100+ QuestionsDetailed AnswersCode ExamplesUpdated for 2026

Introduction

This page provides a complete collection of V Interview Questions and Answers designed for software engineers, system programmers, backend developers, and candidates preparing for technical interviews. V is a statically typed, compiled programming language created by Alexander Medvednikov. It focuses on simplicity, performance, and safety, offering features like fast compilation, zero-cost C interoperability, built-in concurrency, and memory management without garbage collection. This interview guide covers beginner, intermediate, and advanced V concepts including syntax, variables, functions, structs, interfaces, generics, error handling, concurrency (spawn, channels), modules, testing, web development, and real-world programming scenarios.

Why V?

  • Simplicity – clean syntax inspired by Go and Rust, easy to learn
  • Performance – compiles to native code with zero-cost C interop
  • Memory safety – no null, no global state, and automatic memory management
  • Fast compilation – compiles millions of lines of code in seconds
  • Built-in concurrency – lightweight threads (spawn) and channels for safe parallelism
  • Growing ecosystem – active community, web frameworks (Vweb), and game libraries
  • Used in production – companies and projects adopt V for systems, web, and CLI tools

Most Asked V Interview Questions

Beginner
1. What is V (Vlang)?

V (also known as Vlang) is a statically typed, compiled programming language designed for simplicity, speed, and safety. It's a new language inspired by Go and Rust.

  • Fast compilation: Compiles to machine code quickly
  • Memory safe: No null, no undefined behavior
  • Concurrency: Built-in channels and coroutines
  • Simple syntax: Easy to learn and read
  • Cross-platform: Windows, Linux, macOS
vlang
// Hello World in V (Vlang)
fn main() {
    println("Hello, World!")
}
Beginner
2. How to declare variables in V?

Variables in V are immutable by default. Use := for type inference and mut for mutable variables.

  • Immutable: name := "Alice"
  • Mutable: mut age := 25
  • Explicit type: var x int = 10
  • Constants: const PI = 3.14159
  • Shadowing: Variables cannot be shadowed
vlang
// Variables in V (Vlang)
fn main() {
    // Immutable variable (default)
    immutable_var := "World"
    
    // Mutable variable
    mut mutable_var := "Hello"
    mutable_var = "V"
    
    // Type inference
    inferred := 42
    
    // Explicit type
    explicit int = 10
    
    // Constants
    const pi = 3.14159
    
    // Display
    println(immutable_var)
    println(mutable_var)
    println(inferred)
    println(explicit)
    println(pi)
}
Beginner
3. What are the data types in V?

V provides a rich set of primitive and composite types.

  • Integers: int, i8, i16, i32, i64, u8, u16, u32, u64
  • Floats: f32, f64
  • Boolean: bool
  • String: string
  • Rune: rune
  • Array: [T]
  • Map: map[string]T
  • Struct: struct { ... }
  • Interface: interface { ... }
vlang
// Data Types in V (Vlang)
fn main() {
    // Integer types
    int_num := 10
    unsigned := u32(100)
    small_int := i8(127)
    large_int := i64(1000000)
    
    // Floating point
    float_num := 3.14
    double_num := 3.14159
    
    // Boolean
    is_active := true
    is_inactive := false
    
    // Character
    char_val := `A`
    
    // String
    str_val := "Hello V"
    
    // Array
    arr := [1, 2, 3, 4, 5]
    
    // Tuple
    tuple := (10, 3.14, "hello")
    
    // Map
    map := {
        "name": "Alice",
        "age": 25
    }
    
    // Option type (null safety)
    optional := ?int(nil)
    
    // Type checking
    println(typeof(int_num).name)
}
Beginner
4. How to define functions in V?

Functions are defined with the fn keyword. They support parameters, return types, recursion, and multiple return values.

  • Syntax: fn name(params) return_type { ... }
  • Single‑expression: fn add(a, b int) int { a + b }
  • Recursive: fn factorial(n int) int { ... }
  • Multiple returns: (int, int)
  • Higher‑order: functions as parameters
  • Anonymous: fn() { ... }()
vlang
// Functions in V (Vlang)
// Basic function
fn add(a int, b int) int {
    return a + b
}

// Function with multiple return values
fn divide(a int, b int) (int, int) {
    return a / b, a % b
}

// Function with default parameters
fn greet(name string) string {
    if name == "" {
        return "Hello, Guest!"
    }
    return "Hello, " + name + "!"
}

// Higher-order function
fn operate(a int, b int, op fn(int, int) int) int {
    return op(a, b)
}

// Closure (lambda)
multiply := fn(a int, b int) int {
    return a * b
}

// Main function
fn main() {
    println(add(5, 3))
    quotient, remainder := divide(10, 3)
    println("Quotient: ${quotient}, Remainder: ${remainder}")
    println(greet("Alice"))
    println(operate(6, 7, multiply))
}
Beginner
5. What are arrays in V?

Arrays are ordered, homogeneous collections. They are mutable and have a dynamic size.

  • Creation: [1, 2, 3]
  • Append: arr << 4
  • Insert: arr.insert(index, value)
  • Delete: arr.delete(index)
  • Slice: arr[1..3]
  • Fixed size: [3]int{1,2,3}
vlang
// Arrays in V (Vlang)
fn main() {
    // Array creation
    mut numbers := [1, 2, 3, 4, 5]
    strings := ["Apple", "Banana", "Orange"]
    
    // Access and modify
    println(numbers[2])
    numbers[2] = 10
    
    // Array operations
    println(numbers.len)
    numbers << 6  // Append
    numbers.pop() // Remove last
    
    // Iteration
    for num in numbers {
        println(num)
    }
    
    // Array methods
    doubled := numbers.map(fn (x int) int { return x * 2 })
    filtered := numbers.filter(fn (x int) bool { return x > 2 })
    sum := numbers.reduce(fn (a int, b int) int { return a + b }, 0)
    
    println(doubled)
    println(filtered)
    println(sum)
    
    // Fixed-size array
    fixed_array := [5]int{1, 2, 3, 4, 5}
}
Beginner
6. What are maps in V?

Maps are associative arrays (dictionaries) that map keys to values.

  • Creation: map[string]int{ "a": 1, "b": 2 }
  • Access: m["key"] or { default }
  • Add/Update: m["key"] = value
  • Delete: m.delete("key")
  • Membership: if "key" in m { ... }
vlang
// Collections in V (Vlang)
fn main() {
    // Array (list)
    immutable_array := [1, 2, 3, 4, 5]
    mut mutable_array := [1, 2, 3]
    mutable_array << 4
    mutable_array.delete(1)
    
    // Map (dictionary)
    mut map := map[string]string{}
    map["key1"] = "value1"
    map["key2"] = "value2"
    map.delete("key1")
    
    // Set (using map)
    mut set := map[int]bool{}
    set[1] = true
    set[2] = true
    set[3] = true
    set.delete(2)
    
    // Collection operations
    numbers := [1, 2, 3, 4, 5, 6]
    evens := numbers.filter(fn (x int) bool { return x % 2 == 0 })
    doubled := numbers.map(fn (x int) int { return x * 2 })
    sum := numbers.reduce(fn (a int, b int) int { return a + b }, 0)
    
    println(evens)
    println(doubled)
    println(sum)
}
Beginner
7. What are structs in V?

Structs group related fields. They can have methods (including mutating methods).

  • Definition: struct Person { name string; age int }
  • Instantiation: p := Person{"Alice", 25}
  • Method: fn (p Person) greet() string { ... }
  • Mutating method: fn (mut p Person) birthday() { p.age++ }
  • Embedding: struct Employee { Person; salary int }
vlang
// Structs (Data Classes) in V (Vlang)
struct Person {
    name string
    age int
    city string = "Unknown"
}

// Methods
fn (p Person) greet() string {
    return "Hello, my name is " + p.name
}

// Mutating method
fn (mut p Person) increment_age() {
    p.age++
}

// Constructor
fn new_person(name string, age int) Person {
    return Person{
        name: name,
        age: age
    }
}

fn main() {
    mut person1 := Person{
        name: "Alice",
        age: 25,
        city: "NYC"
    }
    
    person2 := Person{
        name: "Bob",
        age: 30
    }
    
    // Copy (structs are value types)
    person3 := person1
    person3.age = 26
    
    println(person1.name)
    println(person1.age)
    println(person1.city)
    println(person1.greet())
    
    person1.increment_age()
    println(person1.age)
}
Beginner
8. What are interfaces in V?

Interfaces define a set of methods. A type implements an interface if it has all the required methods.

  • Definition: interface Speaker { speak() string }
  • Implementation: implicit (no explicit implements)
  • Usage: any type that provides the methods can be used as the interface
  • Empty interface: interface{} (like Go's any)
  • Type assertion: if val is Speaker { ... }
vlang
// Enums and Sum Types in V (Vlang)
enum Color {
    red
    green
    blue
}

enum Status {
    success(int)
    error(string)
    loading
}

// Sum type (sealed class)
type Shape = Circle | Rectangle | Point

struct Circle {
    radius f64
}

struct Rectangle {
    width f64
    height f64
}

struct Point {}

fn (c Circle) area() f64 {
    return 3.14159 * c.radius * c.radius
}

fn (r Rectangle) area() f64 {
    return r.width * r.height
}

fn (p Point) area() f64 {
    return 0.0
}

fn main() {
    color := Color.red
    status := Status.success(200)
    shape := Circle{radius: 5.0}
    
    // Match statement
    match color {
        Color.red { println("Color is Red") }
        Color.green { println("Color is Green") }
        Color.blue { println("Color is Blue") }
    }
    
    match status {
     
    Status.success(code) { println("Success with code: ${code}") }
Status.error(msg) { println("Error: ${msg}") }
Status.loading { println("Loading...") }

    }
    
    println(shape.area())
}
Beginner
9. How does error handling work in V?

V uses ?T (optionals) and or blocks for error handling. There are no exceptions.

  • Optional type: ?int (may have a value or be none)
  • Returning: return none or return value
  • Handling: result := fn() or { ... }
  • Unwrap: value := optional or { default }
  • Propagation: value := optional? (panics on error)
vlang
// Null Safety in V (Vlang)
// Option type for null safety
struct User {
    name string
    email ?string  // Optional field
}

fn main() {
    // Optional variable
    maybe_string := ?string(nil)
    // maybe_string := ?string("Hello")
    
    // Safe access with or block
    value := maybe_string or { "default" }
    println(value)
    
    // Optional chaining
    user := User{
        name: "Alice",
        email: "alice@example.com"
    }
    
    email := user.email or { "No email" }
    println(email)
    
    // If let pattern
    if name := maybe_string {
        println("String is: ")
    }
    
    // Guard statement
    data := ?int(42)
    if data == none {
        println("Data is none")
    } else {
        println("Data: ${data}")
    }
    
    // Option with .? operator (unsafe unwrap)
    // value := maybe_string.?
}
Beginner
10. What are option types in V?

Option types (?T) represent values that may be absent. They are like Maybe or Option in other languages.

  • Declaration: mut maybe := ?int = none
  • Setting: maybe = 42
  • Checking: if n := maybe { ... }
  • Unwrapping: value := maybe or { 0 }
  • Panic on none: value := maybe?
vlang
// Control Flow in V (Vlang)
fn main() {
    // If-else
    age := 25
    status := if age < 18 { "Minor" } else { "Adult" }
    println(status)
    
    // If-else-if
    grade := 'A'
    result := if grade == 'A' {
        "Excellent"
    } else if grade == 'B' {
        "Good"
    } else if grade == 'C' {
        "Fair"
    } else {
        "Needs Improvement"
    }
    println(result)
    
    // Match statement
    score := 85
    grade2 := match score {
        90...100 { "A" }
        80...89 { "B" }
        70...79 { "C" }
        else { "F" }
    }
    println(grade2)
    
    // For loop
    for i := 0; i < 5; i++ {
        println(i)
    }
    
    // For-in loop
    items := ["A", "B", "C"]
    for item in items {
        println(item)
    }
    
    // While loop
    mut i := 0
    for i < 5 {
        println(i)
        i++
    }
    
    // Infinite loop with break
    mut j := 0
    for {
        println(j)
        j++
        if j >= 5 {
            break
        }
    }
}
Beginner
11. Control flow statements in V

V provides if, else, match (switch), and loops.

  • If-else: if cond { ... } else { ... }
  • If-else if: if cond1 { ... } else if cond2 { ... }
  • Match: match value { pattern { ... } }
  • For: for i in 0..n { ... }
  • While: for cond { ... }
vlang
// Interfaces and Inheritance in V (Vlang)
// Interface
interface Animal {
    name string
    make_sound() string
}

// Struct implementing interface
struct Dog {
    name string
    breed string
}

fn (d Dog) make_sound() string {
    return "Woof!"
}

// Struct with inheritance (embedding)
struct Cat {
    Animal // Embedding
    color string
}

// Interface with multiple implementations
interface Flyable {
    fly() string
}

interface Swimmable {
    swim() string
}

struct Duck {
    name string
}

fn (d Duck) fly() string {
    return "Flying"
}

fn (d Duck) swim() string {
    return "Swimming"
}

fn main() {
    dog := Dog{
        name: "Rex",
        breed: "German Shepherd"
    }
    
    cat := Cat{
        name: "Whiskers",
        color: "Black"
    }
    
    duck := Duck{
        name: "Donald"
    }
    
    println(dog.make_sound())
    println(dog.name)
    println(dog.breed)
    
    println(duck.fly())
    println(duck.swim())
}
Beginner
12. What are loops in V?

V has for loops with range, while loops, and infinite loops with break.

  • Range: for i in 0..5 { ... }
  • Step: for i in 0..10 step 2 { ... }
  • While: for cond { ... }
  • Infinite: for { ... }
  • Array iteration: for val in arr { ... }
vlang
// Properties in V (Vlang)
struct Person {
    mut:
        _name string
        _age int
        _email string
}

// Getter
fn (p Person) name() string {
    return p._name.to_upper()
}

// Setter with validation
fn (mut p Person) set_name(name string) {
    p._name = name.trim_space()
}

fn (p Person) age() int {
    return p._age
}

fn (mut p Person) set_age(age int) {
    if age >= 0 {
        p._age = age
    }
}

// Computed property
fn (p Person) full_name() string {
    return "${p._name} (Age: ${p._age})"
}

// Lazy property
struct LazyPerson {
    name string
    mut:
        expensive_data string = ""
        computed bool = false
}

fn (mut p LazyPerson) get_expensive_data() string {
    if !p.computed {
        println("Computing expensive data...")
        p.expensive_data = "Expensive Result"
        p.computed = true
    }
    return p.expensive_data
}

fn main() {
    mut person := Person{
        _name: "  Alice  ",
        _age: 25,
        _email: "alice@example.com"
    }
    
    println(person.name()) // ALICE
    person.set_name("Bob")
    println(person.name()) // BOB
    person.set_age(26)
    println(person.age())
    println(person.full_name())
    
    mut lazy := LazyPerson{
        name: "Alice"
    }
    println(lazy.get_expensive_data())
    println(lazy.get_expensive_data()) // Cached
}
Beginner
13. How to use match (switch) in V?

match is a powerful pattern‑matching construct similar to switch in other languages.

  • Syntax: match value { pattern => { ... } }
  • Literal patterns: 1, "hello", true
  • Ranges: 1..10
  • Multiple patterns: 1,2,3 => { ... }
  • Else: else { ... } (default)
vlang
// Static Methods in V (Vlang)
struct MyClass {
    id int
}

// Static field
const tag = "MyClass"

// Static counter
mut counter := 0

// Static method (factory)
fn create() MyClass {
    counter++
    return MyClass{
        id: counter
    }
}

// Static method
fn class_method() string {
    return "Class method called, counter: ${counter}"
}

// Instance method
fn (mc MyClass) instance_method() string {
    return "Instance ${mc.id} method called"
}

// Singleton pattern
struct Singleton {
    mut:
        data []string
}

mut singleton_instance := Singleton{}

fn get_singleton() &Singleton {
    return &singleton_instance
}

fn (mut s Singleton) add_data(item string) {
    s.data << item
}

fn (s Singleton) get_data() []string {
    return s.data
}

fn main() {
    println(tag)
    obj1 := create()
    obj2 := create()
    println(class_method())
    println(obj1.instance_method())
    println(obj2.instance_method())
    
    s1 := get_singleton()
    s2 := get_singleton()
    s1.add_data("Hello")
    println(s2.get_data()) // ["Hello"]
}
Intermediate
14. What are generics in V?

Generics allow writing code that works with multiple types. They use type parameters ([T]).

  • Generic struct: struct Box[T] { value T }
  • Generic function: fn identity[T](x T) T { return x }
  • Type constraints: where T == int (using interfaces or union types)
  • Multiple type params: [T, U]
  • Type inference: often automatic
vlang
// Error Handling in V (Vlang)
// Custom error type
struct InvalidAgeError {
    age int
}

fn (e InvalidAgeError) msg() string {
    return "Invalid age: ${e.age}"
}

// Function that returns option/result
fn divide(a int, b int) ?int {
    if b == 0 {
        return none
    }
    return a / b
}

// Function with custom error
fn validate_age(age int) ? {
    if age < 0 || age > 150 {
        return error("Invalid age: ${age}")
    }
}

// Using with or block
fn main() {
    // Option handling
    result := divide(10, 2) or {
        println("Error: ${err}")
        return
    }
    println("Result: ${result}")
    
    // Handling division by zero
    result2 := divide(10, 0) or {
        println("Error: ${err}")
        0
    }
    println("Result: ${result2}")
    
    // Custom error handling
    err := validate_age(25) or {
        println("Error: ${err}")
        return
    }
    println("Age is valid")
    
    // Using if
    if result := divide(10, 2) {
        println("Result: ${result}")
    } else {
        println("Error occurred")
    }
    
    // Defer (finally equivalent)
    defer {
        println("Cleaning up...")
    }
    println("Processing...")
}
Intermediate
15. How to work with strings in V?

Strings are immutable, UTF‑8 encoded bytes. They support concatenation, indexing, slicing, and many built‑in functions.

  • Concatenation: "Hello" + " " + "World"
  • Interpolation: "Hello $name"
  • Length: s.len (returns bytes, not runes)
  • Runes: s.runes() for Unicode support
  • Slicing: s[1..3]
  • Replace: s.replace("old", "new")
vlang
// Closures in V (Vlang)
fn main() {
    // Basic closure
    square := fn (x int) int {
        return x * x
    }
    
    // Closure with multiple parameters
    add := fn (a int, b int) int {
        return a + b
    }
    
    // Closure with multiple lines
    complex := fn (x int) int {
        y := x * 2
        return y + 10
    }
    
    // Higher-order function
    operate := fn (a int, b int, op fn(int, int) int) int {
        return op(a, b)
    }
    
    // Closure capturing environment
    factor := 2
    multiply := fn [factor] (x int) int {
        return x * factor
    }
    
    // Closure returning closure
    get_multiplier := fn (factor int) fn(int) int {
        return fn [factor] (x int) int {
            return x * factor
        }
    }
    
    // Using closures
    println(square(5))
    println(add(5, 3))
    println(complex(5))
    println(operate(6, 7, fn (a int, b int) int { return a * b }))
    println(multiply(5))
    
    double := get_multiplier(2)
    println(double(5))
    
    // Closures with arrays
    numbers := [1, 2, 3, 4, 5]
    doubled := numbers.map(fn (x int) int { return x * 2 })
    filtered := numbers.filter(fn (x int) bool { return x > 2 })
    
    println(doubled)
    println(filtered)
}
Intermediate
16. What are modules in V?

Modules are a way to organize code into reusable units. Each file starts with module name.

  • Definition: module mymodule
  • Export: use pub to make functions/types visible
  • Import: import mymodule
  • Module path: relative to v.mod file
  • Standard library: os, time, net, etc.
vlang
// Scope Functions in V (Vlang)
// V doesn't have built-in scope functions like Kotlin
// But we can use closures and patterns

struct Person {
    name string
    age int
    city string
}

// with - execute block with object
fn with<T, R>(obj T, block fn (T) R) R {
    return block(obj)
}

// also - perform additional operations
fn also<T>(obj T, block fn (T)) T {
    block(obj)
    return obj
}

// let - execute block
fn let<T, R>(obj T, block fn (T) R) R {
    return block(obj)
}

// take-if equivalent
fn take_if<T>(value T, predicate fn (T) bool) ?T {
    if predicate(value) {
        return value
    }
    return none
}

fn main() {
    person := Person{
        name: "Alice",
        age: 25,
        city: "NYC"
    }
    
    // let
    result := let(person, fn (p Person) int {
        println("Name: ${p.name}")
        return p.age + 1
    })
    println("Result: ${result}")
    
    // with
    updated := with(person, fn (mut p Person) {
        p.age = 26
        p.city = "SF"
    })
    println(updated)
    
    // also
    processed := also(person, fn (p Person) {
        println("Before: ${p}")
    })
    println(processed)
    
    // take-if
    adult := take_if(25, fn (age int) bool { return age >= 18 }) or { 0 }
    println("Adult: ${adult}")
}
Intermediate
17. How to import modules in V?

Use the import statement to bring in external modules.

  • Standard library: import os
  • Custom module: import mymodule
  • Alias: import mymodule as m
  • Selective import: import os { getwd }
  • Only for main: module main
vlang
// Extension Methods in V (Vlang)
// V doesn't have extension methods directly
// Using wrapper functions

// String extensions
fn is_email(s string) bool {
    return s.contains("@") && s.contains(".")
}

fn add_prefix(s string, prefix string) string {
    return prefix + s
}

fn word_count(s string) int {
    return s.split(" ").len
}

// Numeric extensions
fn is_even(n int) bool {
    return n % 2 == 0
}

fn is_odd(n int) bool {
    return n % 2 != 0
}

// Array extensions
fn second_or_none<T>(arr []T) ?T {
    if arr.len >= 2 {
        return arr[1]
    }
    return none
}

fn main() {
    email := "test@example.com"
    println(is_email(email))
    
    greeting := add_prefix("Hello", "Greeting: ")
    println(greeting)
    
    println(is_even(5))
    println(word_count("Hello World"))
    
    numbers := [1, 2, 3]
    second := second_or_none(numbers) or { 0 }
    println(second)
}
Intermediate
18. What is the `pub` keyword in V?

The pub keyword makes functions, types, or fields publicly accessible outside the module.

  • Public function: pub fn hello() { ... }
  • Public struct: pub struct Person { ... }
  • Public field: pub field int
  • Private by default: everything is private unless marked pub
  • Re‑export: pub use (to expose items from another module)
vlang
// Type Aliases in V (Vlang)
// Type aliases for complex types
type Operation = fn(int, int) int
type UserMap = map[string]User
type UserId = int
type UserName = string

// Struct for alias example
struct User {
    id UserId
    name UserName
}

// Using type aliases
fn execute(op Operation, a int, b int) int {
    return op(a, b)
}

// Function type alias
type OperationFn = fn(int, int) int

fn add(a int, b int) int { return a + b }
fn multiply(a int, b int) int { return a * b }

// Tuple type alias
type UserInfo = (string, int)

fn main() {
    add_op := fn (a int, b int) int { return a + b }
    multiply_op := fn (a int, b int) int { return a * b }
    
    println(execute(add_op, 5, 3))
    println(execute(multiply_op, 5, 3))
    
    add_fn := add
    multiply_fn := multiply
    
    println(add_fn(5, 3))
    println(multiply_fn(5, 3))
    
    mut users := UserMap{}
    users["user1"] = User{id: 1, name: "Alice"}
    users["user2"] = User{id: 2, name: "Bob"}
    
    user := users["user1"] or { User{id: 0, name: "Unknown"} }
    println("User: ${user.name}")
    
    user_info := UserInfo("Alice", 25)
    println("Name: ${user_info[0]}, Age: ${user_info[1]}")
}
Intermediate
19. What are constants in V?

Constants are immutable values that are known at compile time. They can be primitive types or compile‑time expressions.

  • Single: const PI = 3.14159
  • Block: const ( E = 2.718; G = 9.81 )
  • Computed: const SQUARE = 8 * 8
  • Typed: const MAX int = 100
  • Scope: module‑level (cannot be inside functions)
vlang
// Inline Functions in V (Vlang)
// V doesn't have inline functions like Kotlin
// Using macros and compile-time evaluation

// Simple function (compiler may inline)
fn square(x int) int {
    return x * x
}

// Generic function
fn process<T>(value T, transform fn(T) T) T {
    return transform(value)
}

// Compile-time evaluation
fn measure_time(block fn()) {
    start := time.now()
    block()
    elapsed := time.now() - start
    println("Time: ${elapsed}")
}

// Macro-like function
fn measure<T>(block fn() T) T {
    start := time.now()
    result := block()
    elapsed := time.now() - start
    println("Time: ${elapsed}")
    return result
}

// Usage
fn main() {
    println(square(5))
    
    result := process(5, fn (x int) int { return x * 2 })
    println(result)
    
    measure_time(fn () {
        time.sleep(100 * time.millisecond)
        println("Operation completed")
    })
    
    measured := measure(fn () int {
        time.sleep(100 * time.millisecond)
        return 42
    })
    println("Result: ${measured}")
}
Intermediate
20. How to use pointers in V?

V supports pointers via the & operator and * for dereferencing. Pointers are safe by default.

  • Getting address: p := &x
  • Dereferencing: *p
  • Modifying: *p = 20
  • Struct field access: p.field (automatically dereferenced)
  • Unsafe pointers: unsafe { ... } for low‑level operations
vlang
// Higher-Order Functions in V (Vlang)
fn main() {
    // Function that takes a function as parameter
    apply_operation := fn (a int, b int, op fn(int, int) int) int {
        return op(a, b)
    }
    
    // Function that returns a function
    get_multiplier := fn (factor int) fn(int) int {
        return fn [factor] (x int) int {
            return x * factor
        }
    }
    
    // Function composition
    compose := fn (f fn(int) int, g fn(int) int) fn(int) int {
        return fn (x int) int {
            return f(g(x))
        }
    }
    
    // Higher-order function with multiple closures
    process := fn (value int, transform fn(int) int, filter fn(int) bool) ?int {
        if filter(value) {
            return transform(value)
        }
        return none
    }
    
    // Usage
    result := apply_operation(10, 20, fn (a int, b int) int { return a + b })
    println(result)
    
    double := get_multiplier(2)
    println(double(5))
    
    square := fn (x int) int { return x * x }
    add_ten := fn (x int) int { return x + 10 }
    square_then_add_ten := compose(add_ten, square)
    println(square_then_add_ten(5))
    
    processed := process(5, fn (x int) int { return x * 2 }, fn (x int) bool { return x > 3 }) or { 0 }
    println(processed)
    
    // Iterator higher-order functions
    numbers := [1, 2, 3, 4, 5]
    squared := numbers.map(fn (x int) int { return x * x })
    even := numbers.filter(fn (x int) bool { return x % 2 == 0 })
    sum := numbers.reduce(fn (a int, b int) int { return a + b }, 0)
    
    println(squared)
    println(even)
    println(sum)
}
Advanced
21. What is memory management in V?

V uses automatic memory management based on reference counting, with no GC pause. It also supports manual memory via unsafe code.

  • Reference counting: automatic, deterministic
  • No garbage collector: avoids pauses
  • Heap allocation: via new, arrays, maps, etc.
  • Manual memory: malloc / free inside unsafe
  • Stack allocation: default for local variables
vlang
// Concurrency in V (Vlang)
import time
import sync

// Spawn a thread
fn worker(id int) {
    println("Worker ${id} started")
    time.sleep(500 * time.millisecond)
    println("Worker ${id} finished")
}

// Channel (using shared memory)
fn producer(ch chan int) {
    for i in 0..5 {
        ch <- i
        println("Produced: ${i}")
        time.sleep(100 * time.millisecond)
    }
    close(ch)
}

fn consumer(ch chan int) {
    for {
        value, ok := <- ch
        if !ok {
            break
        }
        println("Consumed: ${value}")
        time.sleep(150 * time.millisecond)
    }
}

// Mutex for shared state
struct Counter {
    mut:
        value int
        mu sync.Mutex
}

fn (mut c Counter) increment() {
    c.mu.lock()
    c.value++
    c.mu.unlock()
}

fn main() {
    // Threads
    mut threads := []thread{}
    for i in 0..3 {
        threads << spawn worker(i)
    }
    
    for t in threads {
        t.wait()
    }
    
    // Channels
    ch := chan int{cap: 10}
    spawn producer(ch)
    spawn consumer(ch)
    
    // Wait for channels
    time.sleep(2 * time.second)
    
    // Mutex
    mut counter := Counter{}
    mut threads2 := []thread{}
    for _ in 0..100 {
        threads2 << spawn fn (mut c Counter) {
            c.increment()
        }(mut counter)
    }
    
    for t in threads2 {
        t.wait()
    }
    
    println("Counter: ${counter.value}")
}
Advanced
22. What are built-in functions in V?

V provides several built‑in functions available in the global namespace.

  • println/print: output
  • len: length of array, string, map
  • panic: halt execution with message
  • assert: debug assertions
  • is/as: type assertions
  • dump: debug print with type information
vlang
// Iterators and Generators in V (Vlang)
// V doesn't have generators, but we can use arrays and custom iterators

// Custom iterator using array
struct Counter {
    max int
    mut:
        current int
}

fn (mut c Counter) next() ?int {
    if c.current < c.max {
        c.current++
        return c.current
    }
    return none
}

// Iterator using range
fn main() {
    // Range iteration
    for i in 0..10 {
        println(i)
    }
    
    // Step iteration
    for i in 0..10 {
        if i % 2 == 0 {
            println(i)
        }
    }
    
    // Custom iterator
    mut counter := Counter{
        max: 5
    }
    for {
        value := counter.next() or { break }
        println(value)
    }
    
    // Array iteration
    numbers := [1, 2, 3, 4, 5]
    for num in numbers {
        println(num)
    }
    
    // Map iteration
    map := {
        "one": 1,
        "two": 2,
        "three": 3
    }
    for key, value in map {
        println("${key}: ${value}")
    }
    
    // Lazy iteration (using filter and map)
    result := numbers.filter(fn (x int) bool { return x % 2 == 0 })
                      .map(fn (x int) int { return x * 2 })
    println(result)
}
Advanced
23. How to work with files in V?

File I/O is provided by the os module. Operations include reading, writing, appending, and deleting.

  • Write: os.write_file("file.txt", "content") or { ... }
  • Read: content := os.read_file("file.txt") or { return }
  • Append: os.append_file("file.txt", "more")
  • Delete: os.rm("file.txt")
  • Check existence: os.exists("file.txt")
vlang
// Channels and Communication in V (Vlang)
import time

// Select statement
fn select_example() {
    ch1 := chan int{cap: 10}
    ch2 := chan int{cap: 10}
    
    spawn fn (ch chan int) {
        time.sleep(500 * time.millisecond)
        ch <- 42
    }(ch1)
    
    spawn fn (ch chan int) {
        time.sleep(300 * time.millisecond)
        ch <- 100
    }(ch2)
    
    for {
        select {
            value := <-ch1 {
                println("Channel 1: ${value}")
            }
            value := <-ch2 {
                println("Channel 2: ${value}")
            }
            timeout: time.after(1000 * time.millisecond) {
                println("Timeout")
                return
            }
        }
    }
}

// Buffered channels
fn buffered_channels() {
    ch := chan int{cap: 3}
    
    ch <- 1
    ch <- 2
    ch <- 3
    
    println(<-ch)
    println(<-ch)
    println(<-ch)
}

// Fan-out pattern
fn fan_out() {
    ch := chan int{cap: 10}
    
    spawn fn (ch chan int) {
        for i in 0..10 {
            ch <- i
        }
        close(ch)
    }(ch)
    
    for i in 0..3 {
        spawn fn (id int, ch chan int) {
            for value := range ch {
                println("Consumer ${id}: ${value}")
                time.sleep(100 * time.millisecond)
            }
        }(i, ch)
    }
    
    time.sleep(2 * time.second)
}

// Fan-in pattern
fn fan_in() {
    ch := chan int{cap: 10}
    
    for i in 0..3 {
        spawn fn (id int, ch chan int) {
            for j in 0..5 {
                ch <- id * 10 + j
                time.sleep(50 * time.millisecond)
            }
        }(i, ch)
    }
    
    for i in 0..15 {
        value := <-ch
        println("Received: ${value}")
    }
}

fn main() {
    select_example()
    buffered_channels()
    fan_out()
    fan_in()
}
Advanced
24. What are channels in V?

Channels are used for communication between coroutines (spawn). They are typed and can be buffered.

  • Creation: ch := chan int{cap: 10}
  • Send: ch <- value
  • Receive: val := <-ch
  • Close: close(ch)
  • Iteration: for val in ch { ... }
vlang
// Enums and Pattern Matching in V (Vlang)
enum Result[T] {
    success(T)
    error(string)
    loading
}

enum Shape {
    circle(radius f64)
    rectangle(width f64, height f64)
    point
}

fn (s Shape) area() f64 {
    return match s {
        Shape.circle(radius) { 3.14159 * radius * radius }
        Shape.rectangle(width, height) { width * height }
        Shape.point { 0.0 }
    }
}

enum Payment {
    cash(amount f64)
    credit_card(number string, expiry string)
    paypal(email string)
}

fn main() {
    result := Result[int].success(200)
    shape := Shape.circle(5.0)
    payment := Payment.credit_card("1234-5678", "12/25")
    
    // Match on result
    match result {
        Result.success(value) { println("Success: ${value}") }
        Result.error(msg) { println("Error: ${msg}") }
        Result.loading { println("Loading...") }
    }
    
    // Match on shape
    match shape {
        Shape.circle(radius) { println("Circle with radius: ${radius}") }
        Shape.rectangle(width, height) { println("Rectangle: ${width}x${height}") }
        Shape.point { println("Point") }
    }
    
    // Match on payment
    match payment {
        Payment.cash(amount) { println("Cash amount: ${amount}") }
        Payment.credit_card(number, expiry) { println("Card: ${number}, Expiry: ${expiry}") }
        Payment.paypal(email) { println("PayPal: ${email}") }
    }
    
    println("Area: ${shape.area()}")
}
Advanced
25. How to spawn coroutines in V?

Use the spawn keyword to run a function concurrently as a coroutine.

  • Syntax: spawn fn() { ... }
  • Passing arguments: spawn worker(1)
  • Lightweight: coroutines are cheap
  • No explicit join: use channels or time to sync
  • Example: spawn fn() { println("Hello from coroutine") }
vlang
// Generics in V (Vlang)
// Generic struct
struct Box[T] {
    value T
}

fn (b Box[T]) get_value() T {
    return b.value
}

// Generic function
fn swap<T>(a T, b T) (T, T) {
    return b, a
}

// Generic with constraints
fn sum_numbers<T>(items []T) T {
    mut sum := 0
    for item in items {
        sum += item
    }
    return sum
}

// Generic with multiple constraints
fn process<T>(value T) string {
    return typeof(value).name
}

// Generic interface
interface Repository[T] {
    get(id int) ?T
    save(item T)
}

struct UserRepository {
    mut:
        users []User
}

fn (mut r UserRepository) get(id int) ?User {
    for user in r.users {
        if user.id == id {
            return user
        }
    }
    return none
}

fn (mut r UserRepository) save(user User) {
    r.users << user
}

struct User {
    id int
    name string
}

// Main
fn main() {
    // Generic struct
    box_int := Box[int]{value: 42}
    box_string := Box[string]{value: "Hello"}
    
    println(box_int.get_value())
    println(box_string.get_value())
    
    // Generic function
    a, b := swap(1, 2)
    println("Swapped: ${a}, ${b}")
    
    // Generic constraints
    numbers := [1, 2, 3, 4, 5]
    // println(sum_numbers(numbers))
    
    // Generic interface
    mut repo := UserRepository{}
    repo.save(User{id: 1, name: "Alice"})
    user := repo.get(1) or { User{id: 0, name: "Unknown"} }
    println("User: ${user.name}")
}
Advanced
26. What is the `defer` statement in V?

defer schedules a block to run when the surrounding function exits, regardless of how it exits.

  • Syntax: defer { ... }
  • Runs at end: even if panic occurs
  • Multiple defers: execute in reverse order (LIFO)
  • Useful for cleanup: closing files, unlocking mutexes
vlang
// Interfaces and Polymorphism in V (Vlang)
// Interface definition
interface Shape {
    area() f64
    perimeter() f64
}

// Circle implementation
struct Circle {
    radius f64
}

fn (c Circle) area() f64 {
    return 3.14159 * c.radius * c.radius
}

fn (c Circle) perimeter() f64 {
    return 2 * 3.14159 * c.radius
}

// Rectangle implementation
struct Rectangle {
    width f64
    height f64
}

fn (r Rectangle) area() f64 {
    return r.width * r.height
}

fn (r Rectangle) perimeter() f64 {
    return 2 * (r.width + r.height)
}

// Triangle implementation
struct Triangle {
    a f64
    b f64
    c f64
}

fn (t Triangle) area() f64 {
    s := (t.a + t.b + t.c) / 2
    return (s * (s - t.a) * (s - t.b) * (s - t.c)).sqrt()
}

fn (t Triangle) perimeter() f64 {
    return t.a + t.b + t.c
}

// Polymorphic function
fn print_shape_info(s Shape) {
    println("Area: ${s.area():.2f}")
    println("Perimeter: ${s.perimeter():.2f}")
}

// Interface with optional methods
interface Drawable {
    draw()
    color() string
}

fn main() {
    shapes := [
        Shape(Circle{radius: 5.0}),
        Shape(Rectangle{width: 4.0, height: 6.0}),
        Shape(Triangle{a: 3.0, b: 4.0, c: 5.0})
    ]
    
    for shape in shapes {
        print_shape_info(shape)
    }
}
Advanced
27. What are enums in V?

Enums define a set of named constants. They can have integer values and are used for type safety.

  • Definition: enum Color { red; green; blue }
  • Values: Color.red, Color.green
  • Custom values: enum Status { success = 200; error = 500 }
  • Conversion: int(Color.red) and Color(int_value)
  • Matching: match c { .red { ... } }
vlang
// Singleton Pattern in V (Vlang)
// Singleton using global variable
struct AppConfig {
    api_url string
    timeout int
}

const config = AppConfig{
    api_url: "https://api.example.com",
    timeout: 5000
}

// Singleton with lazy initialization
struct UserManager {
    mut:
        users []string
}

mut user_manager_instance := UserManager{}

fn get_user_manager() &UserManager {
    return &user_manager_instance
}

// Singleton with mutex
import sync

struct Database {
    mut:
        connected bool
        mu sync.Mutex
}

mut db_instance := &Database{
    connected: false
}

fn get_database() &Database {
    db_instance.mu.lock()
    if !db_instance.connected {
        db_instance.connected = true
        println("Database connected")
    }
    db_instance.mu.unlock()
    return db_instance
}

// Singleton using atomic
struct AtomicSingleton {
    mut:
        data map[string]string
}

atomic_instance := &AtomicSingleton{
    data: map[string]string{}
}

fn get_atomic_singleton() &AtomicSingleton {
    return atomic_instance
}

fn main() {
    // Using const singleton
    println(config.api_url)
    println(config.timeout)
    
    // Using lazy singleton
    manager1 := get_user_manager()
    manager2 := get_user_manager()
    manager1.users << "Alice"
    manager1.users << "Bob"
    println(manager2.users) // ["Alice", "Bob"]
    
    // Using mutex singleton
    db1 := get_database()
    db2 := get_database()
    println(db1.connected)
    println(db2.connected)
}
Advanced
28. What are unions in V?

Unions are sum types that can hold values of different types, similar to tagged unions or enums with payloads.

  • Definition: type MyUnion = int | string
  • Variants: MyUnion(42) or MyUnion("hello")
  • Matching: match u { int { ... } string { ... } }
  • Used for: error handling, AST nodes, etc.
  • Safe: exhaustive match required
  • ````
vlang
// Builder Pattern in V (Vlang)
struct User {
    name string
    age int
    email string
    city string
}

struct UserBuilder {
    mut:
        name string
        age int
        email string
        city string
}

fn UserBuilder.new() UserBuilder {
    return UserBuilder{
        city: "Unknown"
    }
}

fn (mut b UserBuilder) name(name string) &UserBuilder {
    b.name = name
    return b
}

fn (mut b UserBuilder) age(age int) &UserBuilder {
    b.age = age
    return b
}

fn (mut b UserBuilder) email(email string) &UserBuilder {
    b.email = email
    return b
}

fn (mut b UserBuilder) city(city string) &UserBuilder {
    b.city = city
    return b
}

fn (b UserBuilder) build() User {
    return User{
        name: b.name,
        age: b.age,
        email: b.email,
        city: b.city
    }
}

// Query builder
struct Query {
    table string
    fields []string
    conditions []string
    order []string
    limit int
}

struct QueryBuilder {
    mut:
        table string
        fields []string
        conditions []string
        order []string
        limit int
}

fn QueryBuilder.from(table string) QueryBuilder {
    return QueryBuilder{
        table: table
    }
}

fn (mut b QueryBuilder) select(fields ...string) &QueryBuilder {
    b.fields = fields
    return b
}

fn (mut b QueryBuilder) where(condition string) &QueryBuilder {
    b.conditions << condition
    return b
}

fn (mut b QueryBuilder) order_by(field string, asc bool) &QueryBuilder {
    direction := if asc { "ASC" } else { "DESC" }
    b.order << "${field} ${direction}"
    return b
}

fn (mut b QueryBuilder) limit(count int) &QueryBuilder {
    b.limit = count
    return b
}

fn (b QueryBuilder) build() string {
    mut query := "SELECT "
    if b.fields.len == 0 {
        query += "*"
    } else {
        query += b.fields.join(", ")
    }
    query += " FROM ${b.table}"
    if b.conditions.len > 0 {
        query += " WHERE " + b.conditions.join(" AND ")
    }
    if b.order.len > 0 {
        query += " ORDER BY " + b.order.join(", ")
    }
    if b.limit > 0 {
        query += " LIMIT ${b.limit}"
    }
    return query
}

fn main() {
    // User builder
    user := UserBuilder.new()
        .name("Alice")
        .age(25)
        .email("alice@example.com")
        .city("NYC")
        .build()
    
    println(user)
    
    // Query builder
    query := QueryBuilder.from("users")
        .select("name", "age")
        .where("age > 18")
        .order_by("name", true)
        .limit(10)
        .build()
    
    println(query)
}
Advanced
29. How to test code in V?

V has a built‑in test framework. Test files end with _test.v and contain test_* functions.

  • Test function: fn test_my_func() { assert 1 + 1 == 2 }
  • Run tests: v test .
  • Assertions: assert condition
  • Testing module: import testing for advanced assertions
  • Benchmarks: fn benchmark_my_func(b &testing.B) { ... }
vlang
// Macros in V (Vlang)
// V has limited macro support
// Using compile-time code generation

// Simple macro (compile-time function)
fn square(x int) int {
    return x * x
}

// Compile-time evaluation
const PI = 3.14159

// Using comptime for conditional compilation
fn platform_specific() {
    $if windows {
        println("Running on Windows")
    } $else $if linux {
        println("Running on Linux")
    } $else {
        println("Running on unknown OS")
    }
}

// Generic macro for logging
fn log(message string) {
    $if debug {
        println("[DEBUG] ${message}")
    } $else {
        // No debug output
    }
}

// Macro-like function for timing
fn measure<T>(block fn() T) T {
    start := time.now()
    result := block()
    elapsed := time.now() - start
    println("Time: ${elapsed}")
    return result
}

// Assert macro
fn assert_equal<T>(expected T, actual T) {
    if expected != actual {
        println("Assertion failed: expected ${expected}, got ${actual}")
        exit(1)
    }
}

fn main() {
    // Compile-time evaluation
    println("PI: ${PI}")
    
    // Platform-specific code
    platform_specific()
    
    // Debug logging
    log("This is a debug message")
    
    // Timing
    result := measure(fn () int {
        time.sleep(100 * time.millisecond)
        return 42
    })
    println("Result: ${result}")
    
    // Assertion
    assert_equal(5, 5)
    // assert_equal(5, 6) // Would fail
}
Advanced
30. What is the V build system?

V provides a simple, fast build system using the v command. It supports building, running, testing, and cross‑compilation.

  • Build: v build .
  • Run: v run main.v
  • Cross‑compile: v -os windows .
  • Production build: v -prod .
  • With GC: v -gc boehm .
  • Debug: v -g .
vlang
// Reflection in V (Vlang)
// V has limited reflection support
import reflect

struct Person {
    name string
    age int
    email string
}

fn main() {
    person := Person{
        name: "Alice",
        age: 25,
        email: "alice@example.com"
    }
    
    // Type information
    println("Type: ${typeof(person).name}")
    
    // Field iteration
    for field in reflect.fields(person) {
        println("${field.name}: ${field.value}")
    }
    
    // Type checking
    if person is Person {
        println("Is Person")
    }
    
    // Generic type handling
    print_type_info(person)
}

fn print_type_info<T>(value T) {
    println("Type: ${typeof(value).name}")
    $if T is Person {
        println("This is a Person")
        p := value as Person
        println("Name: ${p.name}")
    } $else {
        println("Unknown type")
    }
}
Coding Round
31. Reverse a string

Reverse a string using runes (to handle Unicode) and manual iteration.

  • Runes: s.runes() for Unicode support
  • Manual: Iterate from end to start
  • Return: result.string()
  • Complexity: O(n) time
vlang
// Reverse a string in V (Vlang)
fn reverse_string(s string) string {
    mut runes := s.runes()
    mut result := []rune{}
    for i := runes.len - 1; i >= 0; i-- {
        result << runes[i]
    }
    return result.string()
}

fn main() {
    println(reverse_string("hello")) // "olleh"
}
Coding Round
32. Check palindrome

Check if a string is a palindrome using two-pointer approach on runes.

  • Two-pointer: Compare from both ends
  • Runes: s.runes() for Unicode support
  • Case sensitive: V strings are case sensitive
  • Complexity: O(n) time
vlang
// Check palindrome in V (Vlang)
fn is_palindrome(s string) bool {
    runes := s.runes()
    mut i := 0
    mut j := runes.len - 1
    for i < j {
        if runes[i] != runes[j] {
            return false
        }
        i++
        j--
    }
    return true
}

fn main() {
    println(is_palindrome("racecar")) // true
    println(is_palindrome("hello"))   // false
}
Coding Round
33. Find max in array

Find maximum value using manual iteration.

  • Manual: Iterate and track max
  • Option: Returns ?int for empty array
  • Complexity: O(n) time
  • Return: Max value or none
vlang
// Find max in array in V (Vlang)
fn find_max(arr []int) ?int {
    if arr.len == 0 {
        return none
    }
    mut max := arr[0]
    for num in arr {
        if num > max {
            max = num
        }
    }
    return max
}

fn main() {
    numbers := [1, 5, 3, 9, 2]
    max := find_max(numbers) or { 0 }
    println(max) // 9
}
Coding Round
34. Remove duplicates

Remove duplicates using map to track seen elements.

  • Map: map[int]bool
  • Manual: Iterate and check
  • Complexity: O(n) time
  • Return: Unique array
vlang
// Remove duplicates in V (Vlang)
fn remove_duplicates(arr []int) []int {
    mut seen := map[int]bool{}
    mut result := []int{}
    for item in arr {
        if !seen[item] {
            seen[item] = true
            result << item
        }
    }
    return result
}

fn main() {
    numbers := [1, 2, 2, 3, 3, 4]
    unique := remove_duplicates(numbers)
    println(unique) // [1, 2, 3, 4]
}
Coding Round
35. Merge arrays

Merge arrays using clone() and << operator.

  • clone: arr1.clone()
  • Append: result << arr2
  • Unique merge: Check for duplicates
  • Generic: <T> support
vlang
// Merge arrays in V (Vlang)
fn merge_arrays<T>(arr1 []T, arr2 []T) []T {
    mut result := arr1.clone()
    result << arr2
    return result
}

fn merge_unique(arr1 []int, arr2 []int) []int {
    mut result := arr1.clone()
    for item in arr2 {
        if !result.contains(item) {
            result << item
        }
    }
    return result
}

fn main() {
    arr1 := [1, 2, 3]
    arr2 := [3, 4, 5]
    merged := merge_arrays(arr1, arr2)
    println(merged) // [1, 2, 3, 3, 4, 5]
    
    unique := merge_unique(arr1, arr2)
    println(unique) // [1, 2, 3, 4, 5]
}
Coding Round
36. Convert string to number

Convert string to number using .int() method.

  • .int(): s.int()
  • Option: Returns ?int
  • Error handling: Use or block
  • Return: Number or default
vlang
// Convert string to number in V (Vlang)
fn string_to_number(s string) ?int {
    return s.int()
}

fn main() {
    num := string_to_number("42") or { 0 }
    println(num) // 42
}
Coding Round
37. Loop through map

Iterate through map using for key, value in map.

  • For-in: for key, value in map
  • Keys: map.keys()
  • Values: map.values()
  • Order: Not guaranteed
vlang
// Loop through map in V (Vlang)
fn main() {
    map := {
        "name": "Alice",
        "age": 25,
        "city": "NYC"
    }
    
    for key, value in map {
        println("${key} => ${value}")
    }
}
Coding Round
38. Delay function execution

Delay execution using time.sleep().

  • Sleep: time.sleep(delay_ms * time.millisecond)
  • Blocking: Blocks current thread
  • Async: Use spawn for non-blocking
  • Return: Executes function after delay
vlang
// Delay function execution in V (Vlang)
import time

fn delayed_execution(delay_ms int, fn fn()) {
    time.sleep(delay_ms * time.millisecond)
    fn()
}

fn main() {
    delayed_execution(2000, fn () {
        println("After 2 seconds")
    })
}
Coding Round
39. HTTP GET request

Make HTTP GET requests using net.http module.

  • http.get: http.get(url)
  • Option: Returns ?string
  • Error handling: Use or block
  • Response: response.body
vlang
// HTTP GET request in V (Vlang)
import net.http

fn fetch_data(url string) ?string {
    response := http.get(url)?
    return response.body
}

fn main() {
    data := fetch_data("https://api.example.com/data") or { "" }
    println(data)
}
Coding Round
40. Create a promise‑like Deferred

Create a Deferred using channels for async communication.

  • Channel: chan string{cap: 1}
  • spawn: Run in background
  • Send: ch <- result
  • Receive: <-ch
vlang
// Promise-like Deferred in V (Vlang)
import time

fn create_deferred(should_resolve bool) chan string {
    ch := chan string{cap: 1}
    spawn fn (ch chan string, resolve bool) {
        time.sleep(1000 * time.millisecond)
        if resolve {
            ch <- "Success!"
        } else {
            ch <- "Failed!"
        }
    }(ch, should_resolve)
    return ch
}

fn main() {
    ch := create_deferred(true)
    result := <-ch
    println(result)
}
Coding Round
41. Factorial

Calculate factorial using recursion or iteration.

  • Recursive: n * factorial(n - 1)
  • Base case: n <= 1
  • Iterative: Loop with multiplication
  • Return type: int
vlang
// Factorial in V (Vlang)
fn factorial(n int) int {
    if n <= 1 {
        return 1
    }
    return n * factorial(n - 1)
}

fn main() {
    println(factorial(5)) // 120
}
Coding Round
42. Fibonacci

Calculate Fibonacci using recursion, iteration, or memoization.

  • Recursive: fib(n-1) + fib(n-2)
  • Iterative: Loop with variables
  • Memoization: Cache in map
  • Complexity: O(n) with memoization
vlang
// Fibonacci in V (Vlang)
fn fibonacci(n int) int {
    if n <= 1 {
        return n
    }
    return fibonacci(n - 1) + fibonacci(n - 2)
}

fn main() {
    println(fibonacci(8)) // 21
}
Coding Round
43. FizzBuzz

FizzBuzz using if-else with modulo operations.

  • Modulo: Check divisibility by 3, 5, 15
  • Order: Check 15 first
  • Range: for i in 1..n + 1
  • Output: Print results
vlang
// FizzBuzz in V (Vlang)
fn fizzbuzz(n int) {
    for i in 1..n + 1 {
        if i % 15 == 0 {
            println("FizzBuzz")
        } else if i % 3 == 0 {
            println("Fizz")
        } else if i % 5 == 0 {
            println("Buzz")
        } else {
            println(i)
        }
    }
}

fn main() {
    fizzbuzz(15)
}
Coding Round
44. Find missing number

Find missing number using formula n*(n+1)/2 - sum.

  • Formula: total - sum
  • reduce: arr.reduce(fn (a, b) int { return a + b }, 0)
  • Complexity: O(n) time
  • Return: Missing number
vlang
// Find missing number in V (Vlang)
fn find_missing(arr []int) int {
    n := arr.len + 1
    total := n * (n + 1) / 2
    sum := arr.reduce(fn (a int, b int) int { return a + b }, 0)
    return total - sum
}

fn main() {
    numbers := [1, 2, 4, 5, 6]
    missing := find_missing(numbers)
    println(missing) // 3
}
Coding Round
45. Find duplicates

Find duplicates using map to track seen elements.

  • Map: map[int]bool
  • Track: Mark seen elements
  • Complexity: O(n) time
  • Return: Duplicates array
vlang
// Find duplicates in V (Vlang)
fn find_duplicates(arr []int) []int {
    mut seen := map[int]bool{}
    mut duplicates := []int{}
    for item in arr {
        if seen[item] {
            duplicates << item
        } else {
            seen[item] = true
        }
    }
    return duplicates
}

fn main() {
    numbers := [1, 2, 3, 2, 4, 3]
    dups := find_duplicates(numbers)
    println(dups) // [2, 3]
}
Coding Round
46. Sum of array

Calculate sum using reduce or manual iteration.

  • reduce: arr.reduce(fn (a, b) int { return a + b }, 0)
  • Manual: Loop and accumulate
  • Return type: int
  • Complexity: O(n) time
vlang
// Sum of array in V (Vlang)
fn sum_array(arr []int) int {
    return arr.reduce(fn (a int, b int) int { return a + b }, 0)
}

fn main() {
    numbers := [1, 2, 3, 4, 5]
    sum := sum_array(numbers)
    println(sum) // 15
}
Coding Round
47. Average of array

Calculate average using sum divided by length.

  • Method: sum / arr.len
  • Type: Use f64 for precision
  • Empty array: Return 0.0
  • Return type: f64
vlang
// Average of array in V (Vlang)
fn average_array(arr []f64) f64 {
    if arr.len == 0 {
        return 0.0
    }
    sum := arr.reduce(fn (a f64, b f64) f64 { return a + b }, 0.0)
    return sum / arr.len
}

fn main() {
    numbers := [1.0, 2.0, 3.0, 4.0, 5.0]
    avg := average_array(numbers)
    println(avg) // 3.0
}
Coding Round
48. Sort array ascending

Sort using arr.sort() method.

  • sort(): arr.sort()
  • In-place: Modifies original array
  • Complexity: O(n log n)
  • Return: Sorted array
vlang
// Sort array ascending in V (Vlang)
fn sort_ascending(mut arr []int) {
    arr.sort()
}

fn main() {
    mut numbers := [5, 2, 8, 1, 9]
    sort_ascending(mut numbers)
    println(numbers) // [1, 2, 5, 8, 9]
}
Coding Round
49. Sort array descending

Sort descending using sort() and reverse().

  • sort(): arr.sort()
  • reverse(): arr.reverse()
  • In-place: Modifies original array
  • Complexity: O(n log n)
vlang
// Sort array descending in V (Vlang)
fn sort_descending(mut arr []int) {
    arr.sort()
    arr.reverse()
}

fn main() {
    mut numbers := [5, 2, 8, 1, 9]
    sort_descending(mut numbers)
    println(numbers) // [9, 8, 5, 2, 1]
}
Coding Round
50. Flatten nested array

Flatten a 2D array by concatenating sub‑arrays.

  • Loop: Iterate through sub‑arrays
  • Concatenate: result << sub
  • Complexity: O(n) time
  • Return: Flattened array
vlang
// Flatten nested array in V (Vlang)
fn flatten_array(arr [][]int) []int {
    mut result := []int{}
    for sub in arr {
        result << sub
    }
    return result
}

fn main() {
    nested := [[1, 2], [3, 4], [5, 6]]
    flat := flatten_array(nested)
    println(flat) // [1, 2, 3, 4, 5, 6]
}
Coding Round
51. Chunk array

Split array into chunks of given size.

  • Loop: Iterate with step size
  • Slice: arr[i..i+size]
  • Edge case: Handle last chunk
  • Return: 2D array of chunks
vlang
// Chunk array in V (Vlang)
fn chunk_array(arr []int, size int) [][]int {
    mut chunks := [][]int{}
    mut current := []int{}
    for i, item in arr {
        current << item
        if (i + 1) % size == 0 {
            chunks << current
            current = []
        }
    }
    if current.len > 0 {
        chunks << current
    }
    return chunks
}

fn main() {
    numbers := [1, 2, 3, 4, 5, 6]
    chunks := chunk_array(numbers, 2)
    println(chunks) // [[1, 2], [3, 4], [5, 6]]
}
Coding Round
53. Quick sort

Quick sort using recursion and partitioning.

  • Algorithm: Choose pivot, partition, recurse
  • Time: O(n log n) average
  • Memory: Creates new arrays
  • Return: Sorted array
vlang
// Quick sort in V (Vlang)
fn quick_sort(arr []int) []int {
    if arr.len <= 1 {
        return arr
    }
    pivot := arr[0]
    mut left := []int{}
    mut right := []int{}
    for i in 1..arr.len {
        if arr[i] < pivot {
            left << arr[i]
        } else {
            right << arr[i]
        }
    }
    return quick_sort(left) + [pivot] + quick_sort(right)
}

fn main() {
    numbers := [5, 3, 8, 4, 2, 7, 1, 6]
    sorted := quick_sort(numbers)
    println(sorted)
}
Coding Round
54. Merge sort

Merge sort using divide-and-conquer and merging.

  • Algorithm: Divide, sort, merge
  • Time: O(n log n)
  • Space: O(n) auxiliary space
  • Return: Sorted array
vlang
// Merge sort in V (Vlang)
fn merge_sort(arr []int) []int {
    if arr.len <= 1 {
        return arr
    }
    mid := arr.len / 2
    left := merge_sort(arr[..mid])
    right := merge_sort(arr[mid..])
    return merge(left, right)
}

fn merge(left []int, right []int) []int {
    mut result := []int{}
    mut i := 0
    mut j := 0
    for i < left.len && j < right.len {
        if left[i] <= right[j] {
            result << left[i]
            i++
        } else {
            result << right[j]
            j++
        }
    }
    result << left[i..]
    result << right[j..]
    return result
}

fn main() {
    numbers := [5, 3, 8, 4, 2, 7, 1, 6]
    sorted := merge_sort(numbers)
    println(sorted)
}
Coding Round
55. Bubble sort

Bubble sort with early termination.

  • Algorithm: Compare adjacent, swap
  • Time: O(n²) worst case
  • Optimization: Stop if no swaps
  • In-place: Modifies original array
vlang
// Bubble sort in V (Vlang)
fn bubble_sort(mut arr []int) {
    for i in 0..arr.len - 1 {
        mut swapped := false
        for j in 0..arr.len - i - 1 {
            if arr[j] > arr[j + 1] {
                arr[j], arr[j + 1] = arr[j + 1], arr[j]
                swapped = true
            }
        }
        if !swapped {
            break
        }
    }
}

fn main() {
    mut numbers := [5, 3, 8, 4, 2, 7, 1, 6]
    bubble_sort(mut numbers)
    println(numbers)
}
Coding Round
56. Intersection of arrays

Find common elements using map for membership.

  • Map: map[int]bool
  • Filter: Check if in map
  • Complexity: O(n) time
  • Return: Array of common elements
vlang
// Intersection of arrays in V (Vlang)
fn intersection(arr1 []int, arr2 []int) []int {
    mut set := map[int]bool{}
    for item in arr2 {
        set[item] = true
    }
    mut result := []int{}
    for item in arr1 {
        if set[item] {
            result << item
        }
    }
    return result
}

fn main() {
    arr1 := [1, 2, 3, 4]
    arr2 := [3, 4, 5, 6]
    inter := intersection(arr1, arr2)
    println(inter) // [3, 4]
}
Coding Round
57. Union of arrays

Combine arrays with unique elements using map.

  • Map: map[int]bool
  • Keys: map.keys()
  • Complexity: O(n) time
  • Return: Array of unique elements
vlang
// Union of arrays in V (Vlang)
fn union(arr1 []int, arr2 []int) []int {
    mut set := map[int]bool{}
    for item in arr1 {
        set[item] = true
    }
    for item in arr2 {
        set[item] = true
    }
    mut result := []int{}
    for key in set.keys() {
        result << key
    }
    return result
}

fn main() {
    arr1 := [1, 2, 3]
    arr2 := [3, 4, 5]
    uni := union(arr1, arr2)
    println(uni) // [1, 2, 3, 4, 5]
}
Coding Round
58. Difference of arrays

Find elements in first array not in second using map.

  • Map: map[int]bool
  • Filter: Check if not in map
  • Complexity: O(n) time
  • Return: Array of differences
vlang
// Difference of arrays in V (Vlang)
fn difference(arr1 []int, arr2 []int) []int {
    mut set := map[int]bool{}
    for item in arr2 {
        set[item] = true
    }
    mut result := []int{}
    for item in arr1 {
        if !set[item] {
            result << item
        }
    }
    return result
}

fn main() {
    arr1 := [1, 2, 3, 4]
    arr2 := [3, 4, 5, 6]
    diff := difference(arr1, arr2)
    println(diff) // [1, 2]
}
Coding Round
59. Group by property

Group items by property using map.

  • Map: map[string][]Item
  • Loop: Iterate and group
  • Complexity: O(n) time
  • Return: Map of groups
vlang
// Group by property in V (Vlang)
struct Item {
    type string
    name string
}

fn group_by_property(items []Item, key string) map[string][]Item {
    mut groups := map[string][]Item{}
    for item in items {
        value := if key == "type" { item.type } else { item.name }
        groups[value] << item
    }
    return groups
}

fn main() {
    data := [
        Item{type: "fruit", name: "apple"},
        Item{type: "fruit", name: "banana"},
        Item{type: "veg", name: "carrot"}
    ]
    groups := group_by_property(data, "type")
    for key, items in groups {
        println("${key}: ${items}")
    }
}
Coding Round
60. Deep clone object

Deep clone by manually copying struct fields.

  • Manual: Copy each field
  • Nested: Copy nested structs
  • Return: Independent copy
  • Value types: Structs are value types
vlang
// Deep clone in V (Vlang)
struct Address {
    city string
    zip string
}

struct User {
    name string
    address Address
}

fn deep_clone(user User) User {
    return User{
        name: user.name,
        address: Address{
            city: user.address.city,
            zip: user.address.zip
        }
    }
}

fn main() {
    original := User{
        name: "Alice",
        address: Address{
            city: "NYC",
            zip: "10001"
        }
    }
    cloned := deep_clone(original)
    println(original)
    println(cloned)
}
Coding Round
61. Immutable update

Perform immutable update by creating new struct.

  • New struct: Create with updated fields
  • Return: New immutable object
  • Original: Remains unchanged
  • Value types: Structs are value types
vlang
// Immutable update in V (Vlang)
struct User {
    name string
    age int
}

struct State {
    user User
}

fn update_age(state State, new_age int) State {
    return State{
        user: User{
            name: state.user.name,
            age: new_age
        }
    }
}

fn main() {
    state := State{
        user: User{
            name: "Alice",
            age: 25
        }
    }
    new_state := update_age(state, 26)
    println(state.user.age) // 25
    println(new_state.user.age) // 26
}
Coding Round
62. Pipe function

Pipe composes functions from left to right.

  • Implementation: Loop through functions
  • Generic: <T> support
  • Return: Final result
  • Direction: Left to right
vlang
// Pipe function in V (Vlang)
fn pipe<T>(value T, fns []fn(T) T) T {
    mut result := value
    for fn in fns {
        result = fn(result)
    }
    return result
}

fn double(x int) int { return x * 2 }
fn add_ten(x int) int { return x + 10 }
fn square(x int) int { return x * x }

fn main() {
    process := [double, add_ten, square]
    result := pipe(5, process)
    println(result) // (5*2+10)^2 = 400
}
Coding Round
63. Compose function

Compose functions from right to left.

  • Implementation: Loop in reverse
  • Generic: <T> support
  • Return: Composed function
  • Direction: Right to left
vlang
// Compose function in V (Vlang)
fn compose(fns []fn(int) int) fn(int) int {
    return fn (x int) int {
        mut result := x
        for i := fns.len - 1; i >= 0; i-- {
            result = fns[i](result)
        }
        return result
    }
}

fn double(x int) int { return x * 2 }
fn add_ten(x int) int { return x + 10 }
fn square(x int) int { return x * x }

fn main() {
    process := compose([square, add_ten, double])
    result := process(5)
    println(result) // (5*2+10)^2 = 400
}
Coding Round
64. Memoization

Cache function results based on arguments using map.

  • Map: map[T]U
  • Generic: <T, U> support
  • Return: Cached or computed result
  • Trade-off: Memory for speed
vlang
// Memoization in V (Vlang)
fn memoize<T, U>(fn fn(T) U) fn(T) U {
    mut cache := map[T]U{}
    return fn (arg T) U {
        if arg in cache {
            return cache[arg]
        }
        result := fn(arg)
        cache[arg] = result
        return result
    }
}

fn fibonacci(n int) int {
    if n <= 1 {
        return n
    }
    return fibonacci(n - 1) + fibonacci(n - 2)
}

fn main() {
    fib := memoize(fibonacci)
    println(fib(10)) // 55
}
Coding Round
65. Once function

Ensure a function is called only once using flag.

  • Flag: mut called := false
  • Result: Cache the result
  • Generic: <T> support
  • Use case: Initialization
vlang
// Once function in V (Vlang)
fn once<T>(fn fn() T) fn() T {
    mut called := false
    mut result := T
    return fn () T {
        if !called {
            called = true
            result = fn()
        }
        return result
    }
}

fn main() {
    initialize := once(fn () int {
        println("Initialized")
        return 42
    })
    
    println(initialize())
    println(initialize())
}
Coding Round
66. Debounce with leading edge

Debounce with leading edge using timestamp tracking.

  • Timestamp: Track last call time
  • Delay: Check time difference
  • Execution: Execute if enough time passed
  • Use case: Search input, API calls
vlang
// Debounce in V (Vlang)
import time

fn debounce<T>(delay_ms int, fn fn(T)) fn(T) {
    mut last_call := time.now()
    return fn (arg T) {
        now := time.now()
        if now - last_call >= delay_ms * time.millisecond {
            last_call = now
            fn(arg)
        }
    }
}

fn main() {
    debounced := debounce(1000, fn (msg string) {
        println("Executed: ${msg}")
    })
    
    debounced("First")
    debounced("Second")
    debounced("Third")
}
Coding Round
67. Throttle with leading edge

Throttle with leading edge using timestamp tracking.

  • Timestamp: Track last execution
  • Rate limiting: At most once per period
  • Execution: Execute if enough time passed
  • Use case: Scroll events, resize
vlang
// Throttle in V (Vlang)
import time

fn throttle<T>(delay_ms int, fn fn(T)) fn(T) {
    mut last_call := time.now()
    return fn (arg T) {
        now := time.now()
        if now - last_call >= delay_ms * time.millisecond {
            last_call = now
            fn(arg)
        }
    }
}

fn main() {
    throttled := throttle(1000, fn (msg string) {
        println("Executed: ${msg}")
    })
    
    throttled("First")
    throttled("Second")
    throttled("Third")
}
Coding Round
68. Deep equal

Deep equality comparison using field-by-field comparison.

  • Field comparison: Compare each field
  • Nested: Compare nested structs
  • Return: Boolean result
  • Complexity: O(n) time
vlang
// Deep equal in V (Vlang)
struct Address {
    city string
    zip string
}

struct User {
    name string
    address Address
}

fn deep_equal(a User, b User) bool {
    if a.name != b.name {
        return false
    }
    if a.address.city != b.address.city {
        return false
    }
    if a.address.zip != b.address.zip {
        return false
    }
    return true
}

fn main() {
    user1 := User{
        name: "Alice",
        address: Address{
            city: "NYC",
            zip: "10001"
        }
    }
    user2 := User{
        name: "Alice",
        address: Address{
            city: "NYC",
            zip: "10001"
        }
    }
    println(deep_equal(user1, user2)) // true
}
Coding Round
69. Observable pattern

Observable pattern with subscribers and notifications.

  • Observable: Maintains subscribers
  • Subscribe: Add callback
  • Notify: Call all subscribers
  • Generic: <T> support
vlang
// Observable pattern in V (Vlang)
struct Observable<T> {
    mut:
        subscribers []fn(T)
}

fn (mut o Observable<T>) subscribe(callback fn(T)) {
    o.subscribers << callback
}

fn (o Observable<T>) notify(data T) {
    for subscriber in o.subscribers {
        subscriber(data)
    }
}

fn main() {
    mut observable := Observable[string]{}
    observable.subscribe(fn (data string) {
        println("Observer 1: ${data}")
    })
    observable.subscribe(fn (data string) {
        println("Observer 2: ${data}")
    })
    observable.notify("Hello World")
}
Coding Round
70. Singleton pattern

Singleton pattern using global variable.

  • Global variable: mut instance := Singleton
  • Getter: get_singleton() &Singleton
  • Global access: Through function
  • Lazy: Initialize on first use
vlang
// Singleton pattern in V (Vlang)
struct Singleton {
    mut:
        data []string
}

mut singleton_instance := Singleton{}

fn get_singleton() &Singleton {
    return &singleton_instance
}

fn main() {
    s1 := get_singleton()
    s2 := get_singleton()
    s1.data << "Hello"
    println(s2.data) // ["Hello"]
}
Coding Round
71. Factory pattern

Factory pattern using match statement.

  • Factory function: create_user(type, name)
  • Match: Determine which type to create
  • Interface: interface User
  • Return: User interface
vlang
// Factory pattern in V (Vlang)
interface User {
    name string
    role() string
}

struct Admin {
    name string
}

fn (a Admin) role() string {
    return "admin"
}

struct Guest {
    name string
}

fn (g Guest) role() string {
    return "guest"
}

struct RegularUser {
    name string
}

fn (r RegularUser) role() string {
    return "regular"
}

fn create_user(type string, name string) User {
    match type {
        "admin" { return Admin{name} }
        "guest" { return Guest{name} }
        else { return RegularUser{name} }
    }
}

fn main() {
    admin := create_user("admin", "Alice")
    guest := create_user("guest", "Bob")
    println("${admin.name} role: ${admin.role()}")
    println("${guest.name} role: ${guest.role()}")
}
Coding Round
72. Strategy pattern

Strategy pattern using interfaces.

  • Strategy interface: interface PaymentStrategy
  • Context: Uses strategy
  • Runtime switching: Change strategy
  • Benefits: Encapsulate algorithms
vlang
// Strategy pattern in V (Vlang)
interface PaymentStrategy {
    pay(amount f64)
}

struct CreditCardStrategy {}

fn (c CreditCardStrategy) pay(amount f64) {
    println("Paid $${amount:.2f} with Credit Card")
}

struct PayPalStrategy {}

fn (p PayPalStrategy) pay(amount f64) {
    println("Paid $${amount:.2f} with PayPal")
}

struct CryptoStrategy {}

fn (c CryptoStrategy) pay(amount f64) {
    println("Paid $${amount:.2f} with Crypto")
}

struct PaymentContext {
    mut:
        strategy PaymentStrategy
}

fn (mut c PaymentContext) set_strategy(strategy PaymentStrategy) {
    c.strategy = strategy
}

fn (c PaymentContext) execute_payment(amount f64) {
    c.strategy.pay(amount)
}

fn main() {
    mut context := PaymentContext{
        strategy: CreditCardStrategy{}
    }
    context.execute_payment(100.0)
    
    context.set_strategy(PayPalStrategy{})
    context.execute_payment(50.0)
}
Coding Round
73. Observer pattern

Observer pattern with subject and observers.

  • Subject: Maintains observers
  • Observer interface: interface Observer
  • Attach/Detach: Add/remove observers
  • Notify: Call update on all observers
vlang
// Observer pattern in V (Vlang)
interface Observer {
    update(data string)
}

struct Subject {
    mut:
        observers []Observer
        state string
}

fn (mut s Subject) attach(observer Observer) {
    s.observers << observer
}

fn (mut s Subject) detach(observer Observer) {
    for i in 0..s.observers.len {
        if s.observers[i] == observer {
            s.observers.delete(i)
            break
        }
    }
}

fn (mut s Subject) set_state(state string) {
    s.state = state
    s.notify_observers()
}

fn (s Subject) notify_observers() {
    for observer in s.observers {
        observer.update(s.state)
    }
}

struct ConcreteObserver {
    name string
}

fn (o ConcreteObserver) update(data string) {
    println("${o.name} received: ${data}")
}

fn main() {
    mut subject := Subject{}
    observer1 := ConcreteObserver{name: "Observer1"}
    observer2 := ConcreteObserver{name: "Observer2"}
    subject.attach(observer1)
    subject.attach(observer2)
    subject.set_state("Hello World")
}
Coding Round
74. Decorator pattern

Decorator pattern using wrapper structs.

  • Component: Base interface
  • Decorator: Wraps component
  • Chaining: Multiple decorators
  • Benefits: Add behavior dynamically
vlang
// Decorator pattern in V (Vlang)
interface Coffee {
    cost() f64
    description() string
}

struct SimpleCoffee {}

fn (c SimpleCoffee) cost() f64 {
    return 5.0
}

fn (c SimpleCoffee) description() string {
    return "Coffee"
}

struct MilkDecorator {
    coffee Coffee
}

fn (d MilkDecorator) cost() f64 {
    return d.coffee.cost() + 2.0
}

fn (d MilkDecorator) description() string {
    return d.coffee.description() + ", Milk"
}

struct SugarDecorator {
    coffee Coffee
}

fn (d SugarDecorator) cost() f64 {
    return d.coffee.cost() + 1.0
}

fn (d SugarDecorator) description() string {
    return d.coffee.description() + ", Sugar"
}

fn main() {
    mut coffee := Coffee(SimpleCoffee{})
    coffee = MilkDecorator{coffee}
    coffee = SugarDecorator{coffee}
    println(coffee.description()) // Coffee, Milk, Sugar
    println(coffee.cost()) // 8.0
}
Coding Round
75. Command pattern

Command pattern with execute and undo methods.

  • Command interface: interface Command
  • Receiver: Performs work
  • Invoker: Executes commands
  • Undo/Redo: Command history
vlang
// Command pattern in V (Vlang)
interface Command {
    execute()
    undo()
}

struct AddCommand {
    mut:
        receiver []int
        value int
}

fn (mut c AddCommand) execute() {
    c.receiver << c.value
}

fn (mut c AddCommand) undo() {
    for i in 0..c.receiver.len {
        if c.receiver[i] == c.value {
            c.receiver.delete(i)
            break
        }
    }
}

struct CommandManager {
    mut:
        history []Command
}

fn (mut m CommandManager) execute(cmd Command) {
    cmd.execute()
    m.history << cmd
}

fn (mut m CommandManager) undo() {
    if m.history.len > 0 {
        cmd := m.history.pop()
        cmd.undo()
    }
}

fn main() {
    mut receiver := [1, 2, 3]
    mut manager := CommandManager{}
    cmd := AddCommand{
        receiver: receiver,
        value: 4
    }
    manager.execute(cmd)
    println(receiver) // [1, 2, 3, 4]
    manager.undo()
    println(receiver) // [1, 2, 3]
}
Coding Round
76. Memento pattern

Memento pattern for state capture and restoration.

  • Originator: Creates/restores mementos
  • Memento: Stores state
  • Caretaker: Manages mementos
  • Undo/Redo: State history
vlang
// Memento pattern in V (Vlang)
struct Memento {
    state string
}

struct Originator {
    mut:
        state string
}

fn (o Originator) save_state() Memento {
    return Memento{o.state}
}

fn (mut o Originator) restore_state(m Memento) {
    o.state = m.state
}

struct Caretaker {
    mut:
        mementos []Memento
}

fn (mut c Caretaker) add_memento(m Memento) {
    c.mementos << m
}

fn (c Caretaker) get_memento(index int) ?Memento {
    if index < c.mementos.len {
        return c.mementos[index]
    }
    return none
}

fn main() {
    mut originator := Originator{}
    mut caretaker := Caretaker{}
    
    originator.state = "State 1"
    caretaker.add_memento(originator.save_state())
    
    originator.state = "State 2"
    caretaker.add_memento(originator.save_state())
    
    originator.state = "State 3"
    
    memento := caretaker.get_memento(0) or { Memento{""} }
    originator.restore_state(memento)
    println(originator.state) // State 1
}
Coding Round
77. Mediator pattern

Mediator pattern for centralized communication.

  • Mediator: Encapsulates communication
  • Colleague: Communicates through mediator
  • Benefits: Loose coupling
  • Use case: Chat systems
vlang
// Mediator pattern in V (Vlang)
struct Mediator {
    mut:
        colleagues []Colleague
}

fn (mut m Mediator) register(colleague Colleague) {
    m.colleagues << colleague
    colleague.mediator = m
}

fn (m Mediator) send(message string, sender Colleague) {
    for colleague in m.colleagues {
        if colleague != sender {
            colleague.receive(message)
        }
    }
}

struct Colleague {
    name string
    mediator Mediator
}

fn (c Colleague) send(message string) {
    c.mediator.send(message, c)
}

fn (c Colleague) receive(message string) {
    println("${c.name} received: ${message}")
}

fn main() {
    mut mediator := Mediator{}
    alice := Colleague{name: "Alice"}
    bob := Colleague{name: "Bob"}
    
    mediator.register(alice)
    mediator.register(bob)
    
    alice.send("Hello Bob!")
}
Coding Round
78. Chain of Responsibility

Chain of Responsibility using interface.

  • Handler interface: interface Handler
  • Chain: Link handlers
  • Benefits: Decoupling
  • Use case: Logging, authentication
vlang
// Chain of Responsibility in V (Vlang)
interface Handler {
    set_next(handler Handler)
    handle(request string) ?string
}

struct AuthHandler {
    mut:
        next Handler
}

fn (mut a AuthHandler) set_next(handler Handler) {
    a.next = handler
}

fn (a AuthHandler) handle(request string) ?string {
    if request.contains("token") {
        println("Authentication passed")
        if a.next != 0 {
            return a.next.handle(request)
        }
        return "Success"
    }
    println("Authentication failed")
    return none
}

struct LoggerHandler {
    mut:
        next Handler
}

fn (mut l LoggerHandler) set_next(handler Handler) {
    l.next = handler
}

fn (l LoggerHandler) handle(request string) ?string {
    println("Logging request: ${request}")
    if l.next != 0 {
        return l.next.handle(request)
    }
    return "Logged"
}

fn main() {
    mut auth := AuthHandler{}
    mut logger := LoggerHandler{}
    auth.set_next(logger)
    result := auth.handle("token:valid") or { "Failed" }
    println(result)
}
Coding Round
79. State pattern

State pattern using interface.

  • State interface: interface State
  • Context: Maintains state
  • Transitions: Change between states
  • Benefits: Clean state management
vlang
// State pattern in V (Vlang)
interface State {
    handle(context Context)
}

struct Context {
    mut:
        state State
}

fn (mut c Context) set_state(state State) {
    c.state = state
}

fn (c Context) request() {
    c.state.handle(c)
}

struct ReadyState {}

fn (r ReadyState) handle(mut c Context) {
    println("Ready: Waiting for input")
    c.set_state(ProcessingState{})
}

struct ProcessingState {}

fn (p ProcessingState) handle(mut c Context) {
    println("Processing: Working on task")
    c.set_state(CompletedState{})
}

struct CompletedState {}

fn (c CompletedState) handle(mut ctx Context) {
    println("Completed: Task finished")
}

fn main() {
    mut context := Context{
        state: ReadyState{}
    }
    context.request() // Ready
    context.request() // Processing
    context.request() // Completed
}
Coding Round
80. Proxy pattern

Proxy pattern using interface.

  • Subject interface: interface Subject
  • Proxy: Controls access
  • Lazy loading: Create on demand
  • Benefits: Access control, logging
vlang
// Proxy pattern in V (Vlang)
interface Subject {
    request() string
}

struct RealSubject {}

fn (r RealSubject) request() string {
    return "RealSubject: Handling request"
}

struct Proxy {
    mut:
        real_subject RealSubject
}

fn (p Proxy) request() string {
    if p.check_access() {
        return p.real_subject.request()
    }
    return "Proxy: Access denied"
}

fn (p Proxy) check_access() bool {
    println("Proxy: Checking access")
    return true
}

fn main() {
    proxy := Proxy{}
    println(proxy.request())
}
Coding Round
81. Flyweight pattern

Flyweight pattern for sharing objects using map.

  • Flyweight: Shared object
  • Factory: Manages flyweights
  • Benefits: Memory optimization
  • Use case: Character rendering
vlang
// Flyweight pattern in V (Vlang)
struct Flyweight {
    shared_state string
}

fn (f Flyweight) operation(unique_state string) {
    println("Shared: ${f.shared_state}, Unique: ${unique_state}")
}

struct FlyweightFactory {
    mut:
        flyweights map[string]Flyweight
}

fn (mut f FlyweightFactory) get_flyweight(shared_state string) Flyweight {
    if shared_state in f.flyweights {
        return f.flyweights[shared_state]
    }
    flyweight := Flyweight{shared_state}
    f.flyweights[shared_state] = flyweight
    println("Creating new flyweight for: ${shared_state}")
    return flyweight
}

fn main() {
    mut factory := FlyweightFactory{}
    fw1 := factory.get_flyweight("state1")
    fw2 := factory.get_flyweight("state1")
    fw3 := factory.get_flyweight("state2")
    fw1.operation("unique1")
    fw2.operation("unique2")
    fw3.operation("unique3")
}
Coding Round
82. Bridge pattern

Bridge pattern for separating abstraction from implementation.

  • Abstraction: High-level interface
  • Implementation: Low-level operations
  • Benefits: Separation of concerns
  • Use case: Cross-platform
vlang
// Bridge pattern in V (Vlang)
interface Implementation {
    operation_impl() string
}

struct ConcreteImplementationA {}

fn (c ConcreteImplementationA) operation_impl() string {
    return "ConcreteImplementationA: Operation"
}

struct ConcreteImplementationB {}

fn (c ConcreteImplementationB) operation_impl() string {
    return "ConcreteImplementationB: Operation"
}

struct Abstraction {
    impl Implementation
}

fn (a Abstraction) operation() string {
    return "Abstraction: Additional logic - " + a.impl.operation_impl()
}

fn main() {
    impl_a := ConcreteImplementationA{}
    impl_b := ConcreteImplementationB{}
    abstraction1 := Abstraction{impl_a}
    abstraction2 := Abstraction{impl_b}
    println(abstraction1.operation())
    println(abstraction2.operation())
}
Coding Round
83. Adapter pattern

Adapter pattern for converting interfaces.

  • Target: Expected interface
  • Adaptee: Existing interface
  • Adapter: Bridges interfaces
  • Benefits: Reusability
vlang
// Adapter pattern in V (Vlang)
interface Target {
    request() string
}

struct Adaptee {}

fn (a Adaptee) specific_request() string {
    return "Adaptee: Specific Request"
}

struct Adapter {
    adaptee Adaptee
}

fn (a Adapter) request() string {
    return a.adaptee.specific_request()
}

fn main() {
    adaptee := Adaptee{}
    adapter := Adapter{adaptee}
    println(adapter.request())
}
Coding Round
84. Facade pattern

Facade pattern for simplifying subsystems.

  • Facade: Simplified interface
  • Subsystem: Complex components
  • Benefits: Simplified interface
  • Use case: Library APIs
vlang
// Facade pattern in V (Vlang)
struct SubsystemA {}

fn (s SubsystemA) operation_a() string {
    return "SubsystemA: Operation"
}

struct SubsystemB {}

fn (s SubsystemB) operation_b() string {
    return "SubsystemB: Operation"
}

struct SubsystemC {}

fn (s SubsystemC) operation_c() string {
    return "SubsystemC: Operation"
}

struct Facade {
    a SubsystemA
    b SubsystemB
    c SubsystemC
}

fn (f Facade) operation() string {
    return f.a.operation_a() + " + " + f.b.operation_b() + " + " + f.c.operation_c()
}

fn main() {
    facade := Facade{}
    println(facade.operation())
}
Coding Round
85. Composite pattern

Composite pattern for tree structures.

  • Component: Interface for all
  • Leaf: Individual object
  • Composite: Container
  • Benefits: Uniform interface
vlang
// Composite pattern in V (Vlang)
interface Component {
    operation() string
}

struct Leaf {
    name string
}

fn (l Leaf) operation() string {
    return "Leaf ${l.name}: Operation"
}

struct Composite {
    name string
    mut:
        children []Component
}

fn (mut c Composite) add(component Component) {
    c.children << component
}

fn (c Composite) operation() string {
    mut result := "Composite ${c.name}: ["
    for child in c.children {
        result += child.operation() + ", "
    }
    result += "]"
    return result
}

fn main() {
    leaf1 := Leaf{"A"}
    leaf2 := Leaf{"B"}
    mut composite := Composite{name: "Root"}
    composite.add(leaf1)
    composite.add(leaf2)
    println(composite.operation())
}
Coding Round
86. Visitor pattern

Visitor pattern for adding operations without modifying elements.

  • Visitor: Defines operations
  • Element: Accepts visitors
  • Benefits: Adding operations without modifying
  • Use case: Compilers, AST
vlang
// Visitor pattern in V (Vlang)
interface Visitor {
    visit_element_a(element ElementA) string
    visit_element_b(element ElementB) string
}

interface Element {
    accept(visitor Visitor) string
}

struct ElementA {
    data string
}

fn (e ElementA) accept(visitor Visitor) string {
    return visitor.visit_element_a(e)
}

struct ElementB {
    data string
}

fn (e ElementB) accept(visitor Visitor) string {
    return visitor.visit_element_b(e)
}

struct ConcreteVisitor {}

fn (c ConcreteVisitor) visit_element_a(e ElementA) string {
    return "Visiting ElementA with data: ${e.data}"
}

fn (c ConcreteVisitor) visit_element_b(e ElementB) string {
    return "Visiting ElementB with data: ${e.data}"
}

fn main() {
    visitor := ConcreteVisitor{}
    element_a := ElementA{"A data"}
    element_b := ElementB{"B data"}
    println(element_a.accept(visitor))
    println(element_b.accept(visitor))
}
Coding Round
87. Iterator pattern

Iterator pattern for sequential access.

  • Iterator: Traverses collection
  • has_next: Check for more items
  • next: Return next item
  • Generic: <T> support
vlang
// Iterator pattern in V (Vlang)
struct Iterator<T> {
    collection []T
    mut:
        index int
}

fn (mut i Iterator<T>) next() ?T {
    if i.index < i.collection.len {
        value := i.collection[i.index]
        i.index++
        return value
    }
    return none
}

fn (i Iterator<T>) has_next() bool {
    return i.index < i.collection.len
}

struct Collection<T> {
    items []T
}

fn (c Collection<T>) iterator() Iterator<T> {
    return Iterator<T>{c.items}
}

fn main() {
    collection := Collection<int>{[1, 2, 3, 4, 5]}
    mut iter := collection.iterator()
    for iter.has_next() {
        value := iter.next() or { break }
        println(value)
    }
}
Coding Round
88. Template Method pattern

Template Method for algorithm skeletons.

  • AbstractClass: Defines template
  • ConcreteClass: Implements steps
  • Benefits: Code reuse
  • Use case: Frameworks
vlang
// Template Method pattern in V (Vlang)
interface AbstractClass {
    template_method() string
    step1() string
    step2() string
    step3() string
}

fn (a AbstractClass) template_method() string {
    return a.step1() + " -> " + a.step2() + " -> " + a.step3()
}

struct ConcreteClass {}

fn (c ConcreteClass) step1() string {
    return "Step 1"
}

fn (c ConcreteClass) step2() string {
    return "Concrete Step 2"
}

fn (c ConcreteClass) step3() string {
    return "Step 3"
}

fn main() {
    concrete := ConcreteClass{}
    println(concrete.template_method())
}
Coding Round
89. Builder pattern

Builder pattern for constructing complex objects.

  • Builder: Constructs parts
  • Director: Orchestrates construction
  • Product: Constructed object
  • Benefits: Step-by-step construction
vlang
// Builder pattern in V (Vlang)
struct Product {
    mut:
        parts []string
}

fn (mut p Product) add(part string) {
    p.parts << part
}

fn (p Product) list_parts() string {
    return p.parts.join(", ")
}

struct Builder {
    mut:
        product Product
}

fn (mut b Builder) reset() {
    b.product = Product{}
}

fn (mut b Builder) build_step_a() {
    b.product.add("Part A")
}

fn (mut b Builder) build_step_b() {
    b.product.add("Part B")
}

fn (b Builder) get_result() Product {
    return b.product
}

struct Director {
    builder Builder
}

fn (d Director) build_minimal() {
    d.builder.build_step_a()
}

fn (d Director) build_full() {
    d.builder.build_step_a()
    d.builder.build_step_b()
}

fn main() {
    mut builder := Builder{}
    director := Director{builder}
    director.build_minimal()
    product := builder.get_result()
    println(product.list_parts()) // Part A
}
Coding Round
90. Prototype pattern

Prototype pattern for cloning objects.

  • Prototype: Cloneable object
  • Clone: Creates a copy
  • Deep clone: Recursive copy
  • Benefits: Object reuse, performance
vlang
// Prototype pattern in V (Vlang)
struct Prototype {
    name string
    nested map[string]int
}

fn (p Prototype) clone() Prototype {
    return Prototype{
        name: p.name,
        nested: p.nested
    }
}

fn (p Prototype) deep_clone() Prototype {
    mut new_nested := map[string]int{}
    for key, value in p.nested {
        new_nested[key] = value
    }
    return Prototype{
        name: p.name,
        nested: new_nested
    }
}

fn main() {
    original := Prototype{
        name: "Original",
        nested: {"value": 42}
    }
    copy := original.clone()
    copy.nested["value"] = 99
    println(original.nested) // {"value": 42}
    
    deep_copy := original.deep_clone()
    deep_copy.nested["value"] = 100
    println(original.nested) // {"value": 42}
}
Coding Round
91. Error Handling

Error handling using option types and custom errors.

  • Option types: ?int
  • or block: or { err }
  • Custom errors: struct ValidationError
  • Error propagation: Return ?
vlang
// Error Handling in V (Vlang)
// Custom error type
struct ValidationError {
    field string
    message string
}

fn (e ValidationError) str() string {
    return "Validation error in ${e.field}: ${e.message}"
}

// Function returning option
fn validate_age(age int) ? {
    if age < 0 {
        return error("Age cannot be negative")
    }
    if age > 150 {
        return error("Invalid age")
    }
}

// Using with or block
fn main() {
    err := validate_age(25) or {
        println("Error: ${err}")
        return
    }
    println("Age is valid")
    
    // Using if
    if err := validate_age(-5) {
        println("Valid")
    } else {
        println("Invalid")
    }
    
    // Custom error type
    fn validate_email(email string) ? {
        if !email.contains("@") {
            return ValidationError{"email", "Invalid email format"}
        }
    }
    
    err2 := validate_email("invalid") or {
        println("Error: ${err}")
        return
    }
}
Coding Round
92. File I/O

File I/O operations using os module.

  • Write: os.write_file()
  • Read: os.read_file()
  • Append: os.append_file()
  • Delete: os.rm()
vlang
// File I/O in V (Vlang)
import os

fn main() {
    // Write to file
    content := "Hello, World!"
    os.write_file("hello.txt", content) or {
        println("Error writing file: ${err}")
        return
    }
    println("File written successfully")
    
    // Read from file
    data := os.read_file("hello.txt") or {
        println("Error reading file: ${err}")
        return
    }
    println("File content: ${data}")
    
    // Append to file
    os.append_file("hello.txt", "
Appended line") or {
        println("Error appending: ${err}")
        return
    }
    
    // Check if file exists
    if os.exists("hello.txt") {
        println("File exists")
    }
    
    // Delete file
    os.rm("hello.txt") or {
        println("Error deleting file: ${err}")
        return
    }
}
Coding Round
93. JSON Handling

JSON serialization and deserialization using json module.

  • Encode: json.encode()
  • Decode: json.decode()
  • Struct tags: Field names match JSON
  • Error handling: Use or block
vlang
// JSON Handling in V (Vlang)
import json

struct User {
    name string
    age int
    email string
}

fn main() {
    // Serialize to JSON
    user := User{
        name: "Alice",
        age: 25,
        email: "alice@example.com"
    }
    json_data := json.encode(user)
    println(json_data)
    
    // Deserialize from JSON
    json_str := '{"name":"Bob","age":30,"email":"bob@example.com"}'
    parsed := json.decode(User, json_str) or {
        println("Error parsing JSON: ${err}")
        return
    }
    println("Name: ${parsed.name}, Age: ${parsed.age}")
}
Coding Round
94. Database Operations

Database operations using db.sqlite module.

  • Connect: sqlite.connect()
  • Create table: db.exec()
  • Insert: db.exec() with parameters
  • Query: db.query()
vlang
// Database Operations in V (Vlang)
import db.sqlite

struct User {
    id int
    name string
    age int
    email string
}

fn main() {
    // Open database
    db := sqlite.connect("test.db") or {
        println("Error connecting to database: ${err}")
        return
    }
    defer {
        db.close() or { println("Error closing database: ${err}") }
    }
    
    // Create table
    db.exec("CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT, age INTEGER, email TEXT)") or {
        println("Error creating table: ${err}")
        return
    }
    
    // Insert data
    db.exec("INSERT INTO users (name, age, email) VALUES (?, ?, ?)", "Alice", 25, "alice@example.com") or {
        println("Error inserting data: ${err}")
        return
    }
    
    // Query data
    rows := db.query("SELECT id, name, age, email FROM users") or {
        println("Error querying data: ${err}")
        return
    }
    
    for row in rows {
        println("ID: ${row.id}, Name: ${row.name}, Age: ${row.age}, Email: ${row.email}")
    }
}
Coding Round
95. Testing

Testing using V's built-in test framework.

  • Test files: _test.v
  • Test functions: fn test_name()
  • Assertions: assert condition
  • Run tests: v test .
vlang
// Testing in V (Vlang)
// test file: main_test.v
/*
import testing

fn test_add() {
    assert add(2, 3) == 5
    assert add(-1, 1) == 0
}

fn test_divide() {
    assert divide(10, 2) == 5
    assert divide(10, 0) == 0 // Should handle division by zero
}
*/

// Example functions to test
fn add(a int, b int) int {
    return a + b
}

fn divide(a int, b int) int {
    if b == 0 {
        return 0
    }
    return a / b
}

fn main() {
    println("Running tests...")
    // In V, tests are run with: v test .
}
Coding Round
96. Web Server

Web server using net.http.server module.

  • Server: server.Server{port: 8080}
  • Handle: server.handle("/", fn)
  • Request: http.Request
  • Response: res.write()
vlang
// Web Server in V (Vlang)
import net.http
import net.http.server

// Simple HTTP server
fn main() {
    mut server := server.Server{
        port: 8080
    }
    
    server.handle("/", fn (req http.Request, res mut http.Response) {
        res.write("Hello, World!")
    })
    
    server.handle("/api/users", fn (req http.Request, res mut http.Response) {
        users := '[{"name":"Alice","age":25},{"name":"Bob","age":30}]'
        res.headers.set("Content-Type", "application/json")
        res.write(users)
    })
    
    println("Server running on http://localhost:8080")
    server.serve() or {
        println("Error starting server: ${err}")
    }
}
Coding Round
97. CLI Application

CLI application using flag module.

  • Flag parser: flag.new_flag_parser()
  • String flag: fp.string()
  • Int flag: fp.int()
  • Bool flag: fp.bool()
vlang
// CLI Application in V (Vlang)
import os
import flag

fn main() {
    mut fp := flag.new_flag_parser(os.args)
    name := fp.string("name", 'n', "", "Name to greet")
    age := fp.int("age", 'a', 0, "Age of the person")
    verbose := fp.bool("verbose", 'v', false, "Verbose output")
    
    if name == "" {
        println("Usage: app -name <name> -age <age> -v")
        return
    }
    
    if verbose {
        println("Name: ${name}")
        println("Age: ${age}")
    }
    
    println("Hello, ${name}! You are ${age} years old.")
}
Coding Round
98. Modules and Packages

Creating and using modules with pub keyword.

  • Module: module name
  • Export: pub fn
  • Import: import module
  • Usage: module.function()
vlang
// Modules and Packages in V (Vlang)
// math.v (module)
module math

pub fn add(a int, b int) int {
    return a + b
}

pub fn subtract(a int, b int) int {
    return a - b
}

// main.v
import math

fn main() {
    println(math.add(5, 3)) // 8
    println(math.subtract(10, 4)) // 6
}
Coding Round
99. Generics and Type Constraints

Generics with type constraints in V.

  • Generic struct: struct Box[T]
  • Generic function: fn sum<T>(a T, b T) T
  • Multiple types: fn swap[T, U]
  • Type inference: Automatically inferred
vlang
// Generics and Type Constraints in V (Vlang)
// Generic struct
struct Box[T] {
    value T
}

fn (b Box[T]) get() T {
    return b.value
}

// Generic function with constraints
fn sum_numbers<T>(a T, b T) T {
    return a + b
}

// Generic with multiple types
fn swap<T, U>(a T, b U) (U, T) {
    return b, a
}

// Main
fn main() {
    box_int := Box[int]{42}
    box_string := Box[string]{"Hello"}
    println(box_int.get()) // 42
    println(box_string.get()) // Hello
    
    println(sum_numbers(5, 3)) // 8
    println(sum_numbers(10.5, 3.5)) // 14.0
    
    a, b := swap(1, "Hello")
    println("${a}, ${b}") // Hello, 1
}
Coding Round
100. V Best Practices

Best practices for writing clean, efficient V code.

  • Immutability: Use immutable variables by default
  • Option types: Use for nullable values
  • Match: Use exhaustive pattern matching
  • Structs: Use for data grouping
  • Interfaces: Use for polymorphism
vlang
// V Best Practices
// 1. Use immutability by default
fn main() {
    // Immutable variables (default)
    name := "Alice"
    // name = "Bob" // Error: cannot assign to immutable variable
    
    // Mutable variables
    mut age := 25
    age++
    
    // 2. Use option types for nullable values
    maybe_string := ?string("Hello")
    value := maybe_string or { "default" }
    println(value)
    
    // 3. Use match for exhaustive pattern matching
    status := "active"
    match status {
        "active" { println("Active") }
        "inactive" { println("Inactive") }
        else { println("Unknown") }
    }
    
    // 4. Use structs for data grouping
    person := Person{
        name: "Alice",
        age: 25
    }
    
    // 5. Use interfaces for polymorphism
    // 6. Use channels for concurrency
    // 7. Use defer for cleanup
    defer {
        println("Cleanup")
    }
    
    // 8. Use const for constants
    const PI = 3.14159
    
    // 9. Use enums for fixed values
    // 10. Use sum types for sealed classes
}