

TuplesThis technical note is excerpted from the text of a proposal submitted by ISE to the Nonprofit International Consortium for Eiffel (NICE). It describes a set of extensions to Eiffel. This is a working document, precise for the most part but informal in places, and is currently under discussion. The original form of this document was entitled Tuples, routine objects and iterators and covered important applications of tuples. These applications now have a detailed discussion of their own. Make sure to read that discussion once you have learned about tuples. Because the note followed earlier discussions within the language committee of NICE, it lacks the customary "introduction" and "rationale" parts explaining the purpose of the proposed extensions. The rationale and applications should, however, quickly become clear to any reader familiar with Eiffel. The mechanism described below is available in ISE Eiffel 4.3, with a few limitations detailed below. 1. Tuple typesA new Kernel Library class is introduced: TUPLE. Alone among all classes, class TUPLE has a variable number of generic parameters. TUPLE, TUPLE [X], TUPLE [X, Y], TUPLE [X, Y, Z] and so on are all valid types, assuming valid types X, Y, Z and so on. Conformance rules: [CONF1] For n >= 0 TUPLE [U_{1}, U_{2}, ..., U_{n}, U_{n+1}] conforms to TUPLE [U_{1}, U_{2}, ..., U_{n}]
In particular all tuple types conform to TUPLE, with no parameter. [CONF2] For n >= 0 If *every* one of the types T_{1}, T_{2}, ..., T_{n} conforms to a type T, then TUPLE [T_{1}, T_{2}, ..., T_{n}] conforms to ARRAY [T]. Definition: a "tuple type" is any type based on class TUPLE, i.e. any type of the form TUPLE [T_{1}, T_{2}, ..., T_{n}] for any n (including 0, for which there is no generic parameter).
The domain of f contains the interval 1..n (in other words, f is defined for any i such that 1 <= i <= n). For 1 <= i <= n, f (i) is a member of T_{i}. With this definition, TUPLE_{n} is indeed a subset of TUPLE_{n+1}, and in particular TUPLE_{0}, the empty set, is a subset of TUPLE_{n} for any n.) Semantics: an instance of TUPLE [T_{1}, T_{2}, ..., T_{n}] is a tuple whose first element is an instance of T_{1}, the second element being an instance of T_{2} etc. (The precise definition is the mathematical one given in note 1.) Note that there can be more than n elements to the tuple: for example a tuple with first element 5 and second element "FOO" is an instance of all of the following tuple types: TUPLE; TUPLE [INTEGER]; TUPLE [INTEGER, STRING].
C [G > TUPLE] and then use the generic derivations C [TUPLE [X]] C [TUPLE [X, Y]]and so on. This also makes it possible to have the effect of some fixed parameters and some variable ones, as in C [G, H, I > TUPLE] so we have all the necessary flexibility.) 2. Tuple expressionsLet e_{1}, e_{2}, ..., e_{n} be expressions of respective types T_{1}, T_{2}, ..., T_{n}. Then the expression[e_{1}, e_{2}, ..., e_{n}] denotes an instance of TUPLE [T_{1}, T_{2}, ..., T_{n}], whose first element is e_{1}, the second element being e_{2} etc. Tuple expressions can be nested: whereas [1, 2, 3] is a tuple with three elements (representing an instance of TUPLE [INTEGER, INTEGER, INTEGER]), [1, [2, 3]] is a tuple with two elements, the second one itself a tuple; the overall expression represents an instance of TUPLE [INTEGER, TUPLE [INTEGER, INTEGER]. As a special case of tuple expression syntax, the delimiters [ and ] are replaced by parentheses for the tuple representing the actual argument list of a routine call (see section 4). 3. TUPLE featuresThe exact specification of class TUPLE will be described in an addition to ELKS. The principal features are: count (number of significant elements) item (i), with the obvious precondition: the ith element, of type ANY (since the value of i is not known at compile time); also first, second, third, fourth and fifth, of the appropriate types. put (x, i), with the obvious precondition: replace ith element with x. If argument x is not of the appropriate type T_{i} there is no effect. is_equal: redefined to consider only the first n elements, where n is the smaller length. Other features under consideration include: stripped (i): a tuple of type TUPLE [T_{1}, T_{2}, T_{i1}, T_{i+1}, ..., T_{n}], derived from the current one by removing the ith component, again with the obvious precondition. wedged (x, i): a tuple with one more element, inserted at position i. infix "+": tuple concatenation infix "++": element concatenation; t ++ x is the same thing as t.wedged (x, t.count + 1). In addition, there may be in class GENERAL the following three features: acceptable_tuple (t: TUPLE): BOOLEAN  Is t convertible into an object of the current  type? associated_tuple: TUPLE  Tuple made of all of this object's field ensure acceptable_tuple (Result) make_from_tuple (t: TUPLE)  Reset from t. require acceptable_tuple (t) ensure equal (associated_tuple, t)
4. What have we gained?First we have solved the only case in the Eiffel language in which an expression has no precisely defined type: polymorphic manifest arrays. We don't have manifest arrays any more, but manifest tuples, with a precisely defined type. No incompatibility is introduced thanks to rule CONF2. The original syntax for manifest arrays, Result := <<e_{1}, e_{2}, ..., e_{n}>>, will continue to be supported. Second, we can define functions that return multiple results. This is a quite significant increase in expressive power. No common language has that. (You have to go to Lisp and functional languages.) Just define TUPLE [...] as the result type; in the function, you will write things like Result := [e_{1}, e_{2}, ..., e_{n}] Also, from a theoretical viewpoint, feature calls are simpler and more homogeneous: every feature takes exactly one tuple as argument and returns exactly one tuple as a result. (Either of these tuples may be empty: the first for a feature with no argument, the second for a procedure.) The syntax for a call becomes Feature Arguments with Arguments defined as Tuple_expression where the Tuple_expression uses the form given in section 2 but with the outermost [ and ] delimiters replaced by parentheses to conform to usual practice. So the call f (a, b, c) which we continue to think of as having three arguments a, b and c, formally has only one tuple argument [a, b, c]. This is of course not to be confused with a call of the form g ([a, b, c]) which has one argument (a tuple with three elements) in both the ordinary and the formal sense. 5. Active, iterators, numerical applications, introspectionFor a set of important applications of tuples see the book chapter on delayed calls and iterators which also covers aspects of numerical software and related topics following from the tuple mechanism. 6. Temporary limitationsThe implementation of tuples in ISE Eiffel 4.3 has the following limitations: Conformance of ARRAY types to TUPLE types is not yet fully supported. Class TUPLE does not have features such as first and second. You must use item and, in most cases, an assignment attempt.
