A procedure that redefines itself to take more inputs than it took originally can't subsequently call itself recursively. The problem seems to be that the previous definition cached how many inputs it was supposed to take and the cache isn't invalidated. More technically, the procedure was "treeified" with the original number of arguments and it's retreeified when the definition changes.
A procedure can redefine itself and then subsequently call itself. The problem is specific to when the number of inputs change.
Steps to Reproduce:
Step 1: Define the procedure that redefines itself:
DEFINE "REDEFINEWHILERUNNING [ []
; Redefine the procedure take an input.
[ DEFINE "REDEFINEWHILERUNNING [ [arg] [OUTPUT :arg] ] ]
; Run the new definition to output 1.
[ OUTPUT REDEFINEWHILERUNNING 1 ]
]
Step 2: Run the procedure with the original definition
SHOW REDEFINEWHILERUNNING
Step 3: Run the procedure with the new definition
SHOW REDEFINEWHILERUNNING 2
What Happens:
Step 2 throws an error because the final line of the original definition still expects the procedure to take no inputs.
not enough inputs to REDEFINEWHILERUNNING in REDEFINEWHILERUNNING
[OUTPUT REDEFINEWHILERUNNING 1]
Expected Result:
Step 2 prints 1.
Step 3 prints 2.
MSWLogo 6.5b has similar behavior, except that for Step 2 the error looks like:
Therefore, this is not a regression.
UCBLogo 6.2 behaves correctly (as described in "Expected Result").
This was fixed by [r6343]. The fix will be available in FMSLogo 8.6.0.
This bug had four variants. It affected running procedures that are:
The problem is that these workspace procedures all untreeified the previous procedure.
This was historically needed because the tree had a circular reference and changing
the case object's procnode while it still had a tree would leak the tree. However,
the evaluator can't handle when a running procedure is untreeified and the generation
changes, as this sets the tree of bodylist to NIL, and the evaluator can't re-treeify NIL.
A recent change reworked the structure of a tree to no longer creates circular references.
Therefore, explicit untreeifying is no longer needed, so that logic could all be removed.
This is a rare fix where the fix is entirely done by removing code.
Related
Commit: [r6343]