The Curried Creator

Functions that return functions seem peculiar, yet this hack simplified Haskell Curry’s math a couple of decades before the electronic computer. The pattern has wormed its way into recent computer languages where is solves other problems.

Most bodies of user mode code designed for a capability kernel include a small portion that runs to create a new instance of the object, a Zot, whose behavior the code defines. Strictly this portions defines the behavior of a different object called the Zot creator. This pattern is so convenient that it was perhaps universal in Keykos. I suspect it is a good plan for other capability platforms as well. The capability to the unique creator was conventionally called “ZotC” in the shared public directory where the creators of the common objects were found. Insofar as objects are functions, ZotC is a function that returns a function.

The pattern may be iterated at least once. The factory code was accessed by invoking the factory creator creator (FCC). When X invokes FCC the factory code selects a new brander so that X may create a family of types of objects that trusted each other. Objects of one of these types may collaborate with others of the family with small overhead. This first factory code would then create a new domain, perhaps named FC by X. FC belongs to X and if Y calls FCC he will receive a factory creator with another brander.

When FC is called another portion of the factory code will create a domain to serve as the creator of objects of some particular type, within the family. All this folderol is merely Currying (where a function evaluates to another function and f(x, y) is replaced by f(x)(y)).

Scheme:
(define (log10 x) (/ (log x) (log 10))) ; but better:
(define log10 (let ((z (/ (log 10)))) (lambda (x) (* z (log x)))))

C
#include <math.h>
typedef double f(double);
f log10 =({double z = 1./log(10); double log10(double x){return z*log(x);}; log10;})

Algol68:
PROC (REAL)REAL log10 = (REAL z = 1.0/log(10); (REAL x)REAL: z*log(x));

The Scheme code is valid and useful. The C code is rejected by most compilers as including nested procedure definitions. Gcc accepts the code but fails because the outer stack frame, holding z, vanishes before the function can be called. The Algol68 code was accepted by and useful for the AWRE compiler.

Destructors

Termination code was typically included and was typically the inverse of construction. If some step during creation was thwarted by insufficient space or other obstacle, it could conveniently GO TO (gasp) a spot in the destruction code that would uncreate what had just been created. (This is the only example of GO TO among the patterns that I embrace.)