[Nickle]Recursive datatypes (was: Tonight's topics)
Keith Packard
nickle@nickle.org
Wed, 24 Jul 2002 11:26:00 -0700
Around 13 o'clock on Jul 24, Carl Worth wrote:
> typedef x;
> typedef struct {
> x y;
> } x;
> While I could probably live without this, what's the fundamental
> difference between that struct definition and the following:
It's not a matter of "probably" living without recursive structures, the
fact is you can't actually create a value of that type -- the
representation of this type is of infinite size. The current kludge is to
ensure that the automatic structure value creation code doesn't recurse in
this case, but that leaves us with a structure containing undefined
values, that's what we're trying to eliminate.
The way around this type problem is to use a type which can be represented
with more than one kind of value.
> typedef struct {
> poly y;
> } x;
Now I can represent values of this type easily:
x foo = { y = 7 };
x bar = { y = (x) { y = (x) { y = <> } } };
To avoid pure polymorphism, you can use a union type instead:
typedef list;
typedef union {
list next;
void end;
} listref;
typedef struct {
listref ref;
} list;
list l = { ref = (listref.next) (list) { ref = (listref.end) <> } };
union switch (l.ref) {
case next: printf ("next\n"); break;
case end: printf ("end\n"); break;
}
if (l.ref == listend) printf ("yes\n");
l.ref.next.ref.next = (list) { ref = listend };
ML has a cleaner syntax for unions which makes this look less awkward. The
advantage of unions is you can retain most of the compile-time
typechecking, and the run-time typechecking is all explicitly labeled in
the code.
-keith