there are several reasons for preserving a script context, such as preserving I variable:
i think when @sliderule implemented it, it also allowed to check recursion easily, since we need to push the execution stack and we have to make sure we don’t exceed the max stack size. it also means that avoiding infinite loops is just one reason, the other reason is the limited stack size. we could increase it but we still need to select some max number.
we could add a way to call a script without storing the context - but this feels like it’s becoming a very special use case with some unclear ramifications. if we considered it, i wouldn’t do it based on where you call a script (what if you do want to preserve context even when calling from the last line?) but having a dedicated op. but again, this feels like a pretty special case*, and we would still need to prevent infinite loops somehow.
also looking at the code, i think we also need to preserve J and K variables as part of execution context.
* well, and maybe it isn’t such a special case after all, it could be useful to be able to jump to another script without returning to the calling script, so you wouldn’t need to do something like SCRIPT 5; BREAK to replicate that. the op could be SCRIPT! / $! similar to M! to signify you’re doing something potentially risky.