@d4s_over_dt4 recently created a forum topic:"Change x by y not hyperized" (it was closed by @jens because of the user's supposed hyper-activity ). Much of the answer to his request can be found in the earlier forum topic "Make 'set' and 'change' hyperizable".
As it happens I recently created hyperized "set" and "change"-like commands and reporters, such as:
In that situation, it's much better to have the counter variable as part of the loop structure, like the upvar in FOR, rather than some random global and CHANGE BY commands. Upvars are both self-documenting and limited in scope. (I'm not saying you disagree with that. Just saying that you can build iteration structures that don't spill out into the rest of the program.)
I wasn't hinting at FOR. Even so, upvars in FOR actually do spill out of the loop, like in:
You can do this without declaring "ï" anywhere else (in this case, it is reported as: 11, which may be understandable from an implementation ~, but not from a user perspective). See recent forum discussion: Script variables and upvars: make 'm local
What I meant to say was in other iterative constructs, like REPEAT UNTIL (which is sometimes preferable over FOR), it often makes sense to use and update a "counter" variable.
No, I didn't think you meant FOR. I was pointing to FOR as an example of iteration done right, in which the iteration variable is visibly part of the iteration, not some random global variable pressed into service.
The upvar is treated as a Script Variable. It's true that it survives the end of the loop, but only within the current script. In particular, you can have two FOR loops in two different blocks, with one calling the other, without clobbering each other's variable, even if they're both called I.
If it were up to me, the iteration variable would disappear once the loop is finished. But Jens keeps finding uses for the current behavior that make it easier to write projects.