1.10. Tuples

As you might guess from the title, Felix has tuples. A tuple is a value consisting of an ordered sequence of two or more values, not necessarily of the same type. Here are some examples of tuples:
  1,2
  "Hello", "World"
  (1, 2.7, "Hello")
  ()
The comma chain operator constructs tuples. While brackets are not always necessary, the comma operator has a low precedence so tuples usually appear in brackets. Notice there is a special unique empty tuple '()'. There are no tuples with one component: for all values 'a', '(a)' is equivalent.

Now perhaps you have guessed what I meant earlier when I said the function mid only had a single argument. If not, you get another chance, studying this example, which is equivalent to example 106.

Start C++ section to tut/examples/tut110.flx[1 /1 ]
     1: include "std";
     2: fun mid(a:int, b:int):int =
     3: {
     4:   val c = (a + b) / 2;
     5:   return c;
     6: }
     7: val x = (2,4);
     8: print (mid x); print "\n";
End C++ section to tut/examples/tut110.flx[1]
Here you can see that mid takes a single argument which is a tuple of two ints.

A tuple is a product type: you may be familiar with the Cartesian product of sets. The notation for tuple types is the same, except of course we use '*' instead of a multiply sign: here is the declaration of x with a type annotation:

  val x : int * int = (2,4);
You should note that tuple construction is not associative. Here are three tuple value declarations with type annotations:
  val x : int * int * int = (1,2,3);
  val y : (int * int) * int = ((1,2),3);
  val z : int * (int * int) = (1,(2,3));
These three tuples have distinct types and values. The first has three components, each of type int. The other two have two components each: an int and a pair of ints, in the two possible orderings.

The type of the empty tuple '()' is called 'unit'. It can also be called '1', the reason will become clear soon.

I said before that 'almost' all functions in Felix have one argument. The tuple constructor is the exception.

You can get at tuple components using a suffixed dot followed a zero origin integer in brackets:

Start C++ section to tut/examples/tut111.flx[1 /1 ]
     1: include "std";
     2: val x = (0,1,(3,4));
     3: print x.(0); print " ";
     4: print x.(1); print " ";
     5: print x.(2).(0); print " ";
     6: print x.(2).(1); print "\n";
End C++ section to tut/examples/tut111.flx[1]
The brackets are needed so the lexer doesn't get confused with floating point. The notation is ugly and not recommended .. there is a better way called pattern matching which you will learn about soon.