Happy New Year!
I just noticed that radix-slice is also broken, in the following ways. The 'end' parameter is used as an exclusive index, so the range test of (> end (radix-length radix-struct)) is correct, as is the copy-append! call. But this also means that radix-slice may be called with the length as 'end'. Since naive-append-vector! only increases the height of the radix on the (pow32? write-position) branch, a new radix of 32^k elements will be fully packed and have height k, where k>=1. The (= start 0) branch of radix-slice uses (= (vector-position end height) 0) to peel away levels from the radix and decrease the height. Therefore, a radix-slice call on a new radix of 1024 elements with start 0 and end 1024 will see that the peeling test passes and go down one level, because (vector-position 1024 2) is 0. On the next round it will make and return a new radix consisting solely of the first leaf vector of the source radix, with a height of 1 but claiming a length of 1024 elements. Radix-slice is similarly broken for all sources of size 32^k with k>=2, start=0 and end=length.
A second issue is that a radix-slice call on a new radix of 1024 elements with start 0 and end 32 will not pass the peeling test and will return a radix with 32 elements but height 2. This will break a subsequent naive-append-vector! because the (pow32? write-position) branch assumes the radix is fully packed and needs its height raised.
Radix-delete has a leftover extract-5 as pointed out previously. It also uses 'end' in the level peeling test inside find-head when it obviously meant to use 'start'. Find-head is a near verbatim copy of the one inside radix-slice, so it should obviously be factored out -- the global comments claim:
I'm trying quite hard to [...] B) factor out functions when they can be used in multiple situations
More to the point, the radix-delete fixed with 'start' and 'vector-position' is still broken in ways similar to radix-slice. For example, when called on a new radix with length in [33...1024] and height 2, with start=32 and end=length, it will not pass the level peeling test and it will return a radix with 32 elements but height 2. At that point >>25 applies:
This will break a subsequent naive-append-vector! because the (pow32? write-position) branch assumes the radix is fully packed and needs its height raised.
The other class of errors can be seen when called on a new radix of 1024 elements with both start and end set to length. The first level peeling test will pass and the next round will return a new radix consisting solely of the first leaf vector of the source radix, with a height of 1 but claiming a length of 1024 elements.
And as a matter of elegance, on the (= end (radix-length radix-struct)) branch the (- (radix-length radix-struct) (- end start)) computation in the make-radix call can be entirely replaced with start.
Radix-insert is implemented in terms of radix-append and radix-slice, both of which have the problems pointed out previously. In addition it uses 'radix-struct' on the second branch which is an unbound name at that point, and was meant to be 'radix-struct-write'. I think this about covers the public methods.