I do not understand why the _PRESERVE field is not memorized as well as the field over REDIM (x, y), but it is written differently.
The reason WHY is for performance's sake.
Imagine a DIM array(1 TO 2, 1 TO 4), with the data 1-8 stored in it, as I mentioned above. In memory, it'd be stored as basically "1,2,3,4,5,6,7,8" (though without commas, and in Binary format).
Now, REDIM _PRESERVE array(1 TO 3, 1 TO 4)...
The way it is now, _PRESERVE preserves the data as it currently exists by basically following these steps:
1) Create a new memblock large enough to store the new array. (3 * 4 * element size, which varies based on data type, with default SINGLE being 4 bytes, in this case.)
2) Copy the data from the old array memblock directly to the new array memblock.
3) Free the old array.
4) Make array() point to the new memblock instead of the old one.
0)So "12345678" is our original 2* 4 data.
1)We create a "000000000000" new chunk of data in memory to hold 12 elements.
2)We _PRESERVE the old data and copy it over to become "123456780000".
3)Free the old memory
4)and change pointers.
Simple, fairly fast, and straight forward.
To make _PRESERVE work across multiple dimensions, think of what it'd have to do:
1) Create a new array of proper size, as before. "000000000000"
2) Calculate how large each chunk of "preserved memory" must be, and move it to the proper place inside the new array....
This step means we move "12" first (one old dimension), so we have "120000000000" in the new array.
Then we calculate the proper position for the next position and move the next chunk of substainable data (the "34"), so we have "120340000000".
Continue to calculate and copy....
"120340560000"
"120340560780"
3)Free old array from memory.
4)Swap pointers.
As you can see, there's quite a bit more involved to preserve the data so it's "120340560780", instead of just "123456780000"...
Now, imagine the time this REDIM _PRESERVE process would take, if we REDIM _PRESERVE array(10000,10000,10000,10000).....
How many calculations would that be? How many copies of chunks of memory into their new, proper positions?
I wouldn't even want to take a guess at how large a performance hit such a routine would cause for our programs!
I really don't see how any routine could calculate those "gaps" in the old data and position it "properly" in the new data, without the performance being so abysmal as to render it worthless, for all intents and purposes.
If written into the language itself, QB64 _PRESERVE would have to be flexible enough to check and move data properly for ALL cases. It'd need to work for array(a,b,c,d,e,f,g,h,i,j), just as much as it would for a simple array(x,y), and the overhead would be astoundingly terrible.
Personally, I feel it's much better to leave it as it is, and let the user roll their own solution. Then, they can search for a method which will give them the results they need (as you did above), without adversely destroying the performance they'd expect.