Convert a matrix ("DataFrame") to printable string While I understand that &quot;V is a simple language,&quot; I find myself repeating a lot of stuff. For instance the whole first block, &quot;measure column widths,&quot; could beautifully be accomplished by two simple list comprehension lines in Python. Is there some way to simplify the allocate array, initialize the index pointer, loop-assign, increase index pointer code? Any equivalent to Python's enumerate() would go a long way...
What do I do about the pad thing? Sure, it will work in 99.9% instances, but would be nice with an arbitrary length solution (such as ' '*n in Python).
Performance-wise I'm not concerned for this function in particular, but I'm curious if there are any obvious blunders? It looks close to C to me, and it's probably only cache handling that could be a problem? I'm assuming the three mutable arrays end up on the heap? If so: anything I can do about that?
I'm left with the sense that &quot;simple language&quot; in this case is equivalent to &quot;hard-to-read implementation.&quot; With just a few more features it could be both simple and easy to read? What is your impression?
pub fn (df DataFrame) str() string {
    // measure column widths
    mut width := []int{len: 1 + df.cols.len}
    mut str_sers := []Series{len: 1 + df.cols.len}
    mut sers := [df.index]
    sers &lt;&lt; df.cols
    mut i := 0
    for ser in sers {
        str_sers[i] = ser.as_str()
        mut row_strs := str_sers[i].get_str().clone()
        row_strs &lt;&lt; [ser.name]
        width[i] = maxlen(row_strs)
        i++
    }

    // columns
    pad := '                                        '
    mut row_strs := []string{len: sers.len}
    i = 0
    for ser in sers {
        w := width[i]
        row_strs[i] = pad[0..(w - ser.name.len)] + ser.name
        i++
    }
    mut s := row_strs.join('  ')

    // cell data
    l := df.len()
    if l == 0 {
        s += '\n[empty DataFrame]'
    }
    for r in 0 .. l {
        i = 0
        for ser in str_sers {
            w := width[i]
            row_strs[i] = pad[0..(w - ser.get_str()[r].len)] + ser.get_str()[r]
            i++
        }
        s += '\n' + row_strs.join('  ')
    }
    return s
}
V already has a built-in enumeration for plain arrays:
for i, a in arr {
}

Which removes six unnecessary lines of code.
List comprehension would remove another dozen lines, and what little I understand about V's map/reduce, it seems very limited (think lambda without closure) so that is not an option. Python's list comprehension with zip is an efficient way to reduce dumb code, but perhaps it defeats V's &quot;only one way to do things.&quot; And perhaps this is a rare scenario.