<p>In the early 1970s, I had university a co-op job at a place where one of the main languages used was like a glorified calculator.
It provided two stacks, and all variables and operators were a single character.
Depending upon context each letter could be overloaded and interpreted as a scalar (<code>x+2</code>), a vector (<code>x@2</code>), a function (<code>x:2</code>), or whatever.<br />
(I'm guessing about the syntax; it could have been quite different.)</p>
<p>I'm pretty sure it was either in-house, or provided by some external company that wrote and maintained it for them.</p>
<p>The interesting thing for me is that all arrays were powers of 2 in length.
I no longer remember the declaration syntax, but I imagine that each array was stored with an appropriate bit mask, so that <code>x@y</code> was a reference to address <code>x+(y&amp;mask)</code>.</p>
<p>All arrays were thus circular.
This meant that there was no possibility of having indexes out of range.<br />
It also meant that <code>x@-2</code> would naturally be the second from the end of the array, without requiring any different processing than for <code>x@2</code>.<br />
(Remember, this was at a time when an extra instruction or two was considered expensive.)</p>
<p>There were times when this behaviour came in handy (though I really can't remember any specific examples).</p>
<p>I'm wondering if any &quot;real&quot; languages ever provided arrays like this.</p>

<arrays>
Do any languages provide arrays that are always powers of 2 in length?
CC BY-SA 4.0
2023-06-30T01:21:39.070Z
While it's not an answer to the question as described, a related fun fact is that the growth factor in many languages' implementations of dynamic arrays is 2, so if the initial size of the array is a power of two, it will always have a power of two capacity.
rydwolf
CC BY-SA 4.0
2023-06-30T02:25:22.487Z
@RydwolfPrograms, I remember implementations of `malloc()` , perhaps the original BSD, where the allocated blocks were a power of 2, but the first 4 bytes were used to store the size of the block for use by `free()` . This meant that the common practice of `buffer=malloc(1024)` actually used 2048 bytes. 1024 was an obvious choice, but in fact it was the worst possible choice.
Ray Butterworth
CC BY-SA 4.0
2023-06-30T02:38:35.050Z
@RydwolfPrograms, I should add that the documentation for standard stdio functions also encouraged this use of inefficient buffer size.  e.g. `setvbuf(…, malloc(BUFSIZ), …, BUFSIZ)`, where BUFSIZ is almost always defined as a power of 2.
Ray Butterworth
CC BY-SA 4.0
2023-06-30T18:12:39.720Z
Windows low fragmentation heap causes that many (small) allocations are powers of 2.
Pablo H
CC BY-SA 4.0
2023-06-30T18:44:07.363Z
Amusingly, my archives record that I posted this to a newsgroup in 1984: "*… any program that uses stdio can save as much as 50% in buffer space if we just redefined BUFSIZ as 1020 instead of 1024.*". In a style typical of the flame-wars of the time, my blasphemy was kindly and logically refuted: "*I don't get it. You're obviously just being a f___ing a__h____.*".
Ray Butterworth
CC BY-SA 4.0
2023-07-01T16:00:09.280Z
I can't understand the meaning of "real" that you're after. Are we just trying to figure out which language you were working with, for example?
Karl Knechtel
CC BY-SA 4.0
2023-07-01T16:52:57.340Z
@KarlKnechtel, no, I'm sure it was a one-off and long gone. I'm just curious as to whether anyone else ever implemented it.  It potentially wastes a bit of space, but it simplifies other things. For instance the question of whether arrays are origin 0 or origin 1 is meaningless. And if you want to keep track of the latest say 16 instances of something, no bookkeeping is required.
Ray Butterworth
CC BY-SA 4.0
2023-08-15T22:52:23.350Z
Historically, gpus frequently only supported textures with power-of-two sizes, though nowadays they are not so restricted.  Behaviour of out-of-bounds accesses is configurable; see [this graphic](https://learnopengl.com/img/getting-started/texture_wrapping.png).
Moonchild
# Do any languages provide arrays that are always powers of 2 in length?
Posted by: username_0 on 2023-06-30
In the early 1970s, I had university a co-op job at a place where one of the main languages used was like a glorified calculator.
It provided two stacks, and all variables and operators were a single character.
Depending upon context each letter could be overloaded and interpreted as a scalar (`x+2`), a vector (`x@2`), a function (`x:2`), or whatever.  
(I'm guessing about the syntax; it could have been quite different.)

I'm pretty sure it was either in-house, or provided by some external company that wrote and maintained it for them.

The interesting thing for me is that all arrays were powers of 2 in length.
I no longer remember the declaration syntax, but I imagine that each array was stored with an appropriate bit mask, so that `x@y` was a reference to address `x+(y&mask)`.

All arrays were thus circular.
This meant that there was no possibility of having indexes out of range.  
It also meant that `x@-2` would naturally be the second from the end of the array, without requiring any different processing than for `x@2`.  
(Remember, this was at a time when an extra instruction or two was considered expensive.)

There were times when this behaviour came in handy (though I really can't remember any specific examples).

I'm wondering if any "real" languages ever provided arrays like this.
**Tags:** arrays
> **Comments:**
> **username_1**: While it's not an answer to the question as described, a related fun fact is that the growth factor in many languages' implementations of dynamic arrays is 2, so if the initial size of the array is a power of two, it will always have a power of two capacity.  
> **username_0**: @RydwolfPrograms, I remember implementations of `malloc()` , perhaps the original BSD, where the allocated blocks were a power of 2, but the first 4 bytes were used to store the size of the block for use by `free()` . This meant that the common practice of `buffer=malloc(1024)` actually used 2048 bytes. 1024 was an obvious choice, but in fact it was the worst possible choice.  
> **username_0**: @RydwolfPrograms, I should add that the documentation for standard stdio functions also encouraged this use of inefficient buffer size.  e.g. `setvbuf(…, malloc(BUFSIZ), …, BUFSIZ)`, where BUFSIZ is almost always defined as a power of 2.  
> **username_2**: Windows low fragmentation heap causes that many (small) allocations are powers of 2.  
> **username_0**: Amusingly, my archives record that I posted this to a newsgroup in 1984: "*… any program that uses stdio can save as much as 50% in buffer space if we just redefined BUFSIZ as 1020 instead of 1024.*". In a style typical of the flame-wars of the time, my blasphemy was kindly and logically refuted: "*I don't get it. You're obviously just being a f___ing a__h____.*".  
> **username_3**: I can't understand the meaning of "real" that you're after. Are we just trying to figure out which language you were working with, for example?  
> **username_0**: @KarlKnechtel, no, I'm sure it was a one-off and long gone. I'm just curious as to whether anyone else ever implemented it.  It potentially wastes a bit of space, but it simplifies other things. For instance the question of whether arrays are origin 0 or origin 1 is meaningless. And if you want to keep track of the latest say 16 instances of something, no bookkeeping is required.  
> **username_4**: Historically, gpus frequently only supported textures with power-of-two sizes, though nowadays they are not so restricted.  Behaviour of out-of-bounds accesses is configurable; see [this graphic](https://learnopengl.com/img/getting-started/texture_wrapping.png).  
---
## 0 answers
