StaticArgumentTransformation
Static-argument transformation (T1 of docs/internal/CODEGEN_IMPROVEMENT_PLAN.md).
A parameter of a single-binding recursive Let is static when every self-call passes exactly that parameter's own variable in the same position. Static parameters are bound once by a wrapper lambda, and the inner recursion re-passes only the changing ones:
let rec f = λp1...pn. body // some pi static in every self-call
-->
let f = λp1...pn.
let rec f$sat = λq1...qk. body[ f e1...en := f$sat e_q1...e_qk ]
in f$sat q1...qk // q = changing params, in source order
When the static parameters form a prefix (the common case, e.g. go f n acc with an invariant f) a leaner shape is used instead - the wrapper binds only the static prefix and returns the fixpoint itself, so the changing parameters are consumed by f$sat directly:
let f = λp1...pj. let rec f$sat = λq1...qk. body' in f$sat
The wrapper keeps the original name, arity and type, so external uses of f (partial applications, higher-order uses, eta-lets) are unaffected. The fixpoint is built once per entry into f instead of once per iteration, and each iteration saves one Apply per lifted argument.
The transform is skipped (input returned unchanged) when it cannot be proven safe:
- multi-binding recursive
Lets (mutual-recursion groups) and lazy lets; - a rhs that is not a lambda, or has duplicate parameter names;
- any self-reference that is not the head of a self-call saturated to full arity (a bare reference or a partial application could observe the original arity);
- no static parameter at all.
If every parameter is static the last one is demoted to changing, because a nullary strict letrec would diverge.
Runs only when optimization is enabled - see scalus.compiler.sir.lowering.UplcPipeline.run, which is the single place this pass is invoked from. It runs after MutualRecursionElimination, so the peers-as-params static arguments that pass introduces (a $mutrec peer re-passing f1 .. f(i-1) unchanged on every self-call) are lifted here too.
Attributes
- Graph
-
- Supertypes
-
class Objecttrait Matchableclass Any
- Self type