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

Reply via email to