"Calculus and algorithm are the two main ideas of Western science" (David Berlinski).
"The parts are derived from the whole and not the whole from the parts" (Arthur M. Young).
The Concept of Partial Evaluation
Introduction
Partial evaluation is a computer technique that consists in the transformation of an expression (basically, source code) by means of a specialization. To do this, the original expression is assigned values to part of its parameters and then evaluated, producing a new expression, a specialized expression.
This simple but powerful idea is taken from the area of mathematical functions: a curry function is one in which only one argument is applied at a time, yielding successively more and more particularized functions with one less parameter.
Partial evaluation is a generic mechanism that has been the object of special attention and study, since it provides a unifying paradigm, a new perspective, in mathematics, computer science and logic, having received different names: restriction, projection, specialization and currying. But it has been in programming the area where it has undergone the most development, having also provided a very valuable aid in understanding the properties of programming languages themselves.
Motivation
The main motivation for partial evaluation is to increase the speed of execution, since particularized programs are more efficient than generic programs. There are, in this sense, two extreme tendencies:
Write many small efficient programs. The disadvantage is that it takes a lot of programming and maintenance effort.
Write a single highly parameterized program, capable of solving a wide range of problems. The disadvantage is inefficiency, mainly due to parameter processing.
The best between the two positions is to write a highly parameterized program and perform partial evaluations to obtain more efficient, understandable and manageable versions.
Partial evaluation process
The partial evaluation can be manual or automatic. The manual specialization has the disadvantage that it is necessary to make an effort to adapt the code, with the consequent possible appearance of errors. The most interesting is the automatic partial evaluation, because of its predictable behavior and as a generic mechanism:
The starting point is a parameterized X expression (source code segment). The automatic partial evaluation process consists of two phases:
Specialization phase.
The expression X is particularized by assigning values to some parameters E (which are called "static") and evaluated, obtaining a new expression < i>XXEX (called "specialized" or "residual" expression).
Automatic specialization involves the development of a partial evaluator EP (or specializer): a program (rather, a metaprogram) with two arguments: the source code X and the set E corresponding to the static parameters. Its evaluation produces the specialized expression XE:
EP(X, E) = XE
The expression XE, in general, is shorter than the original (X), although sometimes, by deployment of loops or recursive calls, it could be longer.
Evaluation phase.
Values are assigned to the remaining D parameters (which are called "dynamic") and XE is evaluated with those dynamic parameters, i.e., XE(D), producing the result R:
XE(D) = R
The result obtained, R, is identical to that which would be obtained by evaluating X with all parameter values, i.e., X(E, D) = R.
The expression XE(D) is more efficient than X(E, D), having precomputed the parts of X that depend only on E.
Partial evaluation types
The partial evaluation process can be of 3 types:
Online.
The evaluation phase takes place immediately after the specialization phase, i.e. after the specialized expression XE is obtained.
Its main advantage is that it makes immediate use of computational resources, but it has the disadvantage that code generation may not be adequate, even infinite.
Offline.
Specialization is carried out in several stages. Initially, a preprocessing of the original expression (X) is performed based on information about which parameters are static, not on their values, and no decision process is performed by the specializer. In a second stage, starting from the concrete values of the static parameters, the specialization process (obtaining XE) takes place.
Its main advantage is that it allows self-application (application to one's own partial evaluator EP) and the generation of program generators. In addition, the specialization algorithm is simpler.
There is also the strategy called "mixline", in which the two previous methods are mixed.
Partial Evaluation in MENTAL
In MENTAL, partial evaluation is a mechanism that is available directly in the language. There is no need to develop any specializing program. The resources available to perform partial assessments are:
Parameterized generic expressions, by assigning values to one or more parameters.
Expressions of type x/y, where x is a primary expression and y is the secondary expression, consisting of one or more substitutions. You can particularize any (primary) expression, including data, generic expressions, etc. It is totally generic, since it applies to all types of expressions. Expressions do not even need to have formal parameters.
In the secondary expression, one or more substitutions (in series or in parallel) are used that affect the primary expression.
The same primary expression can be specialized in different ways, depending on the secondary expression applied.
The same secondary expression can be applied to different primary expressions.
A specialized expression may itself be specialized (higher-order partial evaluation). In this case, partial evaluation can be considered a type of phased or staged evaluation process.
Combined with the rest of the primitives, a highly flexible and expressive environment is available, including the possibility of evaluation in all three modes (online, offline and mixline).
A curry version of f would be, for example, to specialize the parameter y with 7:
〈( g(x) = f(x 7) )〉 // ev. 〈( g(x) = (x+7 x*7) )〉
Therefore,
g(2) // ev. (9 14)
g(a) // ev. (a+7 a*7)
We have the union function (of sequences or sets).
〈( union(xy) = (x↓ y↓) )〉
If we know one of the parameters, e.g. y=(1 2 3), we can specialize the generic expression:
〈( union1(x) = union(x (1 2 3)) )〉
This expression evaluates to:
〈( union1(x) = (x↓ 1 2 3) )〉
Application examples:
union1(a b c) // ev. (a b c 1 2 3)
union1(a b) // ev. (a b 1 2 3)
union1(a) // ev. (a 1 2 3)
Examples of code specialization
(c =: (x=5 ← a>b →' x=4)°
ce = c/(a=3 b=4) // ev. x=4 (specialized code)
ce // ev. x=4 (specialized code evaluation)
Example of higher order specialization (specialization of specialization)
The scalar product of two numerical sequences x=(x1 ... xn) and y=(y1 ... yn) is defined as the sum of the products corresponding to each of the components of both sequences:
The term "curry" comes from the logician Haskell Brooks Curry, a researcher in combinatorial logic, who applied this technique extensively in the area of recursive functions [Curry, 1958, 1971]. The original idea was Moses Schönfinkel's in 1924, but it was Curry who first recognized and systematized Schönfinkel's work.
The theoretical possibility of partial evaluation was established in the theory of recursive functions by Kleene's s-m-n theorem [1952].
L.A. Lombardi [1967] was probably the first to use the term "partial evaluation" to refer to computation with incomplete information, within the framework of incremental computation with Lisp.
Yoshihiko Futamura [1971] was the first to consider a partial evaluator to be a program that could apply to itself.
Andrei Ershov [1982] used the term "mixed computation," since a partial evaluator produces a mixture of execution and code generation.
Applications of partial evaluation
Automatic program generation. By specializing the generator program and executing it, different programs are obtained. It is a type of metaprogramming [Jones et al. 1993].
Compilers and interpreters: compiler generation, compilation by specializing an interpreter, etc. Partial evaluation has been shown to be closely linked with compilation [Futamura, 1971]. It is the area perhaps most studied and where the most results have been achieved.
Specialized parallel process generation, especially for simulation.
Computer graphics. For example, ray tracing (algorithm for 3-D image synthesis) with specialization of the scene to be drawn.
Database search algorithms. Highly parameterized algorithms consume a lot of time analyzing all arguments, especially if they correspond to complex objects.
Generic programming: development of reusable programs in different contexts.
Operating systems. To optimize processes.
Software reengineering. Partial evaluation allows to decompose large programs into smaller and more understandable ones.
Implementation of domain-specific languages from generic languages.
Advanced applications
Partial evaluation of an interpreter.
We have a source language L, an interpreter INT of that language and a program P written in the language L. Then you have:
The partial evaluation (EP) of the interpreter INT with respect to the static data P (the program) is the specialized interpreter INTP:
EP(INT, P) = INTP
This type of specialization is called "Futamura projection".
The execution of the interpreter INT with the static data P and the dynamic data D is the same as the execution of the specialized interpreter with the dynamic data D:
INT(P, D)) = INTP(D)
Self-application of the specializer (specialize a specializer).
We have a source language L, a partial evaluator (specializer) V implemented in a sublanguage of L, and a program P written in language L. Then one can specialize one's own partial evaluator V with respect to the program P:
V(V, P) = VP V(P, D) = VP(D)
VP is, in this case, a specialized partial evaluator.
Bibliography
Bjorner, Dines.; Ershov, Andrei P.; Jones, Neil D., editors. Partial Evaluation and Mixed Computation. North-Holland, 1988.
Ershov, A.P. Mixed computation: Potential applications and problems for study. Theoretical Computer Science, 18:41-67, 1982.
Futamura, Y. Partial evaluation of computing processs - an approach to a compiler-compiler. Systems, Computers, Controls, 2 (5): 45-50, 1971.
Hatcliff, John; Mogensen, Torben Æ.; Thiemann, Peter, editors. Partial Evaluation: Practice and Theory. Lecture Notes in Computer Science, vol. 1706. Springer-Verlag, 1999.
Jones, Neil D.; Gomard, Carsten K.; Sestoft, Peter. Partial Evaluation and Automatic Program Generation. Prentice Hall Series in Computer Science, 1993. Disponible online.
Jorring, U. y Scherlis, W.L. Compilers and staging transformation. 13th ACM Symposium on Principles of Programming Languages, St. Petersburg, Florida, pp. 86-96, New York: ACM, 1986.
Kleene, S.C. Introduction to Metamathematics. Van Nostrand, 1952.
Lombardi, L.A. Incremental Computation. En F.L. Alt and M. Rubinoff (eds.) Advances in Computers, vol. 8, pp. 247-333, Academia Press, 1967.
Partial-eval.org. Colección de recursos sobre evaluación parcial. http://partial-eval.org