On 10/08/2012, at 10:24 PM, Shayne Fletcher wrote: > On 09/08/2012 21:17, john skaller wrote: >> ~/felix>flx --test=build/release --force p >> (1, (Hello, 1.3)) > > Very cool.
That wasn't because it only worked on a value of manifest tuple type, i.e. the type was known. But now, this is the coolness: ///////////////// // first define a virtual function class X[U] { virtual proc P : U; } // Now make the tuple-cons inductive version instance [U,V with Str[U]] X[U ** V] { proc P (x: U ** V) { match x with | ?a ,, ?b => println$ str a + ","; P b; endmatch; } } // specify the ground case instance [U with Str[U]] X[U] { proc P (x: U ) { println$ str x; } } // and of course test it open[Y] X[Y]; var x = 1,"Hello", 1.3; P x; /////////////////////// The method you see here is the *only* correct way to do *generic* operations on tuples of arbitrary length. Whilst we have a tuple of at least two elements we can split up the head element and tail, and then do polymorphic recursion on the tail. The recursion stops on the last element because it won't match the head,,tail pattern. I chose ,, as the separator for symmetry with ** as the type level of it, however the ** operator for types is Fortran "power" operator and has weird precedence. The ,, operator should ONLY be used in a pattern with the tail element as a type variable (although other cases might work, have to do some experiments). You cannot match a value with type a single type variable, so you cannot use this pattern for overloading. It must be resolved as shown at *instantiation* time to ensure that the length of the tail is known (and of course the types of the tail components). At instantiation time all the type variables are instantiated away. Yes, a match like this one does work: var y = match x with | ?a ,, ?b => a,b endmatch ; but it is entirely pointless because the length and types of the components of x are known: you might just as well match against ?a,?b,?c knowing the type is int * string * double. The compiler simply "unrolls" the type, that is, it just writes out the code each time for each component: there's no loop or anything, this is deferred overloading, which is what type class virtuals provide. We trick the compiler into thinking we have polymorphism to force early type checking, then do a second phase of checking on instantiation. Let me again say that the function above is NOT recursive, it is polymorphic recursion: P is not calling itself, in fact P doesn't exist. Rather P[int ** string * double] calls P[string ** double[ which calls P[double] (these are all distinct functions, even though the first two are generated from the same "template"). When you use a tuple the signature U ** V is more specialised that plain T, so it is selected until it doesn't match, then the plain T case is chosen. CAVEATS: it is known NOT to work on arrays. Make sure the last element is a different type until I fix it. For arrays we'll have to limit the array length. It is VERY annoying to have two representations of tuples. It is also VERY annoying that the tuple_cons representation is not a proper combinator, even in theory. Array indicies must be compact linear types, which is a constraint, but it is really only a practical one not a theoretical one. The cons_tuple representation is a hack because the constraint is theoretically mandatory: the tail HAS to be a tuple (or a single value). The correct way to do this is to have a "type list" construction and glue "tuple" on the front: I'm not doing that at the moment because then the tail is a new kind of variable (not a type variable but a type list variable). There should be a similar construction for sums. Also note, probably product and structs and cstructs, and of course enums variants and unions .. since these are all really either tuples or sums. In most compilers we'd use type erasure after binding to eliminate all but tuples and sums, however it is harder for Felix to do this because it has to generate typed C++ code with some resemblance to the original. -- 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