Grr .. ok, to preserve Felix current semantics .. U ** V
only matches if V is a tuple, meaning *at least 2 components*. This means to model a tuple you have to do this: // Hack to get the parens in place: INNER tuple class Tuple[U] { virtual fun tuple_str (x:U) => str x; } // Any tuple of 3 or more components: INNER tuple instance[U,V with Str[U], Tuple[V]] Tuple[U ** V] { fun tuple_str (x: U ** V) => match x with | ?a ,, ?b => str a +", " + tuple_str b endmatch ; } // OUTER tuple: 3 or more components instance [U, V with Tuple[U ** V]] Str[U ** V] { fun str (x: U ** V) => "(" + tuple_str x +")"; } // OUTER tuple: two components // string instance[T,U] Str[T*U] { fun str (t:T, u:U) => "("+str t + ", " + str u+")"; } // Override to handle arrays of two elements instance[T] Str[T*T] { fun str (t1:T, t2:T) => "("+str t1 + ", " + str t2+")"; } Here the Tuple class is used to do the recursion. The Str class puts the ( parens ) around a whole tuple. This solves the problem that (1, (2.2, "x")) printed (1, 2.2, "x") because Felix doesn't have tuples of one element, so the tail element (2.2, "x") can't be distinguished from two tail elements. I **think** (note emphasis) this actually solves the problem. Can anyone come up with a counter-example? Or a proof it works? The "void" terminator looked good, but a lot more fiddling in the compiler would have been needed to make it work. This means in general to handle tuples you need the cases: T -- not a tuple U * V -- a pair HEAD ** TAIL -- 3 or more elements, polymorphic recursion In general: there are several solutions but we approach the time to rewrite the type system, so tuples and arrays are distinct, and both work from 0 up (we have to throw in manually-called isomorphisms to replace the current automagic ones). We also have to support void correctly. I particular although there are no values of void type, this should be valid: T ^ 0 which as usual is isomorphic to 1: its an array of no elements. Also this is valid: var x : void; Why? Well, why not? It's a variable that cannot be initialised or assigned to. If left alone it will get optimised away because it isn't used so we don't care about the representation. If we do this: var px = &x; we have an issue. We could make px NULL, and still optimise away the variable x. This would mean all pointers to void compared equal. Or we could just ban taking the pointer to a void, however that isn't very nice! -- john skaller skal...@users.sourceforge.net http://felix-lang.org ------------------------------------------------------------------------------ Live Security Virtual Conference Exclusive live event will cover all the ways today's security and threat landscape has changed and how IT managers can respond. Discussions will include endpoint security, mobile security and the latest in malware threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/ _______________________________________________ Felix-language mailing list Felix-language@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/felix-language