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.