Each piece of code has two parts: an "init" section and a "next" section.
Each of these has declaration, for any required variables, and code;

Init initializes the computation, expecting index 'first' to be
requested first, and calls to next to want next element
Init returns the type and size of the object by setting 'tsize'.

Next sets 'res' to the element with the next index, and updates the
index. Next is within the scope of init's variables.

Eval calls init and then next as many times as needed.

Init, next, and eval for functional forms have additional parameters.

This scheme is similar to "An APL compiler"; it is also similar to the
'88 budd paper on 'composition and compilation', but without the lambda
calculus aspects.

e.g. distl

init (in)
    fp_data obju, obj, vec;
    init (in);
    obju = next (in);
    obj = eval (obju);
    vec = next (in);
    tsize = init (vec);
next (in)
    fp_data el;
    el = next (vec);
    res = pair (obj, el);


e.g., function body:
data:
init (in)
    i_in = 0;
    tsize = in.tsize;
next (in)
    res = in.value->[i_in++];
driver for output:
    res = eval (expression);

definition of eval
eval (data)
  if (constant (data))
    res = data;
  else
    tsize = init (data, 1, 1)
    if (tsize >= vector)
      for (i = 0; i < tsize; i++)
        res.value->[i] = next (data);

Def a distl =>

void a (data)
fp_data data;
{
  fp_data obj, vec;
  register i, i_data, i_obj, i_vec, size_vec;

  i_data = 0;
  obju = data.value->elt [i_data++];
  obj = obju;
  vec = data.value->elt [i_data++];
  i_vec = 0;
  size_vec = vec.tsize;
  if (size_vec >= vector)
    for (i = 0; i < size_vec; i++)
      res.value->[i] = pair (obj, data.value->[i_data++]);
}

