News for hackers. Stuff that matters.
Re:Microfeatures I'd like to see in more languages by philsnow on Thursday January 05, 2023 @05:45PM (#34268026)
You'd have to care about the difference between indexing with a literal and indexing with variables of different types/widths, and how indexing with a variable interacts with the size of the area.

For instance if you have an int array that contains the numbers 1-250 and you index with a uint8 variable i,

  for (uint8 i = 247; i++;) {
    // print circ_arr[i]
  }
for the values of i near the overflow points of the circular array and of the uint8 it gets weird:

  i    circ_arr[i]
  247  247
  248  248
  249  249
  250  250
  251  1   # 251 % 250 = 0
  252  2   # 252 % 250 = 1
  253  3   # ...
  254  4
  255  5
  0    1   # i overflows to 0
  1    2
  ...
Re:Microfeatures I'd like to see in more languages by feoren on Thursday January 05, 2023 @06:22PM (#34268437)
Right, the calling code needs to handle its own integer overflows, of course. And if your circular array has a size other than a power of 2 you can get only a partial enumeration in the cycle that includes overflow. Sure. But are you really indexing an array of unknown size with a uint8? It's really impossible that there might be more than 255 things you ever care about? No. Everyone who is using a uint8 to index arrays is either doing something extremely low-level and fiddly where abstractions like this simply don't apply, or they're idiots who are doing cargo-cult shotgun "optimization" because they don't know how to write code that works.

If you're indexing with a [u]int32 you need to worry about this once every 4 billion increments, and if an incomplete cycle is a show-stopper for you, you can compute a safe modulo yourself based on the size(s) of your circular array(s), but more likely you just need something else. But really, you don't care if your cache hiccups a little once every 4 billion caches.

You make a good point, of course, I'm just allergic to people poking holes in back-of-the-napkin explanations of things with the trite "but integers can overflow!" It's one of those most common well actuallys written on this site. Of course integers can overflow. They almost never do though, do they? And if they do, a test fails and you add a single line somewhere to fix it.

I really think the vast majority of programmers are too often thinking about bits when they should be thinking about math.

Re:Microfeatures I'd like to see in more languages by ablob on Thursday January 05, 2023 @06:32PM (#34268548)
The point made is independent of the integer size and I think we should assume in good faith, that uint8 was chosen for the purposes of an example.
Re:Microfeatures I'd like to see in more languages by feoren on Friday January 06, 2023 @02:56AM (#34272122)
Um, maybe, but then his example is sixteen million times worse than reality! If I argued against some technology by showing how bad it would be if it were sixteen million times worse, that's just not a very good argument, is it?
Re:Microfeatures I'd like to see in more languages by ablob on Thursday January 05, 2023 @06:24PM (#34268460)
Why is an overflow that is generated by the caller your concern?
Re:Microfeatures I'd like to see in more languages by Someone on Friday January 06, 2023 @03:29AM (#34272357)
In a language where arrays are fixed-size, I think the proper solution is to have arrays not indexed by integers, but by a custom modular type that depends on the array with values in [0,n) that allows literals in the range [-n, n-1], with literal ‘-1’ being a different way to write ‘n-1’, etc.

You’d need a way to get that type, for example as

  float a[10,20]          // two-dimensional array of floats
  typeof(a.dims(0)) i = 0 // modular type with values in [0,9]
  typeof(a.dims(1)) j = 0 // modular type with values in [0,19]
or, slightly neater:

  auto i = a.indextype(0)
  auto j = a.indextype(1)
Ugly syntax, but in a modern language, most code would probably do something like

  for (i,j,value) in a
where the types are inferred.

Having those modular types means the compiler would do the arithmetic correct for the array, while the negative literals allow programmers to specify “last” and “next to last” correctly.