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

Reply via email to