Differences in opinion.
It is what it is.
My stance, since SquareFingers asked, is that it's not a bug or a hole or a hack or anything similar that you might want to call it, that there is one particular variable (the so-called Loop variable) that the documentation indicates as the counting variable (bypassing it doesn't make it go away). It does appear to me that, in reality, for each FOR loop, the Loop variable first gets set (assigned or initialized, if you will) and then it gets incremented every subsequent step through that loop until the current value of said Loop variable reaches some other value. The vaguer the better. It also occurs to me that variables with elements declared can have more variables nested inside them (to represent the number of their elements) so long as the variable type used stays compatible. Also, I assume that two different elements of the same variable should generally be considered as such. So... I say it's both good and acceptable if not useful as well.
Regardless, the OP says this:
When the FOR statement is first encountered, J has the value 1, and the variable A[1] is initialized to 1. Inside the loop, J is incremented. When the NEXT is reached, the program goes back to the FOR. Now, A[2] is incremented, and checked against the to-value, 15. Next time, A[3] is incremented and checked.
But this is what actually happens, start to finish:
When the FOR statement is first encountered, J has the value 1 so the Loop variable (A[ ]) is at least temporarily A[1]. The value 1 is assigned to the variable A[1] which is then checked against the End value, 15. Inside the loop, J is incremented from 1 to 2. When NEXT is reached, the program increments A[2] (0 to 1) and then goes back to the TO. Now, A[2] is checked against the End value, 15. In the loop, J is incremented from 2 to 3. NEXT increments A[3] (0 to 1) and then goes back to the TO. Then, A[3] is checked against the End value, 15. In the loop, J is incremented from 3 to 4. NEXT increments A[4] (0 to 1) and then goes back to the TO. Now, A[4] is checked against the End value, 15. In the loop, J is incremented from 4 to 5. NEXT increments A[5] (80 to 81) and then goes back to the TO. Finally, A[5] is checked against the End value, 15, and since A[5] currently has a value of 81, the loop ends.
This is all by the book and easily understandable if you take all of the documentation into consideration as a whole. That includes (to name a few things) the e-manual, the instruction list, update logs, and the specs page I linked to before. Look for "nesting" if you want to learn a new and exciting way to say "Yes, you can." Nesting a variable in the Loop variable just adds one potential level of abstraction to the process, the same way it would if you did it anywhere else. All the rules stay the same. The Loop variable isn't "changing" just because you're looking at a different part of it between steps. It's still A[ ]. Not B[ ] or SEAGULLS[ ] or GAZEBO[ ]. You just have to make sure everything's compatible. It's a lot like backing up with a trailer attached to your car when you think about it. The hitch doesn't change into a different one (or a gazebo, for that matter) when its angle to your car changes but that angle (along with the angle of the car's front tires, I suppose) does end up affecting where the whole thing goes.
Here's one way to get this to do what I think you wanted it to do.
I'll try to make it as long and convoluted as possible.
DIM A[100]
'DIM or VAR, pick your poison.
A[5]=12
'Value of element 5 is 12
A[8]=10
'Value of element 8 is 10
A[15]=80
'Effectively stops the loop using the calculated End value
HIGH=15
'Variable to use instead of the number 15
TOP=0
'Variable to use instead of the number 0 when not using J
J=0
'Starting value of the nested variable of A[ ]
A[0]=A[HIGH]-1
'Header info (79 here) to help tell where the loop should stop
'A[J] technically starts here as A[A[HIGH]-1]. Yowza!
FOR A[J]=A[J] TO A[TOP]
'The first time->FOR A[0], assign 79 (should be that already), check against 80, it passes.
'Later STEPs->check current value of A[J] against 80 to see if it passes.
PRINT "Number ";J;" is ",A[J]
'This prints locations/values of elements the loop passes through.
INC J
'This is driving the proxy counter, J. It moves A[ ] to the next element.
DEC A[J]
'This negates the effect of the coming NEXT on the current element of A[ ].
NEXT
'This increments A[J] and goes back to TO.
PRINT "Number ";J;" is ",A[HIGH]
'This prints the value of the element that the loop finishes on.
That should list all values of A[ ] from A[0] to A[15]. It works basically the same way as the OP's example but with all arguments in the FOR loop replaced with variables, some of which include nested or double nested variables to boot. There's a function added to decrement A[J] so that counting duties can effectively be proxied to the nested J without causing elements with predetermined values from being altered. You just need to wrap your head around what it's all actually doing. Fortunately, (in my opinion) SmileBoom has done a fair-to-midland sort of job explaining it all. The sample programs are documentation, too, in case you were wondering. Lots of good comments in there even if they are in Japanese sometimes.
I'm going to lightly suggest this topic be relocated to Programming Questions since I definitely see the potential here. You can get this to assign a value (across the elements of an array, no less) each step if you program that in and you don't necessarily need to tell it to print, either. It could be writing that information to an empty program slot and then saving it out to a file if you wanted. There are much more robust versions of this sort of "bait-and-switch" tactic in SmileBoom's own code if you're willing to dig through it.
Actually, a "Programming Tips and Tricks" board would probably be even better, now that I think about it.