vlang / v

Simple, fast, safe, compiled language for developing maintainable software. Compiles itself in <1s with zero library dependencies. Supports automatic C => V translation. https://vlang.io
MIT License
35.88k stars 2.17k forks source link

arrays.sum([]) or {panic(err)} produces a misleading/obscure error message: #22859

Open holder66 opened 2 weeks ago

holder66 commented 2 weeks ago

Describe the bug

arrays.sum([]) or {panic(err)} returns "/v/vlib/arrays/arrays.v:253:4: error: operator += not defined on left operand type T"

Reproduction Steps

arrays.sum([]) or {panic(err)}

Expected Behavior

I would like to see an error message about the array being empty

Current Behavior

v/vlib/arrays/arrays.v:253:4: error: operator += not defined on left operand type T

Possible Solution

No response

Additional Information/Context

No response

V version

Current V version: V 0.4.8 df51e84, timestamp: 2024-11-14 13:58:50 +0200

Environment details (OS name and version, etc.)

V full version: V 0.4.8 dad8e3c.df51e84 OS: macos, macOS, 15.0.1, 24A348 Processor: 16 cpus, 64bit, little endian, Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz

getwd: /Users/henryolders vexe: /Users/henryolders/v/v vexe mtime: 2024-11-14 15:14:24

vroot: OK, value: /Users/henryolders/v VMODULES: OK, value: /Users/henryolders/.vmodules VTMP: OK, value: /tmp/v_507

env VFLAGS: "-use-os-system-to-run"

Git version: git version 2.47.0 Git vroot status: weekly.2024.06-1635-gdf51e840 .git/config present: true

CC version: Apple clang version 16.0.0 (clang-1600.0.26.4) emcc version: N/A thirdparty/tcc status: thirdparty-macos-amd64 975f1ad8

[!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.

Huly®: V_0.6-21302

jorgeluismireles commented 2 weeks ago

I think you need to specify the generic type of the argument. Once specified the type of an empty array then you got a panic with more information: Cannot sum up array of nothing. The generic type must overload the addition operator +. Types int, f32 and the like will work. For other types you need to do something like this:

import arrays

struct Str {
    s string
}

fn (m Str) + (n Str) Str {
    return Str{ m.s + n.s }
}

s1 := arrays.sum([Str{'a'},Str{'b'},Str{'c'}])!
println('${s1.s}') // prints: 'abc'

if s2 := arrays.sum([]Str{}) {
    println('${s2.s}') //
} else {
    println('${err}') // prints: Cannot sum up array of nothing
}

See https://play.vlang.io/p/594631bd45

JalonSolov commented 2 weeks ago

Yes, specifying the type fixes the code, but it doesn't change the fact that the error message is confusing because it doesn't point to your source, it points to a stdlib routine that you can't control.

Error messages should tell you what in your source caused the problem, not where it eventually failed.

jorgeluismireles commented 2 weeks ago

Maybe the compiler should notify first Cannot sum up array of nothing in the line arrays.sum([]).

Then in the case the user adds elements of type not overriding + like a mere string arrays.sum(['a','b']) notify error: operator += not defined on left operand type string. Actually is not clear that overriding only + is included += too.

Delta456 commented 2 weeks ago

If the length of the array is zero. 0 can also be returned accordingly

jorgeluismireles commented 2 weeks ago

I think we should have several "different" zeros to return: int, f32, fraction, complex... arrays.sum works for math.fractions:

import arrays
import math.fractions

zero := fractions.fraction(0,1)
half := fractions.fraction(1,2)
third := fractions.fraction(1,3)

mut fracs := [ zero, half, third ]

if s1 := arrays.sum(fracs) {
    assert s1 == fractions.fraction(5,6)
} else {

}

fracs.clear()

if s2 := arrays.sum(fracs) {

} else {
    assert err.str() == 'Cannot sum up array of nothing.'
}

// assert 0 == zero <- THIS CANNOT BE DONE

But I'm afraid that above fraction zero is not the same than, to say, integer zero. While fractional zero 0/1 is the same to fractional zero of adding 1/2 and -1/2.

So maybe panicking as is done right now solves the different zeros problem easily.

Or... sum function could return an Option instead of a Result, so for empty you'll have none.