'apply' takes a function and applys it to each member e.g. [2 3] : apply double -> [4 6] e.g. (2 3) : apply double -> (4 6) 2 = (2) a function may return (2) which is a clear structure but behaves exactly like 2 so: apply 2 double -> 4 apply(f, 2) = f(2) f(2) -> apply(f, 2) f(2) <=> apply(func:f value:2) <=> apply(func:apply value:(func:f value:2)) so apply can be polymorphic, we know f(int) is defined, but f(box) is not however we can define apply(f, box) -> wrap(apply(f, get(box))) If box is a 'clear' box, wrap(wrap(box)) = wrap(box), and f(x) <=> wrap(2*x) is allowed too, i.e. either the function or the 'input' may determine the type of the outcome all this works for relations too e.g. relation x = y + z + :x :(y z) apply(func:+ arg:(:x :(y z))) invent a clear list box (a,b,c) (or ->a->b->c->) define: apply(func:f arg:(a:list (...))): (map(x, list): (a:(,1,2,3,) b:(,4,5,6,) c:(,1,3,5,)) -> (,(a:1 b:4 c:1), (a:2 b:5 c:3), (a:3, b:6, c:5),) ,1,2,3, ,4,5,6, <=> ,(1 4),(2 5),(3 6), a:(1 2) <=> a:1 a:2 e.g. 2 means "a 2" not "the 2" (normally) (1 2) *2 (2 4) = (4 2) (1,2) *2 (2,4) != (4,2) apply a relation ---------------- structure around each mapped argument is typically the same 5 m *2 10 m apply Rel (StructA ...) struct has: identity structure members place this is unboxed. A box is a struct containing a struct as a member apply Rel args:(Sa Sb Sc): Struct = Sa.struct = Sb.struct = Sc.struct each place P in Struct: S1 := () each member S in args M = get P in S add M to P in S1 apply Rel S1 apply Rel Args: S each Arg in Args: S = Struct(Arg) each Place P in S: Corresp each Arg at ArgP in Args: E at P in Arg E at ArgP in Corresp Rel Corresp