v
v copied to clipboard
ast, checker, cgen: change option to result in index and channel (part 1)
This PR change option to result in index and channel (part 1).
Why though? I think an option is enough for indexing. The only possible error is index out of range.
An option is smaller and more performant.
@spytheman what do you think?
For consistency, range_index is required. The original processing actually returned an error. e.g.
g.writeln('} else {')
g.writeln('\t${tmp_opt}.state = 2; ${tmp_opt}.err = _v_error(_SLIT("array index out of range"));')
@medvednikov consider this:
mut a := []?int{len: 5}
a[1] = 123
a[3] = 456
dump(a)
which produces:
[a.v:4] a: [Option(0), Option(123), Option(0), Option(456), Option(0)]
(which should have been all nones actually, I'll file an issue soon; done in: https://github.com/vlang/v/issues/17532 )
What will a[0] be?
It should be none, but if a[0] returns none internally for the index out of range situation, there is no way to distinguish the two.
If however, it returned an error instead, it will work:
x := a[9999] or { panic(err) } will handle the out of range error, while:
y := x? will handle the possible none value.
What's the usecase for an array of options? I'd rather ban that than make arrays slower and more complex.
In index we can distinguish between negative value or larger than the range.
That's how it works in Rust as well. array.get() returns an Option there:
https://doc.rust-lang.org/std/vec/struct.Vec.html#method.get
i < 0 or i > len is still the same error: out of bounds
What's the usecase for an array of options? I'd rather ban that than make arrays slower and more complex.
For example, an array of thread results, where each thread can either produce a value or none.
fn work(params Params) ?Something {...}
for { ...
threads << spawn work(params)
}
all := threads.wait()
=> all will be of type []?Something , where each one could be either Something or none.
make arrays slower
I was wrong, it is used not for x := a[i] or { default } but for strings: r := s[i] or { default_rune } - string_at_with_check.
It is not used for just a[i] - that is array_get(a, i), nor for just s[i] - that is string_at(s, i) .
Ok, let's allow array of options. But arr[idx] should still return an option.
We have to somehow make your example with mut a := []?int{len: 5} work. I wonder how it's done in Rust.
I'm strongly against using Result for this.
For string.at_with_check, I do agree, that it should return an option and none instead of the error, since the individual elements are concrete bytes/runes, so there is no confusion possible when using it.