curry.icurry.analysis.partials module
Finds the partial application that the head of an apply denotes.
A chain apply (apply h x) y costs a rewrite step and a node per
apply. When the head is known, the optimizer builds the call directly;
see curry.interpreter.optimize.saturate_applies. A head is known when it is
a partial application (IFPCall, or ICPCall of a constructor), or a call
without arguments of a nullary function whose body is one such partial
application, followed through nullary functions to a bounded depth. The
Prelude’s instance methods that fall back to a class default have that
shape:
- _impl#/=#Prelude.Eq#Prelude.Int =
_def#/=#Prelude.Eq _inst#Prelude.Eq#Prelude.Int
and so do userError (a partial application of UserError) and showChar. A
head that is itself an apply of a known head is known too (the body of
g = k 1 with k = f), so the answer does not depend on the order in
which the optimizer reaches the functions. A variable head, and a call with
arguments, are not known.
A call of Prelude.$, the Prelude’s alias of apply, is an apply here
(is_apply): the optimizer runs before alias inlining. A user alias of
apply (app f x = f x) is not: the source wrote the indirection, and the
pass keeps it.
- curry.icurry.analysis.partials.is_apply(expr, modules)[source]
Tells whether
expris a saturated call ofapply: an IFCall with two arguments of Prelude.apply, or of Prelude.$ while the loaded Prelude defines it as an alias of apply (resolve_alias).modulesmaps module names to Curry modules and packages, as Interpreter.modules does.A user alias of apply (app f x = f x) is not an apply here, though inline_aliases turns a call of it into one afterwards: the source wrote the indirection, and a program may need it to hand a known function value to the apply of the runtime, which the optimizer would otherwise fold away (a let of a bare function value does not survive the front end).
- curry.icurry.analysis.partials.lookup_constructor(symbolname, modules)[source]
Finds the IConstructor named by the full name
symbolnameamong the loaded modules, as lookup_function finds a function. Returns None when the module is not loaded or has no such constructor.
- curry.icurry.analysis.partials.lookup_symbol(symbolname, modules)[source]
The IFunction or IConstructor named by
symbolname, or None.
- curry.icurry.analysis.partials.nullary_body(ifun)[source]
The expression that the nullary function
ifunreturns, when its body is one return statement without declarations, or None. A function with parameters, a local variable, a free variable, or a case is never unfolded. Neither is a function without a Curry body (built-in, external, or loaded from its compiled form).
- curry.icurry.analysis.partials.partial_head(expr, modules, depth=MAX_UNFOLDING_DEPTH)[source]
The partial application that the head expression
exprdenotes, as a fresh IFPCall or ICPCall, or None when the head is not known.expris known when it is a partial application; an IFCall without arguments of a nullary function that unfolds to one (unfolding); or anapplywhose head is known and whose call is a partial application (saturate), through at mostdepthnullary functions and applies.modulesmaps module names to Curry modules and packages, as Interpreter.modules does. The partial must agree with the symbol table: the function or constructor is loaded, and its arity is the number of arguments plus the missing count, which is at least one. So a call built from the answer has the arity of its symbol.
- curry.icurry.analysis.partials.saturate(iapply, modules, depth=MAX_UNFOLDING_DEPTH)[source]
The call that the
applynodeiapplybuilds when its head is known (partial_head), or None. When the partial misses one argument, the call is the saturated call (IFCall, or ICCall of a constructor); when it misses more, the call is the longer partial application. A saturated call that is itself anapply(ap = apply, thenap f x) is saturated again, to the bounddepth. The head is a fresh copy, so the call shares nothing with the body of a nullary function; the argument is the one ofiapply.
- curry.icurry.analysis.partials.unfolding(ifun, modules, depth=MAX_UNFOLDING_DEPTH)[source]
The partial application that the nullary function
ifununfolds to, as a fresh expression, or None. The answer comes from the metadata when it is there (a module loaded from its compiled form), else from the body, which may itself be a call of another nullary function or anapplychain (see partial_head). A text in the metadata that does not read back as a partial application makes the function unknown; it does not stop the import.