When you call a procedure, MuPAD® allocates memory for the
local variables, marks them as uninitialized, and evaluates the body
of the procedure. At the end of a procedure call, MuPAD destroys
local variables freeing the allocated memory. Now suppose that the
result of a procedure call refers to local variables of that procedure.
For example, the returned value of this procedure refers to its local
f := proc(x, y) local z; begin z := x + y; return(z); end:
In this case, the variable
z is replaced
by its value at the end of the procedure call. Therefore, the returned
value of the procedure is the value of the variable
not the variable
f := proc(x, y) local z; begin z := x + y; return(hold(z)); end: f(1, 2)
Objects of type
DOM_VAR represent local variables and can
only be used inside procedures. An object of type
DOM_VAR returned as a
result of a procedure call is useless because it does not have any
connection to the procedure.
You can access local variables of a procedure if you either
declare them in that procedure or declare them in a lexically enclosing
procedure. For example, in the following code the procedure
access and modify the variable
x of the enclosing
f := proc(x) local g; begin g := proc() begin x := x+1; end: g(); end: f(2)
Instead of returning the result of the procedure call
you can return
g itself. In this case, the returned
value retains a link to the variable
x of the procedure
call. For reasons of memory management,
declare that it will return something holding a reference to a local
variable. To declare it, use
f := proc(x) local g; option escape; begin g := proc() begin x := x+1; end: g; end: h := f(2): i := f(17): h(); h(); i(); h()
This programming construct is called a closure. It is supported in many programming languages.
Many programming languages support the concept of static variables. Static variables are local variables the values of which are not reset in each call to a procedure. The value of a static variable is initialized during the first call to a procedure. In each subsequent call, a procedure remembers the value of a static variable from the previous call.
Although MuPAD does not let you declare a variable inside a procedure as a static variable, you can still use the concept of static variables while programming in MuPAD.
When defining a procedure with
proc, you often assign the procedure
to an identifier. However, MuPAD lets you use anonymous procedures.
Also, you can define one procedure inside another procedure. Thus,
you can implement the alternative to a static variable in MuPAD as
a nested procedure where:
The outer procedure has a local variable. The outer procedure can be anonymous.
The inner procedure uses the local variable of the outer procedure. For the inner procedure that variable is not local, and therefore it does not reset its value in each call.
For example, this code implements
a static variable in MuPAD:
proc() local cnt; option escape; begin cnt := 0; f := proc() begin cnt := cnt + 1; end: end(): f(); f(); f()
The technique of creating static variables in MuPAD lets you create shared static variables by creating several inner procedures. The inner procedures use the same local variable of the outer procedure. For inner procedures that variable is not local, and therefore it does not reset its value:
proc() local x, y; option escape; begin x := 0; y := 0; f := () -> (x := x + y; [x, y]); g := n -> (y := y + n; [x, y]); end_proc(): f(); g(2); f(); f()