partialSpecialization – Partial specialization of expressions and code
partialSpecialization does (simple) partial specialization of expressions and code.
Call:
partialSpecialization(expression, values)
Parameters:
expression: |
some MuPAD expression or procedure |
values: |
a table assigning values to some parameters |
Return Value:
a copy of f, which has been specialized and optimized for the given values of the parameters
Details:
The parameters can be either global variables, or local variables of the current context.
Currently, the following optimizations are done:
The purpose of partial specialization is to avoid source code duplication for similar procedures that differ at very localized places in their code, without paying a price at execution time.
This implementation is at the stage of proof of concept. The main goal is to collect the typical use cases for such a feature: feedback most welcome!
Among many other probable bugs, the partial specialization does not yet recurse properly inside every possible objects of an expression (e.g. table keys); this mean that some parameters may in some cases be left unsubstituted!
We define the following function, whose behavior depends on a boolean parameter Increasing:
f := proc(x)
begin
for i from 1 to 10 do
if Increasing then
x := 2*x
else
x := x/2
end_if
end_for;
x;
end_proc:
partialSpecialization specializes the code of f for a specific value of the parameter:
g := prog::partialSpecialization(f, table(Increasing = TRUE)):
expose(g)
proc(x)
name f;
begin
for i from 1 to 10 do
x := 2*x
end_for;
x
end_proc
As desired, the if statement has been optimized away.
The parameters may be local variables in the calling context instead of global variables. Here, we replay the previous example, but now Increasing is a parameter of an enclosing procedure:
makeProc :=
proc(Increasing : DOM_BOOL) : DOM_PROC
begin
prog::partialSpecialization(
proc(x)
begin
for i from 1 to 10 do
if Increasing then
x := 2*x
else
x := x/2
end_if
end_for;
x
end_proc,
table(hold(Increasing) = val(Increasing)))
end_proc:
expose(makeProc(TRUE))
proc(x)
begin
for i from 1 to 10 do
x := 2*x
end_for;
x
end_proc
Note that in that case makeProc does not need the option escape; indeed, after the specialization the returned procedure does not refer anymore to any variable of makeProc.
Without using the partial specialization, calling makeProc several times with the same parameter produces procedure whose code is physically shared in memory. Only the context of the procedure differ. Partial specialization breaks this: even if the produced procedures have a syntactically identical code, it will not be physically shared in memory.
Changes in MuPAD 3.1
New Function.