Hi Doug: thank you for the analysis of the problem with the invariants. Without primitive parts we have the invariants: print(parse(str)) equals str and parse(print(obj)) equals obj (for tree objects) provided the LL(1) conditions hold. What is the intent of Complex = [ float ] [ float ]. Complex numbers have an optional real part and an optional imaginary part. But to express this I would be perfectly happy to be forced to write: Complex = [ Float ] [ Float ]. or Complex = float float . with explicitly giving a zero (Complex (0,9), for example). I am leaning towards one (outlaw: optional parts of primitive type) because it allows us to guarantee both invariants. I think that a simple system with a few simple semantic exceptions and stronger invariants is easier to use than a system with no semantic exceptions but exceptions in the invariants. -- Karl >From dougo@ccs.neu.edu Wed Jun 17 07:44:36 1998 >From: Doug Orleans >To: dem@ccs.neu.edu >Subject: optional parts of primitive type > >What should we do with something like this? > > Foo = [ int ]. > >The problem is that optional parts are compared to null when >traversing, but you can't compare primitive types (e.g. int) to null. >Currently this generates a compile error if the universal traversal is >generated (which goes to all parts). As I see it, we have three >choices: > > 1. Outlaw it (with a better error message). > 2. Treat 0 (or false for boolean) as null, and don't traverse if > the part has that value. > 3. Always traverse the part. > >Note that "traversing" a part of primitive type only means that edge >wrappers are called, if any (e.g. "-> Foo,x,int" above). The main >difference you'd notice between cases 2 and 3 is when printing Foo >with a PrintVisitor; in case 2, if the int is set to 0, then it won't >be printed, whereas in case 3, it will. Note that it will be zero >when Foo is parsed both from the empty string and from the string "0". >So in neither case can we maintain the invariant: > > print(parse(str)) == str > >but in both cases we do maintain the invariant: > > parse(print(obj)) == obj > >(Actually it's .equals, not ==, but you get the point.) > >I'm leaning towards 3, since this is easier and faster, and 2 and 3 >seem otherwise pretty much equivalent to me. What do you think? > >--Doug >