Integer conversion - too much friction?

Integer type conversions seem to come up all the time.
Maybe it is unavoidable - but but wish there was less 'friction'.

I think the problem is that array indexes have to be usize - len() also returns usize - which may not be the best choice for your own types (usually is not) - or types in the libraries you call.

I feel I have too many try_into().unwrap() and - when I'm feeling careless - "as u16" in my code.

E.g. the the ncurses crate expects screen coordinates (row & column) to be i32. Crossterm expects u16 for same.

        crossterm::queue!(
            stdout(),
            cursor::MoveTo(
                (i % WIDTH).try_into().unwrap(),
                (i / WIDTH).try_into().unwrap()
            ),
            style::PrintStyledContent(c),
        )
        .ok();
1 Like

Here's one perspective you can take:

(i % WIDTH, i / WIDTH) is already a substantial concept in itself. You might as well finish the job and wrap it up in a nice package that is thoughtful about numeric ranges.

fn index_to_xy(index: usize) -> (u16, u16) {
    assert!(index < WIDTH * HEIGHT);
    // Cannot overflow after the assertion,
    // because WIDTH and HEIGHT are each less than u16::MAX
    (
        (i % WIDTH) as u16,
        (i / WIDTH) as u16
    )
}

Use whichever of as or .try_into().unwrap() you like in this function — in either case it is certain that the conversion cannot overflow/wrap as long as WIDTH and HEIGHT are appropriately set. Now callers never have to worry about anything but “the index is in range”.

6 Likes

Agreed, and I wish there was a way to enable an implementation of usize: From<u64> and only allow my code to only compile on a 64-bit platform.

And this is where you have a problem. As someone who spent may, many days debugging problems created by C and C++ “frictionless” conversions I welcome that change.

Yes, there ways to reduce the boilerplate, but you want there to be friction. Even in something as mundane as terminal coordinates.

E.g. Midnight commander couldn't tolerate terminals wider than 256 characters wide — precisely because there are no friction and thus it's hard to see where exactly 320 is turning into 64.

What you want is to change either ncurses or crossterm to fix the issue, not change the language to hide it. Or maybe add some wrappers if both are unchangeable.

2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.