Selective Memoization with Box Types

Favio Ezequiel Miranda-Perea, Lourdes Del Carmen González-Huesca
2009 Electronical Notes in Theoretical Computer Science  
Memoization is a useful technique to eliminate computational redundancy. A memo function remembers all the arguments to which it has been applied, together with their corresponding results, by storing them in a table. This table is consulted before each functional call to determine if the particular argument is in it. If so, the call is skipped and the stored result is returned; otherwise the call is performed and its result added to the table. Acar, Belloch and Harper present a framework to
more » ... ly memoization selectively, that is, enabling the programmer to determine precisely the dependences between the input and the result of a function. This framework is efficient and yields programs whose performance can be analyzed using standard techniques. The language, implemented as an SML library, is based on a modal type system which allows the programmer to reveal the true data input/output dependences in a program. However, the modality seems to be an ad-hoc choice for the implementation. In this paper we develop selective memoization, using instead box types, corresponding to the necessitation modality . We also include non-memoized functions, and provide full proofs of type safeness and soundness of the dynamic semantics with respect to an effect-free system which is later translated into the very well-known language PCF . Open access under CC BY-NC-ND license. memoization framework presented in [2] provides control over equality and identification of dependences, and some control over space management. When detecting dependencies, it is essential not to omit any, or the function caching will be unsound. However, it is also important not to introduce too broad dependencies, or the memoization will be ineffective. For the technique to be most effective, each function call's dependencies must be recorded as precisely as possible. As an example consider the following simple function: fun f(x,y,z) = if x > 0 then y else z. The choice point (x>0) causes the arguments on which f depends, to change in a dynamic way. For instance in the call to f (1,2,3) the result depends only on x and y; the value of z being irrelevant. Moreover observe that the evaluation of f(x,y,z) does not depend on the exact value of the first argument x, since it suffices to know the sign of x; therefore, a later invocation to say f(3,2,35) in which the result is identical to the one in the previous call, for the argument y is identical, should yield a table lookup using as key the former input (1,2,3). To handle this kind of function calls efficiently, instead of using the input arguments to index the memo table, a list of choice points, called events, is used. Thus, this list, called branch of events, records the control flow of information from the input to the result of a function. This technique improves the memoization process, as showed in [2], although it could still yield recalculations as in the case of f(-1,5,2), since the argument -1 corresponds to a different event, namely not (x > 0). An incremental exploration process guided by a modal type reveals the needed dependences to build a branch. However, the modality ! employed in [2] for this purpose, seems to be an ad-hoc choice for the implementation. To build the type ! T , called a bang type, the underlying type T is required to be indexable, which means that T must admit an injective function, that maps each value of T to a unique integer. Therefore, the type ! T makes explicit the indexable feature of the type T 3 , which is needed for the implementation with hash tables, and although box types are mentioned as an important extension and even used in the implementation they were not formalized. In this paper we propose a system for selective memoization with essentially the same evaluation semantics but using a static semantics which dismisses bang types in favor of box types as defined in [11] . This type, corresponding to the necessitation modality in logic, has been used for different applications such as mobility and locality in distributed computation [9] , secure information flow [8] or extensions with persistent code [13] . To our purposes T can be thought of as a type which encapsulates certain ordinary values by means of immutable references, that is, there is a way to allocate values (box) and to deallocate them (let box). However, we cannot assign a new value to the same box. Furthermore, the encapsulation of a value v by a box signals that v should be explored to reveal its control and data dependences. Particularly, in practice, memoized functions involve a box type in their domains. As we will rely on the language MFL of [2] we give here a brief comparison between this system and our proposal: In this paper we are mainly interested in the mechanism of identification of dependences and their formal definition and behavior, 3 ! T could even be syntax sugar for the product type T, T → Int as implemented in [2] .
doi:10.1016/j.entcs.2009.11.006 fatcat:6tro5andozcr5kdk2o5pkgu34a