Tue Jan 10 13:27:50 EST 2012
Evaluation of recent work
Looking back at the last month or so, the following can be noted:
- The type class structure is better following a better understanding
on type classes in general (overlap & fundep) and cleaning up some
bugs and warts in the structure itself.
- C code generation turned out to be more difficult than expected.
Language.C AST seems to be quite usable, but C syntax in itself
isn't so simple as one might think. It's definitely useful to have
the intermediate Term language and it might even be useful to make a
better pretty-printed syntax.
- "Virtual structures" like (Unatom (Car (Cdr (Ref var)))) seemed to
be an essential addition to Term, and they map directly to C's
struct member dereference: var.m1.m0.m0. This allowed pack/unpack
and app/lam to be placed on (almost) the same footing.
- Construction (Cons, Atom, Nil) and destruction (Car, Cdr, Unatom)
are not the same thing. (duh! but apparently I got confused by
- Related: Structured variables and structured values are not the same
thing. Though they are related through morphisms (i.e. obtain a
structured variable for a structure of variable references).
- All structures down to the C level are binary trees, ending in
explicit 1-element leaf nodes. This seems to be essential for
avoiding instance ambiguity (A thing and a 1-element collecting of
things are not the same!)
- C code generation needed to be monadic to enable naming of C struct
types. It's not possible to do this in-place because the resulting
types are not considered to be equal (no structural matching in C).
- The stx argument to Control (i.e. Term in case of Code rep) doesn't
seem to be necessary. It's sufficient to use the struct-of-rep <->
rep-of-struct morphism and generate either struct of rep or rep of
struct terms with variables, as the user (i.e. Code) knows how to
deconstruct rep of struct (i.e. to Term).
- I found out that "partial" type annotation is possible. This makes
it possible to avoid manual specificiation of large class
constraints. Everything seems to infer as expected now.
- Existential types for Arrow instances are still a mistery. There
seems to be no inherent limitation, just an orgianization of type
class hierarchies that hide recursion relations necessary for
satisfying the Arrow (,) composition.
- Things get complicated when "commutating" multiple type
constructors, i.e. struct of reps of types <-> rep of struct of
types are relatively straightforward. When mixing in a 3rd one,
i.e. rep of array of struct of types it can get too complicated to
understand at a glance.. To build intuition, it helps to create an
exhaustive list of all combinations, eliminate those that are not
meaningful or relevant, and explicitly name the morphisms between
the remaining ones.