Array slicing and recursion

Discussions related to database technologies, file handling, directories and storage
Richard Russell
Posts: 366
Joined: Tue 18 Jun 2024, 09:32

Array slicing and recursion

Post by Richard Russell »

I am finding array slicing to be a very useful capability, but it's necessary to be a little careful if used in a recursive function (in such a way that the slice dimensions change). For example in the code below the array is halved in size at each level of recursion:

Code: Select all

      DIM array(100)
      PROCtest(array())
      END

      DEF PROCtest(a())
      IF DIM(a(),1) < 6 ENDPROC
      PRINT DIM(a(),1)
      PROCtest(a(0 TO DIM(a(),1) DIV 2))
      PRINT DIM(a(),1)
      ENDPROC
You would expect it to print the following, where the array is halved in size as the recursion depth increases, and then restored to its original size as the recursion is 'unwound':

Code: Select all

       100
        50
        25
        12
         6
         6
        12
        25
        50
       100
But in fact the code outputs this:

Code: Select all

       100
        50
        25
        12
         6
         3
         3
         3
         3
       100
The halving at each level works (so if that is all you are interested in all is well) but the restoration of the size as the recursion is unwound doesn't. This is because although the array pointer is correctly stored on the stack and restored on exit from the procedure, the array dimensions (start and length) aren't restored.

If it's important that it works 'as expected' you can achieve that by saving and restoring the slice dimensions yourself. In this example it's just the size that must be restored:

Code: Select all

      DIM array(100)
      PROCtest(array())
      END

      DEF PROCtest(a())
      LOCAL size%
      IF DIM(a(),1) < 6 ENDPROC
      PRINT DIM(a(),1)
      size% = !(PTR(a())+1) : REM Save size
      PROCtest(a(0 TO DIM(a(),1) DIV 2))
      !(PTR(a())+1) = size% : REM Restore size
      PRINT DIM(a(),1)
      ENDPROC
The chances of you encountering this issue are remote, as it requires an uncommon combination of circumstances (array-slicing used in a recursive function, the slice dimensions being different at each level of recursion, and your code caring about those dimensions being restored as the recursion is unwound). But it's as well to be aware of it.