Warnings about wrong usage of lexical scope
This functionality does not run in MATLAB.
Pref::warnDeadProcEnv(TRUE) Pref::warnDeadProcEnv(FALSE) Pref::warnDeadProcEnv(NIL) Pref::warnDeadProcEnv()
Pref::warnDeadProcEnv() returns the current setting.
Pref::warnDeadProcEnv(TRUE) switches on warnings about unreachable procedure environments.
Pref::warnDeadProcEnv(FALSE) switches warning messages off.
Pref::warnDeadProcEnv(NIL) will reset the default value, which is FALSE.
If a procedure is executed a procedure environment is created for this procedure. It contains the current values of formal parameters and local variables. On exit of the procedure this procedure environment is normally not needed any more and destroyed.
If a procedure returns a local procedure as its result, this local procedure escapes its scope. Usually this is no problem. Only if the escaping procedure contains references to formal parameters or local variables of the outer procedure these variables escape their scope. These variables can not be dereferenced since they reference values of a procedure environment of the outer procedure which does not exist any more.
Use option escape in the outer procedure in order to keep its procedure environment untouched.
Here we write procedure p which returns a local procedure. The returned procedure adds the value of its argument y to the value of the argument x of the first procedure. The following naive implementation produces a strange output and, when the resulting procedure is called, a warning message and an error:
Pref::warnDeadProcEnv(FALSE): p := proc(x) begin y -> x + y end: f := p(1); f(2)
Warning: Uninitialized variable 'unknown' used. Evaluating: f
Error: Illegal operand. [_plus] Evaluating: f
If Pref::warnDeadProcEnv is set to TRUE MuPAD® will print a warning message when the local procedure escapes its scope:
Pref::warnDeadProcEnv(TRUE): p := proc(x) begin y -> x + y end: f := p(1)
Warning: Found dead closure of procedure 'p'.
Use option escape in the outer procedure to prevent this warning. The returned procedure f will then work as expected:
p := proc(x) option escape; begin y -> x + y end: f := p(1); f(2)