Here I discuss the logical foundation of *tuples*, in accordance with
the "data as function" concept as proposed by Jørgen Steensgaard-Madsen in his
1989 paper for the CACM titled "Typed Representation of Objects by Functions".

In Fexl I represent tuples inside the curly braces "{}". A tuple may have zero or more elements separated by spaces within the curly braces. Here are some examples of tuples whose elements are simple numbers:

{} {1} {1 2} {1 2 3} {1 2 3 4}

Note that the first example is the *empty tuple* {} consisting of zero
elements.

Although a tuple is a data object, it nevertheless behaves as a function when
you apply it to an argument. That argument is used as a *handler
function*, and all the elements of the tuple are passed into that handler
function as successive arguments. That is how you retrieve the individual
elements of a tuple almost effortlessly.

In light of that concept, here are the functional equivalents for the example tuples listed above:

(\f f) (\f f 1) (\f f 1 2) (\f f 1 2 3) (\f f 1 2 3 4)

To look into it a little further, let's look at an example of grabbing the elements of the tuple {1 2 3}.

# Here's our tuple. \p={1 2 3} # Now let's grab the elements of p, naming them x, y, and z. p \x\y\z # Print the elements. say ["x = "x] say ["y = "y] say ["z = "z]

So what is actually happening there, especially on this line?

p \x\y\z

First, I will add parentheses to highlight the exact functional structure:

\p={1 2 3} p (\x\y\z say ["x = "x] say ["y = "y] say ["z = "z] )

Next, I eliminate the intermediate "p" symbol:

{1 2 3} (\x\y\z say ["x = "x] say ["y = "y] say ["z = "z] )

Then I replace the tuple with its functional equivalent:

(\f f 1 2 3) (\x\y\z say ["x = "x] say ["y = "y] say ["z = "z] )

Now we are looking at a case of quite ordinary lambda reduction. The next step is to substitute the value of "f" with the argument passed in:

(\x\y\z say ["x = "x] say ["y = "y] say ["z = "z] ) 1 2 3

Then we proceed to substitute the values for the x, y, and z parameters:

say ["x = "1] say ["y = "2] say ["z = "3]

At that point it is abundantly clear how evaluation proceeds from there.