vlang

/

v Public
0 commits 39 issues 0 pull requests 0 contributors Discussions Projects CI

Inline error/option propagation #27

Describe the feature

It would be useful if errors/optional values could be propagated not just out of a function but also along a single line, having syntax sugar for things such as accessing a field in an optional struct without having to either explicit none checking or creating an instance of the struct in an or block.

Use Case

I have encountered cases similar to the following example in a few codebases and have often wished for a simpler way of accessing a deeply nested property without repeating many none/error checks.

Proposed Solution

module main

struct Foo {
    property string
}

fn main() {
    // Optional map of structs
    data := get_data()
    target := 'one'

    // Two points of failure, either data could be none or the target struct could not exist
    // Current way to handle this, both with an explicit none check and creating an instance of Foo only to access one property
    if data != none {
        println(data[target] or {
            Foo{'item not found'}
        }.property)
    }

    // Another way to handle it without creating a new Foo when not found, but requires more verbose error checking
    if data != none {
        if item := data[target] {
            println(item.property)
        } else {
            println('item not found')
        }
    }

    // A potential way it could be streamlined by propagating the error in the same line, handled by a single or block at the end
    println(data?[target]?.property or { 'item not found' })
}

fn get_data() ?map[string]Foo {
    return {
        'one': Foo{'item1'}
        'two': Foo{'item2'}
        'three': Foo{'item3'}
    }
}

Other Information

The example may conflict with existing syntax or introduce ambiguity in certain cases, and would also need to strike a good balance between convenience and not hiding too much complexity. Curious to hear any thoughts as to if this is a good design or not.

Acknowledgements

  • [ ] I may be able to implement this feature request
  • [x] This feature might incur a breaking change

Version used

master

Environment details (OS name and version, etc.)

|V full version |V 0.5.1 1b3385cc34ff783e793d1a26a8ec5be587c80fe0.b0e0a1e |:-------------------|:------------------- |OS |linux, "Linux" |Processor |12 cpus, 64bit, little endian, AMD Ryzen 5 7640U w/ Radeon 760M Graphics |Memory |0.83GB/14.93GB | | |V executable |/home/sirsegv/.v/v |V last modified time|2026-05-28 07:04:42 | | |V home dir |OK, value: /home/sirsegv/.v |VMODULES |OK, value: /home/sirsegv/.vmodules |VTMP |OK, value: /tmp/v_1000 |Current working dir |OK, value: /home/sirsegv | | |Git version |git version 2.54.0 |V git status |0.5.1-1772-gb0e0a1e9 |.git/config present |true | | |cc version |cc (GCC) 16.1.1 20260430 |gcc version |gcc (GCC) 16.1.1 20260430 |clang version |clang version 22.1.5 |tcc version |tcc version 0.9.28rc 2025-02-13 HEAD@f8bd136d (x86_64 Linux) |tcc git status |thirdparty-linux-amd64 696c1d84 |emcc version |N/A |glibc version |ldd (GNU libc) 2.43

[!NOTE] You can use the 👍 reaction to increase the issue's priority for developers.

Please note that only the 👍 reaction to the issue itself counts as a vote. Other reactions and those to comments will not be taken into account.