Reusing Function Argument Cells vs. Debugging

In the historical bit-fiddly nature of Rebol, the reuse of argument cells to do work inside a function was frequent.

foo: func [x y [text!]] [
    do-something-with y
    ; Yay, y is now free...use it as a counter
    y: 0
    while [y <> x] [...]
]

This practice is particularly pervasive in native functions, where the argument cells provide a convenient "already protected by GC" cell. Once they've extracted whatever they want into C variables, natives go on to use these slots for anything and everything--as scratch locations.

But it runs up against a problem with debugging...looking in the stack, you no longer see what you passed in for the argument cells. It makes your calls look like gibberish.

Since arguments are not immutable, this is just a "thing". One very good reason not to make them immutable is adaptations...you want to be able to create variations of functions that update the arguments, so as to pass them on to a next phase with an adjustment.

So perhaps it's the debugger's responsibility to figure out a way to capture the inputs off to the side (or notice if they ever change and make a copy?) Or should it be the convention that people just try not to do this unless there is an actual good reason--as with adaptation?

It's just a bit disconcerting to run something like SWITCH and then look in the stack and have gibberish in the cell where you thought you put the thing to switch on...for the sake of micro-optimization. Just making a distinct local seems worth it.

1 Like