Index: doc/proposals/tuples.md
===================================================================
--- doc/proposals/tuples.md	(revision 86841ee36bf28dbbcead51789e9e5ffb8e8843a8)
+++ doc/proposals/tuples.md	(revision 86841ee36bf28dbbcead51789e9e5ffb8e8843a8)
@@ -0,0 +1,660 @@
+Tuples
+======
+
+This proposal is to update tuples, as they were created by Rob in his thesis,
+to address problems have appeared in their use since then. This proposal is
+an attempt to address some of those problems. Adding new functionality,
+updating existing features and removing some problematic features.
+
+The core of change is breaking the current restructurable tuples into
+unstructured tuples and structured tuples. Unstructured tuples handle most
+of the existing uses, with structured tuples filling in a few missing
+use cases.
+
+Current State of Tuples
+-----------------------
+An overview of the current design, as the starting place for the proposal.
+
+### Tuple Syntax
+
+An overview of the syntax for the main three components of tuples, the types
+of tuples, the tuple expressions/values (constructing tuples) and tuple index
+expressions (deconstructing tuples).
+
+Current syntax for tuple types:
+-   Nullary: [void] or []
+-   Unary: [TYPE]
+-   Binary: [TYPE, TYPE]
+-   The pattern continues for three or more elements.
+
+Current syntax for tuple expressions:
+-   Nullary: None. (Same as `void`, use return without an expression.)
+-   Unary: {EXPR} (This might be an error, but I can't make [EXPR] work.)
+-   Binary: [EXPR, EXPR]
+-   The pattern from binary continues for three or more elements.
+
+Current syntax for tuple index expressions, is much simpler. It uses the
+member index expression syntax, except the member name is replaced with the
+element index, which is an integer literal, showing the index of the element
+to get.
+
+Here is a brief example showing all three parts.
+
+	[char, int] tup;
+	tup = ['a', 0];
+	int value = t.1;
+
+### Mass and Multi-Assignment
+
+Two special forms of assignment can be used to set values in tuples.
+Mass Assignment assigns every element in the tuple to a single source value.
+
+	[int, long, float] dst;
+	int src = 4
+	dst = src;
+	// Expands to roughly: dst.0 = src, dst.1 = src, dst.2 = src
+
+Multi-Assignment assigns every element to the matching element of a source
+tuple (both tuples must be the same side).
+
+	[int, long, float] dst;
+	[int, long, double] src = [1, 20, 300.0];
+	dst = src;
+	// Expands to roughly: dst.0 = src.0, dst.1 = src.1, dst.2 = src.2
+	// Note that the last assignment is not an exact match,
+	// an implicit conversion will be applied.
+
+### Tuple Restructuring
+
+Tuples can be restructured as part of overload resolution. Function calls
+will unpack tuples and repack tuples to match signatures. This is a type of
+implicit conversion and is considered during overload resolution.
+
+A simple example is matching multiple parameters of a function to a single
+argument expression, each parameter is bound to a different element of the
+returned tuple.
+
+	[int, int] paramFunc();
+	void callFunc(int a, int b, int c, int d);
+
+	void restructure() {
+		callFunc(paramFunc(), paramFunc());
+	}
+	// Roughly equivilent to:
+	void restructure() {
+		[int, int] fst = paramFunc();
+		[int, int] snd = paramFunc();
+		callFunc(fst.0, fst.1, snd.0, snd.1);
+	}
+
+This is the unique feature of Cforall tuples. There are a few languages have
+multiple return values, but they are usually are a stand alone feature.
+
+### Tuple Casts
+
+C-style casts can be used on tuples. These usually conversion casts (casts
+that preform operations on the cast type, as opposed to reinterpreting the
+existing value).
+
+Tuple casts can remove elements from the end of a tuple and apply a recursive
+cast to any of the elements. As an example:
+
+	[char, char, char] x = ['a', 'b', 'c'];
+	([int, char])x;
+
+This casts the first element type from a char to an int and drops the last
+element. The second line can be replaced the following code, that creates
+a new tuple of by casting the kept elements of the old tuple:
+
+	[(int)x.0, (char)x.1];
+
+Note, tuple casting is more restricted than the implicit tuple restructuring.
+It cannot do any restructuring beyond dropping the trailing elements of
+tuples. For example, you cannot cast `[int, [bool, char], int]` to be a
+`[int, bool, char, int]`.
+
+### Polymorphic Tuple Parameters
+
+One kind of polymorphic parameter is the tuple type parameter, previously
+noted by the `ttype` keyword and now marked by a tailing ellipses (`...`).
+Although described as a tuple type, it is usually viewed as its flattened
+sequence of types.
+
+	forall(T, Ts... | { T max(T, T); T max(Ts); })
+	T max(T arg, Ts args) {
+		return max(arg, max(args));
+	}
+
+This introduces a type name into scope. It is used as a type but because the
+tuple is flattened, the second assertion "T max(Ts);" matches types with
+multiple parameters, although it is used as a tuple function inside the
+function body. For example, in three argument case (all three of the
+same type), both assertions can match the same function. Then "Ts args"
+introduces args as a tuple, where it is past to max.
+
+Issues with the Current State
+-----------------------------
+There are a veriaty of problems with the current implementation which we
+would like to fix.
+
+### Tuples are not Objects
+
+Spoilers, this proposal actually takes them further away from being objects.
+But this illistrates why the current version is not as useful is it could be.
+
+Tuples do not have the lifetime operators (copy construction, copy assignment
+and destructor) and cannot be passed in as a bundle to polymorphic functions.
+The multi-assignment operation is not a single function and is not passed
+in as an assertion.
+
+This prevents tuples from being interwoven with regular polymorphic code.
+
+### Providing TType Arguments is Inconistent
+
+The syntax for ttype arguments is slightly inconsistent. It hasn't come up
+much yet because you do not directly provide ttype polymorphic arguments to
+functions and the are very few existing use-cases for ttype structures.
+
+Passing arguments to a function inlines the arguments into inlines the
+arguments while passing them to a polymorphic type requires them to be
+enclosed in a tuple. Compare `function(x, y, z)` with `Type(A, [B, C])`.
+
+This did not come up previously as there was little reason to explicity
+provide ttype arguments. They are implicit for functions and there is very
+little use case for a ttype on a struct or union.
+
+### Syntax Conflict
+
+The tuple syntax conflicts with designators and the new attribute syntax.
+These conflicts break C compatability goals of Cforall. Designators have had
+to their syntax change and Cforall cannot parse the new attributes.
+
+Although most of this redesign is about the semantics of tuples, but an
+update to tuple syntax that removes these conflicts that would improve the
+compatability of Cforall going forward (and also open up the new attribute
+syntax for cforall features).
+
+Change in Model
+---------------
+This proposal modifies the existing tuples to better handle its main use
+cases. There are some use cases that are no longer handled, and a new
+struct tuple is added to cover those cases.
+
+The existing tuples will be even more "unstructured" than they are now.
+Tuples are considered a sequence of types or typed entities. These packs are
+then unpacked into the surounding context. Put differently, tuples are now
+flattened as much as possible, with some places (like parameter lists) being
+treated as an implicit tuple and the tuple being flattened into that.
+
+Structred tuples are now a separate feature, a structure called "tuple".
+These are polymorphic structures, an instance should act as a structure
+except that use indices instead of field names. These structures shouldn't
+have to be used often, but fill in the use cases that unstructured tuples
+no longer support.
+
+Note that the underlying implementation might not actually look like this.
+
+Changed Features
+----------------
+Some of the concrete changes to the features of the languages.
+
+### Structured Tuple Type
+
+There are still use cases for a structured tuple type. The issues in
+supporting both were because there was one feature trying to support both
+uses. Hence, it is added back in as its own feature.
+
+There should be a standard library or built-in type named `tuple`, it doesn't
+need a special syntax to write types or instances. The type definition might
+use some primitive support, but if supported as a regular type would look
+something like this:
+
+	forall(Ts...)
+	struct tuple {
+		inline Ts all;
+	};
+
+This will be constructed the same way as most types, a list initializer with
+each tuple argument, and the lifetime functions (copy construction, copy
+assignment and destruction) work the same. Field access works two ways, the
+first is accessing the all field, effectively converting the structured
+"struct" tuple into an unstructured tuple, the other is to use tuple indexing
+directly on the structure as if it was an unstructured tuple.
+
+(If inline doesn't work, just rename all to `get`. It does make things a bit
+longer but has no change in functionality. If the all access doesn't work,
+that is a bit more of a problem, tuple slicing might provide a work around.)
+
+### Type Qualifier Distribution
+
+Because tuples are no longer object types, applying type modifiers to them,
+such as cv-qualifiers and pointers, no longer makes sense. That syntax is
+now considered distribution, applying the type modifier to each element of
+the tuple.
+
+Previously `[int, bool] &` would mean a reference to a tuple of an integer
+and a boolean. Now it would be an alias for `[int &, bool &]`, a tuple of a
+reference to an integer and a reference to a boolean. This also applies to
+polymorphic tuple type packs `Ts &` in polymorphic functions.
+
+This allows to specify restrictions on types as you would with a single
+type variable. For example, this can help replace the special cased
+tuple operations, multi-assignment (N-to-N) and mass-assignment (1-to-N).
+
+	// Multi-Assignment
+	forall(T, Us... |
+			{ T & ?=?(T &, T const &); Us & ?=?(Us &, Us const &); })
+	[T, Us] & ?=?(T & dst, Us & dsts, T const & src, Us const & srcs) {
+		dst = src;
+		dsts = srcs;
+		return [dst, dsts];
+	}
+
+	// Mass-Assignment
+	forall(T, U, Vs... |
+			{ U & ?=?(U &, T const &); Vs & ?=?(Vs &, T const &); })
+	[U, Vs] & ?=?(U & dst, Vs & dsts, T const & src) {
+		dst = src;
+		dsts = src;
+		return [dst, dsts];
+	}
+
+These may not work exactly as given (for one, the copy assignment assertion
+in the first function would likely be redundent/conflicting with the implicit
+assertions on the parameters), but they show the pattern. Multi-assignment
+is also would be very hard to write with simple tuple types, because the
+relationship between the two halves of the parameter list does have to line
+up, that cannot be enforced with two different tuples.
+
+### Type Packs
+
+This is not a new feature, but a reframing/extension of existing tuple tuple
+polymorphic parameters as polymorphic type packs. The `Vars...` syntax
+introduces a pack of types into scope. It can be used in many of the same
+ways as a tuple tuple, but in some new ways to.
+
+The primary existing use remains, you can use a polymorphic pack in a
+parameter list, both as part of an assertion and in the signature of the
+main function. The difference, is that this is not an enclosed tuple, but
+a series of types. The only effective difference this makes is it doesn't
+prefer to match another tuple/pack.
+
+This pattern continues to a parameter defined with a pack of types, which
+is considered a pack of parameters, and the name of it introduces is a pack
+of variables, or a flattened tuple.
+
+	forall(Params...)
+	void function(Params values);
+
+New uses cases include declarations of members and variables. For example,
+the creation the structured tuple structure:
+
+	forall(Fields...)
+	struct tuple {
+		Fields get;
+	};
+
+This is again, treated as a pack of members. They have the same layout as
+if they were written out by hand. Now, the name get is still accessed is if
+it was a regular, singular, member. The result of that expression is a
+pack expression, a tuple of all the field accesses, which can be used with a
+tuple index expression to access the underlying members. For example:
+
+	tuple(bool, char, int) data = { ... };
+	// This expression:
+	data.get.2;
+	// Is the same as (if the fields had these names):
+	data.[__anonymous0, __anonymous1, __anonymous2].2;
+
+For local declarations it works similarly, except the name introduced is
+directly usable as a tuple.
+
+	forall(Objects...)
+	void function( ??? ) {
+		???
+		Objects objs = ???;
+		???
+	}
+
+### Tuple Declaration/Deconstruction
+
+Declaring a tuple acts as a pack of variable declarations. When this is done
+with written out type (as opposed to a polymorphic parameter above), then the
+elements of the tuple can be named.
+
+	[int quo, int rem] ret = divmod(a, b);
+
+Here `ret` refers to the tuple, the entire pack, while `quo` and `rem`
+give explicit names to elements of the tuple. Not all the names have to be
+provided, at the very least, any element name can be omitted if the pack name
+is provided, and the pack name can be omitted if all the element names are
+provided. That would ensure every element can be accessed, but it could be
+reduced even more, effectively immediately dropping some values if there is
+no named to access it.
+
+### Tuple Casts
+
+Tuple casts are no longer allowed to do any restructuring. Internal
+restructuring would not be useful, as there is no internal structure.
+Dropping tail elements could be added back in but it is a narrow use case
+so it may be replaced with other features (for example: tuple slicing).
+
+### Forbidden Tuples
+
+The unstructured tuple cannot represent all the types that the previous
+semi-structured tuple could. These cases still exist in various ways,
+special in the internals of a polymorphic type, but general should be
+considered in their reduced form.
+
+Forbidding some of these tuples may remove ambiguity and solve some syntax
+conflicts that currently exist.
+
+Nullary, or 0 element tuples, are equivlent to void, the type that carries
+no data, because they do not either. It should either be replaced with void
+or removed entirely when it appears in a larger sequence.
+
+	// For example, this function:
+	forall(Ts...) Ts example(int first
+	// With Ts = [], should not be treated as:
+	[] example(int first, [] middle, int last);
+	// But instead:
+	void example(int first, int last);
+
+Unary, or 1 element tuples, should be the same as their element type. That
+is to say a single type in an unstructured tuple is a no-op.
+
+Lastly, nested tuples are always flattened into to form a one deep tuple.
+This means that `[bool, [char, int], float]` is resolved as
+`[bool, char, int, float]`, with the internal structure of the tuple ignored.
+
+The flatten into a large sequence rule mentioned above, is actually just an
+application of this. Unstructured tuples can already be restructured, even
+at the top level of an function call. This can be expressed by considering
+the argument list as a tuple:
+
+	call(false, ['a', -7], 3.14)
+	call([false, ['a', -7], 3.14])
+	call([false, 'a', -7, 3.14])
+	call(false, 'a', -7, 3.14)
+
+The ability to write nested tuples may remain so tuple deconstruction can be
+used to name a slice of the tuple.
+
+### Tuple Slicing (Range Tuple Indexing)
+
+(Disclaimer: this is a bit more impulsive, see end for notes.)
+
+This is an extension to tuple indexing. Currently, you may index single
+location of a tuple, extracting the element at that location. By extending
+the index expression to be a range we can grab a slice of the existing tuple
+as another smaller tuple.
+
+	[int_x, char_y] = [int_a, char_b, double_c].(0+~=1)
+
+To get the new tuple, the range has to be constructed and traversed at
+compile time. The size of the range is the size of the result tuple, with
+each element in the result tuple decided by the matching element of the
+range, which gives the index of the original tuple to place there.
+The type of the indices may be and intergal type, but all indices must be in
+range, otherwise it is a compile time error.
+
+In terms of the existing range loops, if you could write this dynamically, it
+would look something like this:
+
+	// Implementation of: output = input.RANGE
+	dyn output = []
+	for ( index : RANGE ) { output = [output, input.index] }
+
+The result of the expression is only has to be considered a tuple if the
+range has two or more values, otherwise it can be considered void or the same
+as indexing the single value in the range.
+
+Some closing notes, this is dependent on generalised range expressions.
+The iterators proposal has a section on some new range types, this feature
+is intended to be built on that feature. Not simply reuse some of the syntax
+that is also used in the special for loop. And compile-time evaluation may
+need to be improved.
+
+Implementation
+--------------
+An overview of the implementation details of the new proposal.
+
+### Structured Tuple Implementation
+Under the hood, unstructured tuples will probably just be implemented as
+structured tuples, with the restructuring code inserted wherever needed.
+In short, the base implementation should stay mostly the same.
+
+Actually inlining tuples can be done in some cases, it may even help with
+some forms like a fixed tuple decomposition. However, polymorphic tuples
+still need to be reduced to a single generic form, which would be a
+polymorphic container, a tuple.
+
+### AST Updates
+The current AST cannot represent all the new features. Particularly, an
+object declaration cannot name elements of the tuple. To this end a new
+node type, `TupleDecl`, should be added to handle tuple deconstruction
+declarations (other cases can still be handled with `ObjectDecl`).
+
+This would act much like a `FunctionDecl` except for tuples, narrowing the
+possible types, to `TupleType` instances instead of `FunctionType` instances,
+and storing some additonal information, in this case the names of the
+elements of the tuples.
+
+(I'm not actually going to decide the implementation now, but some early
+examination of the problem suggests that it might be better off wrapping a
+series of `ObjectDecl` rather than just some strings to hold the names.)
+
+### Field Packs
+Field packs in structures will probably have to be written out in full by
+the specialization pass. If they are not it could have some negative effects
+on layout, causing a structure to take up extra space. It may be able to
+reuse some of the specialization code for the existing tuples.
+
+Related Features in Other Languages
+-----------------------------------
+Other languages have similar features. Organized by the related feature.
+
+(In hindsight, I may have gone overboard with the number of examples.)
+
+### Structured Tuples
+
+There are many languages with structured tuples. Usually just called tuples,
+but they usually follow the same rules as a polymorphic anonymous structures,
+that is to say you provide N types to create a new N-arity tuple. They also
+usually have some special syntax to index the tuples, because there are no
+field names to use.
+
+#### Rust
+Rust has the standard tuples as a primitive in the language. Each arity of
+tuple is a different polymorphic type.
+
+Tuple types and expressions are written with a parenthesized, comma seperated
+list of types or expressions. To avoid confusion with the grouping "(...)",
+one element tuples must have a trailing comma (and larger tuples may have a
+trailing comma).
+
+	const empty: () = ();
+	const single: (usize,) = (12,)
+	const double: (usize, isize) = (34, -56);
+
+Element access uses similar syntax to field access (that is "."), but uses an
+interger literal instead of a field name (for example: "pair.1"). Tuples
+support pattern matching with similar syntax to their expression form.
+
+Some tuple features only apply up to 12-arity tuples.
+It is not directly stated, but I believe the difference is the more limited
+features are implemented in the standard library, for each arity of tuple.
+
+-   https://doc.rust-lang.org/std/primitive.tuple.html
+-   https://doc.rust-lang.org/reference/types/tuple.html
+-   https://doc.rust-lang.org/reference/expressions/tuple-expr.html
+
+#### C++
+Implemented as a template type defined in the standard library. No special
+language features exist to support this, due to the power of C++'s template
+meta-programming.
+
+C++ is also one of the few languages with support for varadic polymorphic
+types, so there is one template that defines all the types. It is written
+as `std::tuple<TYPE...>`, where "TYPE..." is any number of comma separated
+types. This is the standard notation for template type instances.
+
+There is no special syntax for member access of a tuple. You have to use a
+template function for example `std::get<0>( tuple )`.
+
+C++ also has structured binding, a kind of limited pattern matching. In a
+structured binding declaration, you can write an auto typed declaration with
+a list of identifiers in a `[]` list.
+For example, `auto [first, second] = getSize2Tuple();`.
+
+-   https://en.cppreference.com/w/cpp/utility/tuple
+-   https://en.cppreference.com/w/cpp/language/structured_binding
+
+#### Haskell
+Haskell has a special syntax for tuples, but otherwise they are completely
+normal polymorphic types. Because of this, tuples have a maximum size.
+Haskell (98) supports tuples of up to 15 elements and the standard library
+has functions for tuples of up to 7 elements.
+
+The syntax for tuples is a comma seperated list of elements. Either element
+types to create a tuple type, or element values to create a tuple value. The
+context decides which one we are looking for. Such as `(6, "six")` or
+`(Bool, Char, Int)`.
+
+You can also remove all the elements, getting an expression like "(,)" or
+"(,,,)", which can be then be used as a function, for a type or expression.
+
+Haskell supports pattern matching as the main way to extract values from a
+tuple, although helper functions "fst" and "snd" are provided for field
+access on two element tuples.
+
+Haskell does not have 0 or 1-element tuples. The nil type, written "()" for
+both type and value, is effectively the 0 element tuple. There is also a type
+called "Solo" that is a polymorphic structure with one field and is used as
+the 1-element tuple, but has regular Haskell data type syntax.
+
+-   https://www.haskell.org/onlinereport/basic.html
+
+#### OCaml
+OCaml only supports multi-element (2 or more) tuples. Tuple types are written
+as a '*' separated list of types, tuple values are written as ',' separated
+list of expressions. Pattern matching tuples is supported and uses the same
+syntax as values. Parenthesizing these lists is only needed for grouping.
+
+OCaml does not support 0 or 1 element tuples. It does however have the `unit`
+type which has one value written `()`.
+
+-   https://ocaml.org/docs/basic-data-types#tuples
+
+#### Swift
+Swift has tuple types that use the basic parenthesized list of comma
+separated list of types or values. It only supports 0 and 2 or more element
+tuples (the `Void` type is an alias for the empty tuple type).
+
+Swift also supports named tuples. Names can be added to before the tuple
+element, both for the tuple type and value. The syntax is a name followed by
+a colon, for example `(first: int, second: int)`. These names are a fixed
+part of the type, and can be used as part of field access notation (otherwise
+numbers are used in-place of field names `tuple.0` vs. `tuple.first`).
+
+-   https://docs.swift.org/swift-book/documentation/the-swift-programming-language/types/#Tuple-Type
+
+#### Python
+In Python tuples are immutable lists. Because they are dynamically typed
+there is only one tuple type `tuple`.
+
+It also has various named tuples. The first, namedtuple, just allows you to
+add a name the elements of the tuple. The second, NamedTuple, is actually a
+way of creating a typed record in a normally untyped language.
+
+-   https://docs.python.org/3/library/stdtypes.html#sequence-types-list-tuple-range
+-   https://docs.python.org/3/library/collections.html#collections.namedtuple
+-   https://docs.python.org/3/library/typing.html#typing.NamedTuple
+
+#### LISP
+As LISP is dynamically typed, its cons data type is an untyped pair and is
+(perhaps infamously) the main constructor of all compound data types.
+The function `cons` takes two arguments and builds a pair. Functions `car`
+and `cdr` get the first and second elements of the pair.
+
+### Packs
+
+Packs (or unstructures tuples) are a much less common feature. In fact, there
+might just be one language, C++, that supports packs. The most common use
+case for unstructured tuples is returning multiple values, so there is a
+comparison to languages that have that as a special feature.
+
+#### Go
+Go does not have built in tuple types, but it has multi-return syntax that
+looks like the tuple syntax of many other languages.
+
+```
+func main() {
+	i, j := returnIntInt()
+	...
+}
+
+func returnIntInt() (int, int) {
+	return 12, 34
+}
+```
+
+-   https://golangdocs.com/functions-in-golang
+-   https://go.dev/src/go/types/tuple.go
+
+#### Lua
+Lua is a scripting languague, is dynamically typed and stack based. Although
+the stack usually only directly visible in the C-API, it does allow any
+function to return any number of values. Even in a single return, if the
+return expression
+
+```
+local funcion f()
+	return 12, 34
+end
+
+local i, j = f()
+```
+
+#### C++
+C++ templates can take various types of parameters, including parameter
+packs. These contain series of values. These are used in pack expansion,
+which usually expand to a comma separated list, but it can also be a chain of
+boolean binary operator applications. For example, if the parameter
+`typename... Ts` is in scope, then you can declare `std::tuple<Ts...>` to
+introduce a tuple type, if Ts = bool, char, int then the type becomes
+`std::tuple<bool, char, int>`.
+
+A common use is for perfect argument forwarding, which shows some different
+uses of the pattern:
+
+```
+template<typename inner_t>
+class Outer {
+	inner_t inner;
+public:
+	template<typename... Args>
+	Outer(Args&&... args) : inner(std::foward<Args>(args)...) {}
+};
+```
+
+In the first application, `Args&&... args` both uses a pack and introduces
+another one. `Arg0&& arg0, Arg1&& arg1, Arg2&& arg2, ...` is the pattern
+it explands too. The `&&` is used to copy the argument type's reference
+qualifier (the default can strip references away).
+
+The second application, `std::forward<Args>(args)...` uses two packs. These
+are expanded in parellel, and must be the same length (in this case they
+always will be). It also helps show that the `...` is actually the bit doing
+the expansion, it is a suffix "operator" to the expansion pattern.
+
+There are also fold expressions that use binary operators to combine a pack
+into a single expression. For example, `args + ... + 0` which adds every
+element of the `args` pack together.
+
+C++ about the best you could ask for in this area, but it does a lot of work
+at compile time to make this happen.
+
+-   https://en.cppreference.com/w/cpp/language/template_parameters
+-   https://en.cppreference.com/w/cpp/language/parameter_pack
+-   https://en.cppreference.com/w/cpp/language/fold
Index: c/proposals/tuples/Makefile
===================================================================
--- doc/proposals/tuples/Makefile	(revision c82dad4e91592787d98be7b164b82f68e16bb70d)
+++ 	(revision )
@@ -1,92 +1,0 @@
-## Define the configuration variables.
-
-Build = build
-Figures = figures
-Macros = ../../LaTeXmacros
-Bib = ../../bibliography
-
-TeXLIB = .:${Macros}:${MACROS}/listings:${MACROS}/enumitem:${Bib}/:
-LaTeX  = TEXINPUTS=${TeXLIB} && export TEXINPUTS && latex -halt-on-error -output-directory=${Build}
-BibTeX = BIBINPUTS=${TeXLIB} && export BIBINPUTS && bibtex
-
-MAKEFLAGS = --no-print-directory --silent #
-VPATH = ${Build} ${Figures}
-
-## Define the text source files.
-
-SOURCES = ${addsuffix .tex, \
-tuples \
-}
-
-FIGURES = ${addsuffix .tex, \
-}
-
-PICTURES = ${addsuffix .pstex, \
-}
-
-PROGRAMS = ${addsuffix .tex, \
-}
-
-GRAPHS = ${addsuffix .tex, \
-}
-
-## Define the documents that need to be made.
-
-DOCUMENT = tuples.pdf
-BASE = ${basename ${DOCUMENT}}
-
-# Directives #
-
-.PHONY : all clean					# not file names
-
-all : ${DOCUMENT}
-
-clean :
-	@rm -frv ${DOCUMENT} ${BASE}.ps ${Build}
-
-# File Dependencies #
-
-${DOCUMENT} : ${BASE}.ps
-	ps2pdf $<
-
-${BASE}.ps : ${BASE}.dvi
-	dvips ${Build}/$< -o $@
-
-${BASE}.dvi : Makefile ${GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} \
-		${Macros}/common.tex ${Macros}/indexstyle ${Bib}/pl.bib | ${Build}
-	# Conditionally create an empty *.ind (index) file for inclusion until makeindex is run.
-	#if [ ! -r ${basename $@}.ind ] ; then touch ${Build}/${basename $@}.ind ; fi
-	# Must have *.aux file containing citations for bibtex
-	if [ ! -r ${basename $@}.aux ] ; then ${LaTeX} ${basename $@}.tex ; fi
-	-${BibTeX} ${Build}/${basename $@}
-	# Some citations reference others so run again to resolve these citations
-	${LaTeX} ${basename $@}.tex
-	-${BibTeX} ${Build}/${basename $@}
-	# Make index from *.aux entries and input index at end of document
-	#makeindex -s ${Macros}/indexstyle ${Build}/${basename $@}.idx
-	# Run again to finish citations
-	${LaTeX} ${basename $@}.tex
-	# Run again to get index title into table of contents
-	${LaTeX} ${basename $@}.tex
-
-predefined :
-	sed -f predefined.sed ${basename ${DOCUMENT}}.tex > ${basename $@}.cf
-
-## Define the default recipes.
-
-${Build}:
-	mkdir -p ${Build}
-
-%.tex : %.fig | ${Build}
-	fig2dev -L eepic $< > ${Build}/$@
-
-%.ps : %.fig | ${Build}
-	fig2dev -L ps $< > ${Build}/$@
-
-%.pstex : %.fig | ${Build}
-	fig2dev -L pstex $< > ${Build}/$@
-	fig2dev -L pstex_t -p ${Build}/$@ $< > ${Build}/$@_t
-
-# Local Variables: #
-# compile-command: "make" #
-# End: #
Index: c/proposals/tuples/tuples.tex
===================================================================
--- doc/proposals/tuples/tuples.tex	(revision c82dad4e91592787d98be7b164b82f68e16bb70d)
+++ 	(revision )
@@ -1,339 +1,0 @@
-\documentclass[twoside,11pt]{article}
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-% Latex packages used in the document (copied from CFA user manual).
-\usepackage[T1]{fontenc}                                % allow Latin1 (extended ASCII) characters
-\usepackage{textcomp}
-\usepackage[latin1]{inputenc}
-
-\usepackage{fullpage,times,comment}
-\usepackage{epic,eepic}
-\usepackage{upquote}					% switch curled `'" to straight
-\usepackage{calc}
-\usepackage{xspace}
-\usepackage{graphicx}
-\usepackage{varioref}					% extended references
-\usepackage{listings}					% format program code
-\usepackage[flushmargin]{footmisc}			% support label/reference in footnote
-\usepackage{latexsym}                                   % \Box glyph
-\usepackage{mathptmx}                                   % better math font with "times"
-\usepackage[usenames]{color}
-\usepackage[pagewise]{lineno}
-\renewcommand{\linenumberfont}{\scriptsize\sffamily}
-\input{common}                                          % bespoke macros used in the document
-\usepackage[dvips,plainpages=false,pdfpagelabels,pdfpagemode=UseNone,colorlinks=true,pagebackref=true,linkcolor=blue,citecolor=blue,urlcolor=blue,pagebackref=true,breaklinks=true]{hyperref}
-\usepackage{breakurl}
-\renewcommand{\UrlFont}{\small\sf}
-
-\setlength{\topmargin}{-0.45in}				% move running title into header
-\setlength{\headsep}{0.25in}
-
-\usepackage{caption}
-\usepackage{subcaption}
-\usepackage{bigfoot}
-
-\interfootnotelinepenalty=10000
-
-\CFAStyle						% use default CFA format-style
-% inline code ©...© (copyright symbol) emacs: C-q M-)
-% red highlighting ®...® (registered trademark symbol) emacs: C-q M-.
-% blue highlighting ß...ß (sharp s symbol) emacs: C-q M-_
-% green highlighting ¢...¢ (cent symbol) emacs: C-q M-"
-% LaTex escape §...§ (section symbol) emacs: C-q M-'
-% keyword escape ¶...¶ (pilcrow symbol) emacs: C-q M-^
-% math escape $...$ (dollar symbol)
-
-
-\title{
-\Huge \vspace*{1in} Tuple Design in \CFA \\
-\vspace*{1in}
-}
-
-\author{
-\huge Rob Schluntz \\
-\Large \vspace*{0.1in} \texttt{rschlunt@uwaterloo.ca} \\
-\Large Cheriton School of Computer Science \\
-\Large University of Waterloo
-}
-
-\date{
-\today
-}
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-\newcommand{\bigO}[1]{O\!\left( #1 \right)}
-
-\begin{document}
-\pagestyle{headings}
-% changed after setting pagestyle
-\renewcommand{\sectionmark}[1]{\markboth{\thesection\quad #1}{\thesection\quad #1}}
-\renewcommand{\subsectionmark}[1]{\markboth{\thesubsection\quad #1}{\thesubsection\quad #1}}
-\pagenumbering{roman}
-% \linenumbers                                            % comment out to turn off line numbering
-
-\maketitle
-\thispagestyle{empty}
-
-\clearpage
-\thispagestyle{plain}
-\pdfbookmark[1]{Contents}{section}
-\tableofcontents
-
-\clearpage
-\thispagestyle{plain}
-\pagenumbering{arabic}
-
-
-\section{Introduction}
-This document describes my understanding of the existing tuple design~\cite{Buhr94a,Till89}, mixed with my thoughts on improvements after various discussions with Peter, Aaron, and Thierry.
-
-\section{Tuple Expressions}
-A tuple expression is an expression which produces a fixed-size, ordered list of values of heterogeneous types.
-The type of a tuple expression is the tuple of the subexpression types.
-In Cforall, a tuple expression is denoted by a list of expressions enclosed in square brackets.
-
-For example, the expression ©[5, 'x', 10.5]© has type ©[int, char, double]©.
-Tuples are a compile-time phenomenon and have little to no run-time presence.
-
-\subsection{Tuple Variables}
-It is possible to have variables of tuple type, pointer to tuple type, and array of tuple type.
-Tuple types can be composed of any types, except for array types \footnote{I did not see this issue mentioned at all in the original design. A tuple containing an array type seems to make sense up until you try to use a tuple containing an array type as a function parameter. At this point you lose information about the size of the array, which makes tuple assignment difficult. Rather than allowing arrays in most situations and disallowing only as function parameters, it seems like it would be better to be consistent across the board.}.
-
-\begin{lstlisting}
-[double, int] di;
-[double, int] * pdi
-[double, int] adi[10];
-\end{lstlisting}
-The program above declares a variable of type ©[double, int]©, a variable of type pointer to ©[double, int]©, and an array of ten ©[double, int]©.
-
-\subsection{Flattening and Structuring}
-In Cforall, tuples do not have a rigid structure.
-In function call contexts, tuples support implicit flattening and restructuring \footnote{In the original tuple design, four tuple coercions were described: opening, closing, flattening, and structuring. I've combined flattening with opening and structuring with closing in my description, as the distinctions do not seem useful in Cforall since these coercions happen only as arguments to function calls, and I believe all of the semantics are properly covered by the simplified descriptions.}. Tuple flattening recursively expands a tuple into the list of its basic components. Tuple structuring packages a list of expressions into a value of tuple type.
-
-\begin{lstlisting}
-int f(int, int);
-int g([int, int]);
-int h(int, [int, int]);
-[int, int] x;
-int y;
-
-f(x);
-g(y, 10);
-h(x, y);
-\end{lstlisting}
-In Cforall, each of these calls is valid.
-In the call to ©f©, ©x© is implicitly flattened so that the components of ©x© are passed as the two arguments to ©f©.
-For the call to ©g©, the values ©y© and ©10© are structured into a single argument of type ©[int, int]© to match the type of the parameter of ©g©.
-Finally, in the call to ©h©, ©y© is flattened to yield an argument list of length 3, of which the first component of ©x© is passed as the first parameter of ©h©, and the second component of ©x© and ©y© are structured into the second argument of type ©[int, int]©.
-
-\section{Functions}
-\subsection{Argument Passing}
-In resolving a function call, all of the arguments to the call are flattened.
-While determining if a particular function/argument-list combination is valid, the arguments are structured to match the shape of each formal parameter, in order.
-
-For example, given a function declaration ©[int] f(int, [double, int])©, the call ©f([5, 10.2], 0)© can be satisfied by first flattening the tuple to yield the expression ©f(5, 10.2, 0)© and then structuring the argument list to match the formal parameter list structure as ©f(5, [10.2, 0])©.
-
-\subsection{Multiple-Return-Value Functions}
-Functions can be declared to return more than one value.
-Multiple return values are packaged into a tuple value when the function returns.
-A multiple-returning function with return type ©T© can return any expression which is implicitly convertible to ©T©.
-
-\subsection{Tuple Assignment}
-An assignment where the left side of the assignment operator has a tuple type is called tuple assignment.
-There are two kinds of tuple assignment depending on whether the right side of the assignment operator has a tuple type or a non-tuple type, called Multiple Assignment and Mass Assignment respectively.
-Let $L_i$ for $i$ in $[0, n)$ represent each component of the flattened left side, $R_i$ represent each component of the flattened right side of a multiple assignment, and $R$ represent the right side of a mass assignment.
-
-For a multiple assignment to be valid, both tuples must have the same number of elements when flattened. Multiple assignment assigns $R_i$ to $L_i$ for each $i$.
-That is, ©?=?(&$L_i$, $R_i$)© must be a well-typed expression.
-
-Mass assignment assigns the value $R$ to each $L_i$. For a mass assignment to be valid, ©?=?(&$L_i$, $R$)© must be a well-typed expression.
-This differs from C cascading assignment (e.g. ©a=b=c©) in that conversions are applied to $R$ in each individual assignment, which prevents data loss from the chain of conversions that can happen during a cascading assignment.
-
-Both kinds of tuple assignment have parallel semantics, such that each value on the left side and right side is evaluated \emph{before} any assignments occur.
-Tuple assignment is an expression where the result type is the type of the left side of the assignment, as in normal assignment (i.e. the tuple of the types of the left side expressions) \footnote{This is a change from the original tuple design, wherein tuple assignment was a statement. This decision appears to have been made in an attempt to fix what was seen as a problem with assignment, but at the same time this doesn't seem to fit C or Cforall very well. In another language, tuple assignment as a statement could be reasonable, but I don't see a good justification for making this the only kind of assignment that isn't an expression. In this case, I would value consistency over idealism}.
-These semantics allow cascading tuple assignment to work out naturally in any context where a tuple is permitted.
-
-The following example shows multiple, mass, and cascading assignment in one expression
-\begin{lstlisting}
-  int a, b;
-  double c, d;
-  [void] f([int, int]);
-  f([c, a] = [b, d] = 1.5);
-\end{lstlisting}
-First a mass assignment of ©1.5© into ©[b, d]©, which assigns ©1.5© into ©b©, which is truncated to ©1©, and ©1© into ©d©, producing the tuple ©[1, 1.5]© as a result.
-That tuple is used as the right side of the multiple assignment (i.e. ©[c, a] = [1, 1.5]©) which assigns ©1© into ©c© and ©1.5© into ©a©, which is truncated to ©1©, producing the result ©[1, 1]©.
-Finally, the tuple ©[1, 1]© is used as an expression in the call to ©f©.
-
-\subsection{Tuple Construction}
-Tuple construction and destruction follow the same rules and semantics as tuple assignment, except that in the case where there is no right side, the default constructor or destructor is called on each component of the tuple.
-
-It is possible to define constructors and assignment functions for tuple types that provide new semantics.
-For example, the function ©void ?{}([T, U] *, S);© can be defined to allow a tuple variable to be constructed from a value of type ©S©. Due to the structure of generated constructors, it is possible to pass a tuple to a generated constructor for a type with a member prefix that matches the type of the tuple (e.g. an instance of ©struct S { int x; double y; int z }© can be constructed with a tuple of type ©[int, double]©, `out of the box').
-
-\section{Other Tuple Expressions}
-\subsection{Member Tuple Expression}
-It is possible to access multiple fields from a single expression using a Member Tuple Expression \footnote{Called ``record field tuple'' in the original design, but there's no reason to limit this feature to only structs, so ``field tuple'' or ``member tuple'' feels more appropriate.}.
-The result is a single tuple-valued expression whose type is the tuple of the types of the members.
-A member tuple expression has the form ©a.[x, y, z];© where ©a© is an expression with type ©T©, where ©T© supports member access expressions, and ©x, y, z© are all members of ©T© with types ©T$_x$©, ©T$_y$©, and ©T$_z$© respectively.
-Then the type of ©a.[x, y, z]© is ©[T$_x$, T$_y$, T$_z$]©.
-It is possible for a member tuple expression to contain other member access expressions, e.g. ©a.[x, y.[i, j], z.k]©.
-This expression is equivalent to ©[a.x, [a.y.i, a.y.j], a.z.k]©.
-It is guaranteed that the aggregate expression to the left of the ©.© on a member tuple expression is evaluated once.
-
-\subsection{Tuple Indexing}
-Sometimes it is desirable to access a single component of a tuple-valued expression without creating unnecessary temporary variables to assign to.
-Given a tuple-valued expression ©e© and a compile-time constant integer $i$ where $0 \leq i < n$, where $n$ is the number of components in ©e©, ©e.i© will access the $i$\textsuperscript{th} component of ©e©.
-% \footnote{If this syntax cannot be parsed, we can make it ©_i©, and a semantic check ensures that ©_i© has the right form. The capability to access a component of a tuple is helpful internally, and there doesn't seem to be a disadvantage to exposing it to users. On the other hand, it is more general than casting and much more explicit, while also being less verbose.}.
-It is possible to use a member tuple expression with tuple indexing to manually restructure a tuple (rearrange components, drop components, duplicate components, etc.).
-
-% TODO: mention that Tuple.member_name and Aggregate.index could have sensible semantics, but introduce complexity into the model. Agg.idx could mean get the ith member of the aggregate (further, this could be extended for enumerations as well, where the LHS is a type instead of a value), but it's not clear there is a compelling use-case. Tuple.member_name can either mean "distribute the member across the elements of the tuple" [effectively a compile-time map], or alternatively array.member_name (to mean basically the same thing). The problem with this is that it takes this expression's meaning from being clear at compile-time to needing resolver support, as the member name needs to appropriately distribute across every member of the tuple, which could itself be a tuple, etc. Again, the extra complexity is not currently justified.
-
-For example
-\begin{lstlisting}
-  [int, double] x;
-  [double, int, double] y = [x.1, x.0, x.1];  // (1)
-
-  [int, int, int] f();
-  [x.0, y.1] = f().[0, 2];                    // (2)
-\end{lstlisting}
-
-(1) ©y© is initialized using a tuple expression which selects components from the tuple variable ©x©.
-
-(2) A mass assignment of the first and third components from the return value of ©f© into the first component of ©x© and the second component of ©y©.
-
-\subsection{Casting}
-A cast to tuple type is valid when $T_n \leq S_m$, where $T_n$ is the number of components in the target type and $S_m$ is the number of components in the source type, and for each $i$ in $[0, n)$, $S_i$ can be cast to $T_i$.
-Excess elements ($S_j$ for all $j$ in $[n, m)$) are evaluated, but their values are discarded so that they are not included in the result expression.
-This naturally follows the way that a cast to void works in C.
-
-For example,
-\begin{lstlisting}
-  [int, int, int] f();
-  [int, [int, int], int] g();
-
-  ([int, double])f();           // (1)
-  ([int, int, int])g();         // (2)
-  ([void, [int, int]])g();      // (3)
-  ([int, int, int, int])g();    // (4)
-  ([int, [int, int, int]])g();  // (5)
-\end{lstlisting}
-
-(1) discards the last element of the return value and converts the second element to type double.
-
-(2) discards the second component of the second element of the return value of ©g© (if ©g© is free of side effects, this is equivalent to ©[(int)(g().0), (int)(g().1.0), (int)(g().2)]©).
-
-(3) discards the first and third return values (equivalent to ©[(int)(g().1.0), (int)(g().1.1)]©).
-
-(4) is invalid because the cast target type contains 4 components, while the source type contains only 3.
-
-(5) is invalid because the cast ©([int, int, int])(g().1)© is invalid (i.e. it is invalid to cast ©[int, int]© to ©[int, int, int]©)
-
-
-\section{Tuples for Variadic Functions}
-Functions with tuple parameters can be used to provide type-safe variadic functions.
-It appears that it would be possible to leverage tuples to get similar power to what \CC vardiadic templates provide, but with the ability to separately compile them.
-
-\subsection{Option 1: Allow type parameters to match whole tuples, rather than just their components}
-This option could be implemented with two phases of argument matching when a function contains type parameters and the argument list contains tuple arguments.
-If flattening and structuring fail to produce a match, a second attempt at matching the function and argument combination is made where tuple arguments are not expanded and structure must match exactly, modulo implicit conversions. \footnote{It may be desirable to skip the exact matching rule if flattening and structuring produce a match that fails when inferring assertion parameters, at least in the current resolver since our assertion inference appears to be very inefficient.}
-
-For example:
-\begin{lstlisting}
-  forall(otype T, otype U | { T g(U); })
-  void f(T, U);
-
-  [int, int] g([int, int, int, int]);
-
-  f([1, 2], [3, 4, 5, 6]);
-\end{lstlisting}
-With flattening and structuring, the call is first transformed into ©f(1, 2, 3, 4, 5, 6)©.
-Since the first argument of type ©T© does not have a tuple type, unification decides that ©T=int© and ©1© is matched as the first parameter.
-Likewise, ©U© does not have a tuple type, so ©U=int© and ©2© is accepted as the second parameter.
-There are now no remaining formal parameters, there are remaining arguments, and the function is not variadic, so the match fails.
-
-With exact matching, ©T=[int,int]© and ©U=[int,int,int,int]© and so the arguments type check.
-When inferring assertion ©g©, a match is found.
-\footnote{This type of interaction between tuple arguments and type parameters is desirable for perfect forwarding, but it's not obvious to me exactly how this should interact with assertion inference. Ideally, the same rules should apply for assertion satisfaction as apply to argument matching (i.e. flattening \& structuring should be attempted, followed by an exact match attempt on failure), but this may be more complicated than it sounds for assertion satisfaction. Aaron, I'm especially interested to hear your thoughts on this with respect to efficiency in the resolver redesign.
-
-For example, should we allow this to match?
-\begin{lstlisting}
-  forall(otype T, otype U | { T g(U); })
-  void f(T, U);
-
-  [int, int] g(int, ®[int, int]®, int);
-
-  f([1, 2], [3, 4, 5, 6]);
-\end{lstlisting}
-To only have an exact matching rule here feels too strict. At the very least, it would be nice to accept ©[int, int] g(int, int, int, int)©, since that would allow for argument lists to be packaged and sent off to polymorphic functions and then directly forwarded to other functions.}.
-
-The addition of an exact matching rule only affects the outcome for polymorphic type binding when tuples are involved.
-For non-tuple arguments, exact matching and flattening \& structuring are equivalent. For tuple arguments to a function without polymorphic formal parameters, flattening and structuring work whenever an exact match would have worked (the tuple is flattened and implicitly restructured to its original structure).
-Thus there is nothing to be gained from permitting the exact matching rule to take effect when a function does not contain polymorphism and none of the arguments are tuples.
-
-\subsection{Option 2: Add another type parameter kind}
-Perhaps a simpler alternative would be to add another kind of type parameter (e.g., ©ttype©).
-There should be at most one ©ttype© parameter which must occur last in a parameter list.
-Matching against a ©ttype© parameter would consume/package all remaining argument components into a tuple, and would also match no arguments.
-These semantics more closely match normal variadic semantics, while being type-safe. C variadic syntax and ©ttype© polymorphism probably should not be mixed, since it is not clear where to draw the line to decide which arguments belong where.\footnote{In fact, if we go with this proposal, it might be desirable to disallow polymorphic functions to use C variadic syntax to encourage a Cforall style. Aside from maybe calling C variadic functions, it's not obvious to me there would be anything you can do with C variadics that couldn't also be done with ©ttype© parameters. }
-
-Example 1: taken from Wikipedia, demonstrates variadic templates done in a Cforall style
-\begin{lstlisting}
-  void func(void) {}                           // termination version (1)
-  forall(otype T, ttype Params | { void process(const T &); void func(const Params &); })
-  void func(const T& arg1, const Params & p) { // (2)
-    process(arg1);
-    func(p);
-  }
-  void process(int);                           // (3)
-  void process(double);                        // (4)
-  func(1, 2.0, 3.5, 4);
-\end{lstlisting}
-In the call to ©func©, the value ©1© is taken as the first parameter, so ©T© unifies with ©int©, and the arguments ©2.0©, ©3.5©, and ©4© are consumed to form a tuple argument of type ©[double, double, int]©.
-To satisfy the assertions to ©func©, the functions (3) and (2) are implicitly selected to satisfy the requirements of ©void process(const T &)© and ©void func(const Params &)© respectively.
-Since (2) requires assertion parameters, the process repeats selecting (4) and (2).
-The matching process continues recursively until reaching the base case where (3) and (1) are selected.
-The end result is semantically equivalent to ©process(1), process(2.0), process(3.5), process(4)©.
-
-Since (2) is not an exact match for the expected assertion parameter, a thunk is generated that wraps a call to ©func© that accepts an argument of type ©[double, double, int]©.
-This conversion already occurs in the Cforall translator, but may require some modification to handle all of the cases present here.
-
-Example 2: new (i.e. type-safe malloc + constructors)
-\begin{lstlisting}
-  forall(dtype T, ttype Params | sized(T) | { void ?{}(T *, Params); })
-  T * new(Params p) {
-    return malloc(){ p };
-  }
-  array(int) * x = new(1, 2, 3, 4);
-\end{lstlisting}
-In the call to ©new©, ©array(int)© is selected to match ©T©, and ©Params© is expanded ot match ©[int, int, int, int]©. To satisfy the assertions, a constructor with an interface compatible with ©void ?{}(array(int) *, int, int, int, int)© must exist in the current scope.
-
-Assertion inference can also be special cased to match functions that take tuples of any structure only for ttype parameters, if desired.
-
-
-\subsection{Conclusions}
-With either option, we can generate a thunk to perform the conversion from the actual argument's structure to the structure expected by the assertion parameter and that function would be passed as the assertion argument, in a manner similar to the other thunks that are already generated.
-
-I prefer option 2, because it is simpler and I think the semantics are clearer.
-I wouldn't be surprised if it was also noticeably more efficient, because of the lack of backtracking.
-
-As a side note, option 1 also requires calls to be written explicitly, e.g. ©array(int) * x = new([1, 2, 3, 4]);©, which isn't particularly appealing.
-It shifts the burden from the compiler to the programmer, which is almost always wrong, and doesn't match with the way our tuples can be used elsewhere.
-The more I think about it, the more I'm convinced option 1 is the wrong approach, but I'm putting it out anyway in case someone has a good thought on how to make it work correctly.
-
-\addcontentsline{toc}{section}{\refname}
-\bibliographystyle{plain}
-\bibliography{pl}
-
-%\addcontentsline{toc}{section}{\indexname} % add index name to table of contents
-%\begin{theindex}
-%Italic page numbers give the location of the main entry for the referenced term.
-%Plain page numbers denote uses of the indexed term.
-%Entries for grammar non-terminals are italicized.
-%A typewriter font is used for grammar terminals and program identifiers.
-%\indexspace
-%\input{comp_II.ind}
-%\end{theindex}
-
-\end{document}
Index: doc/theses/rob_schluntz_MMath/tuples/Makefile
===================================================================
--- doc/theses/rob_schluntz_MMath/tuples/Makefile	(revision 86841ee36bf28dbbcead51789e9e5ffb8e8843a8)
+++ doc/theses/rob_schluntz_MMath/tuples/Makefile	(revision 86841ee36bf28dbbcead51789e9e5ffb8e8843a8)
@@ -0,0 +1,94 @@
+# Makefile for the original tuple proposal (mantained for history's sake).
+
+## Define the configuration variables.
+
+Build = build
+Figures = figures
+Macros = ../../LaTeXmacros
+Bib = ../../bibliography
+
+TeXLIB = .:${Macros}:${MACROS}/listings:${MACROS}/enumitem:${Bib}/:
+LaTeX  = TEXINPUTS=${TeXLIB} && export TEXINPUTS && latex -halt-on-error -output-directory=${Build}
+BibTeX = BIBINPUTS=${TeXLIB} && export BIBINPUTS && bibtex
+
+MAKEFLAGS = --no-print-directory --silent #
+VPATH = ${Build} ${Figures}
+
+## Define the text source files.
+
+SOURCES = ${addsuffix .tex, \
+tuples \
+}
+
+FIGURES = ${addsuffix .tex, \
+}
+
+PICTURES = ${addsuffix .pstex, \
+}
+
+PROGRAMS = ${addsuffix .tex, \
+}
+
+GRAPHS = ${addsuffix .tex, \
+}
+
+## Define the documents that need to be made.
+
+DOCUMENT = tuples.pdf
+BASE = ${basename ${DOCUMENT}}
+
+# Directives #
+
+.PHONY : all clean					# not file names
+
+all : ${DOCUMENT}
+
+clean :
+	@rm -frv ${DOCUMENT} ${BASE}.ps ${Build}
+
+# File Dependencies #
+
+${DOCUMENT} : ${BASE}.ps
+	ps2pdf $<
+
+${BASE}.ps : ${BASE}.dvi
+	dvips ${Build}/$< -o $@
+
+${BASE}.dvi : Makefile ${GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} \
+		${Macros}/common.tex ${Macros}/indexstyle ${Bib}/pl.bib | ${Build}
+	# Conditionally create an empty *.ind (index) file for inclusion until makeindex is run.
+	#if [ ! -r ${basename $@}.ind ] ; then touch ${Build}/${basename $@}.ind ; fi
+	# Must have *.aux file containing citations for bibtex
+	if [ ! -r ${basename $@}.aux ] ; then ${LaTeX} ${basename $@}.tex ; fi
+	-${BibTeX} ${Build}/${basename $@}
+	# Some citations reference others so run again to resolve these citations
+	${LaTeX} ${basename $@}.tex
+	-${BibTeX} ${Build}/${basename $@}
+	# Make index from *.aux entries and input index at end of document
+	#makeindex -s ${Macros}/indexstyle ${Build}/${basename $@}.idx
+	# Run again to finish citations
+	${LaTeX} ${basename $@}.tex
+	# Run again to get index title into table of contents
+	${LaTeX} ${basename $@}.tex
+
+predefined :
+	sed -f predefined.sed ${basename ${DOCUMENT}}.tex > ${basename $@}.cf
+
+## Define the default recipes.
+
+${Build}:
+	mkdir -p ${Build}
+
+%.tex : %.fig | ${Build}
+	fig2dev -L eepic $< > ${Build}/$@
+
+%.ps : %.fig | ${Build}
+	fig2dev -L ps $< > ${Build}/$@
+
+%.pstex : %.fig | ${Build}
+	fig2dev -L pstex $< > ${Build}/$@
+	fig2dev -L pstex_t -p ${Build}/$@ $< > ${Build}/$@_t
+
+# Local Variables: #
+# compile-command: "make" #
+# End: #
Index: doc/theses/rob_schluntz_MMath/tuples/tuples.tex
===================================================================
--- doc/theses/rob_schluntz_MMath/tuples/tuples.tex	(revision 86841ee36bf28dbbcead51789e9e5ffb8e8843a8)
+++ doc/theses/rob_schluntz_MMath/tuples/tuples.tex	(revision 86841ee36bf28dbbcead51789e9e5ffb8e8843a8)
@@ -0,0 +1,339 @@
+\documentclass[twoside,11pt]{article}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% Latex packages used in the document (copied from CFA user manual).
+\usepackage[T1]{fontenc}                                % allow Latin1 (extended ASCII) characters
+\usepackage{textcomp}
+\usepackage[latin1]{inputenc}
+
+\usepackage{fullpage,times,comment}
+\usepackage{epic,eepic}
+\usepackage{upquote}					% switch curled `'" to straight
+\usepackage{calc}
+\usepackage{xspace}
+\usepackage{graphicx}
+\usepackage{varioref}					% extended references
+\usepackage{listings}					% format program code
+\usepackage[flushmargin]{footmisc}			% support label/reference in footnote
+\usepackage{latexsym}                                   % \Box glyph
+\usepackage{mathptmx}                                   % better math font with "times"
+\usepackage[usenames]{color}
+\usepackage[pagewise]{lineno}
+\renewcommand{\linenumberfont}{\scriptsize\sffamily}
+\input{common}                                          % bespoke macros used in the document
+\usepackage[dvips,plainpages=false,pdfpagelabels,pdfpagemode=UseNone,colorlinks=true,pagebackref=true,linkcolor=blue,citecolor=blue,urlcolor=blue,pagebackref=true,breaklinks=true]{hyperref}
+\usepackage{breakurl}
+\renewcommand{\UrlFont}{\small\sf}
+
+\setlength{\topmargin}{-0.45in}				% move running title into header
+\setlength{\headsep}{0.25in}
+
+\usepackage{caption}
+\usepackage{subcaption}
+\usepackage{bigfoot}
+
+\interfootnotelinepenalty=10000
+
+\CFAStyle						% use default CFA format-style
+% inline code ©...© (copyright symbol) emacs: C-q M-)
+% red highlighting ®...® (registered trademark symbol) emacs: C-q M-.
+% blue highlighting ß...ß (sharp s symbol) emacs: C-q M-_
+% green highlighting ¢...¢ (cent symbol) emacs: C-q M-"
+% LaTex escape §...§ (section symbol) emacs: C-q M-'
+% keyword escape ¶...¶ (pilcrow symbol) emacs: C-q M-^
+% math escape $...$ (dollar symbol)
+
+
+\title{
+\Huge \vspace*{1in} Tuple Design in \CFA \\
+\vspace*{1in}
+}
+
+\author{
+\huge Rob Schluntz \\
+\Large \vspace*{0.1in} \texttt{rschlunt@uwaterloo.ca} \\
+\Large Cheriton School of Computer Science \\
+\Large University of Waterloo
+}
+
+\date{
+\today
+}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\newcommand{\bigO}[1]{O\!\left( #1 \right)}
+
+\begin{document}
+\pagestyle{headings}
+% changed after setting pagestyle
+\renewcommand{\sectionmark}[1]{\markboth{\thesection\quad #1}{\thesection\quad #1}}
+\renewcommand{\subsectionmark}[1]{\markboth{\thesubsection\quad #1}{\thesubsection\quad #1}}
+\pagenumbering{roman}
+% \linenumbers                                            % comment out to turn off line numbering
+
+\maketitle
+\thispagestyle{empty}
+
+\clearpage
+\thispagestyle{plain}
+\pdfbookmark[1]{Contents}{section}
+\tableofcontents
+
+\clearpage
+\thispagestyle{plain}
+\pagenumbering{arabic}
+
+
+\section{Introduction}
+This document describes my understanding of the existing tuple design~\cite{Buhr94a,Till89}, mixed with my thoughts on improvements after various discussions with Peter, Aaron, and Thierry.
+
+\section{Tuple Expressions}
+A tuple expression is an expression which produces a fixed-size, ordered list of values of heterogeneous types.
+The type of a tuple expression is the tuple of the subexpression types.
+In Cforall, a tuple expression is denoted by a list of expressions enclosed in square brackets.
+
+For example, the expression ©[5, 'x', 10.5]© has type ©[int, char, double]©.
+Tuples are a compile-time phenomenon and have little to no run-time presence.
+
+\subsection{Tuple Variables}
+It is possible to have variables of tuple type, pointer to tuple type, and array of tuple type.
+Tuple types can be composed of any types, except for array types \footnote{I did not see this issue mentioned at all in the original design. A tuple containing an array type seems to make sense up until you try to use a tuple containing an array type as a function parameter. At this point you lose information about the size of the array, which makes tuple assignment difficult. Rather than allowing arrays in most situations and disallowing only as function parameters, it seems like it would be better to be consistent across the board.}.
+
+\begin{lstlisting}
+[double, int] di;
+[double, int] * pdi
+[double, int] adi[10];
+\end{lstlisting}
+The program above declares a variable of type ©[double, int]©, a variable of type pointer to ©[double, int]©, and an array of ten ©[double, int]©.
+
+\subsection{Flattening and Structuring}
+In Cforall, tuples do not have a rigid structure.
+In function call contexts, tuples support implicit flattening and restructuring \footnote{In the original tuple design, four tuple coercions were described: opening, closing, flattening, and structuring. I've combined flattening with opening and structuring with closing in my description, as the distinctions do not seem useful in Cforall since these coercions happen only as arguments to function calls, and I believe all of the semantics are properly covered by the simplified descriptions.}. Tuple flattening recursively expands a tuple into the list of its basic components. Tuple structuring packages a list of expressions into a value of tuple type.
+
+\begin{lstlisting}
+int f(int, int);
+int g([int, int]);
+int h(int, [int, int]);
+[int, int] x;
+int y;
+
+f(x);
+g(y, 10);
+h(x, y);
+\end{lstlisting}
+In Cforall, each of these calls is valid.
+In the call to ©f©, ©x© is implicitly flattened so that the components of ©x© are passed as the two arguments to ©f©.
+For the call to ©g©, the values ©y© and ©10© are structured into a single argument of type ©[int, int]© to match the type of the parameter of ©g©.
+Finally, in the call to ©h©, ©y© is flattened to yield an argument list of length 3, of which the first component of ©x© is passed as the first parameter of ©h©, and the second component of ©x© and ©y© are structured into the second argument of type ©[int, int]©.
+
+\section{Functions}
+\subsection{Argument Passing}
+In resolving a function call, all of the arguments to the call are flattened.
+While determining if a particular function/argument-list combination is valid, the arguments are structured to match the shape of each formal parameter, in order.
+
+For example, given a function declaration ©[int] f(int, [double, int])©, the call ©f([5, 10.2], 0)© can be satisfied by first flattening the tuple to yield the expression ©f(5, 10.2, 0)© and then structuring the argument list to match the formal parameter list structure as ©f(5, [10.2, 0])©.
+
+\subsection{Multiple-Return-Value Functions}
+Functions can be declared to return more than one value.
+Multiple return values are packaged into a tuple value when the function returns.
+A multiple-returning function with return type ©T© can return any expression which is implicitly convertible to ©T©.
+
+\subsection{Tuple Assignment}
+An assignment where the left side of the assignment operator has a tuple type is called tuple assignment.
+There are two kinds of tuple assignment depending on whether the right side of the assignment operator has a tuple type or a non-tuple type, called Multiple Assignment and Mass Assignment respectively.
+Let $L_i$ for $i$ in $[0, n)$ represent each component of the flattened left side, $R_i$ represent each component of the flattened right side of a multiple assignment, and $R$ represent the right side of a mass assignment.
+
+For a multiple assignment to be valid, both tuples must have the same number of elements when flattened. Multiple assignment assigns $R_i$ to $L_i$ for each $i$.
+That is, ©?=?(&$L_i$, $R_i$)© must be a well-typed expression.
+
+Mass assignment assigns the value $R$ to each $L_i$. For a mass assignment to be valid, ©?=?(&$L_i$, $R$)© must be a well-typed expression.
+This differs from C cascading assignment (e.g. ©a=b=c©) in that conversions are applied to $R$ in each individual assignment, which prevents data loss from the chain of conversions that can happen during a cascading assignment.
+
+Both kinds of tuple assignment have parallel semantics, such that each value on the left side and right side is evaluated \emph{before} any assignments occur.
+Tuple assignment is an expression where the result type is the type of the left side of the assignment, as in normal assignment (i.e. the tuple of the types of the left side expressions) \footnote{This is a change from the original tuple design, wherein tuple assignment was a statement. This decision appears to have been made in an attempt to fix what was seen as a problem with assignment, but at the same time this doesn't seem to fit C or Cforall very well. In another language, tuple assignment as a statement could be reasonable, but I don't see a good justification for making this the only kind of assignment that isn't an expression. In this case, I would value consistency over idealism}.
+These semantics allow cascading tuple assignment to work out naturally in any context where a tuple is permitted.
+
+The following example shows multiple, mass, and cascading assignment in one expression
+\begin{lstlisting}
+  int a, b;
+  double c, d;
+  [void] f([int, int]);
+  f([c, a] = [b, d] = 1.5);
+\end{lstlisting}
+First a mass assignment of ©1.5© into ©[b, d]©, which assigns ©1.5© into ©b©, which is truncated to ©1©, and ©1© into ©d©, producing the tuple ©[1, 1.5]© as a result.
+That tuple is used as the right side of the multiple assignment (i.e. ©[c, a] = [1, 1.5]©) which assigns ©1© into ©c© and ©1.5© into ©a©, which is truncated to ©1©, producing the result ©[1, 1]©.
+Finally, the tuple ©[1, 1]© is used as an expression in the call to ©f©.
+
+\subsection{Tuple Construction}
+Tuple construction and destruction follow the same rules and semantics as tuple assignment, except that in the case where there is no right side, the default constructor or destructor is called on each component of the tuple.
+
+It is possible to define constructors and assignment functions for tuple types that provide new semantics.
+For example, the function ©void ?{}([T, U] *, S);© can be defined to allow a tuple variable to be constructed from a value of type ©S©. Due to the structure of generated constructors, it is possible to pass a tuple to a generated constructor for a type with a member prefix that matches the type of the tuple (e.g. an instance of ©struct S { int x; double y; int z }© can be constructed with a tuple of type ©[int, double]©, `out of the box').
+
+\section{Other Tuple Expressions}
+\subsection{Member Tuple Expression}
+It is possible to access multiple fields from a single expression using a Member Tuple Expression \footnote{Called ``record field tuple'' in the original design, but there's no reason to limit this feature to only structs, so ``field tuple'' or ``member tuple'' feels more appropriate.}.
+The result is a single tuple-valued expression whose type is the tuple of the types of the members.
+A member tuple expression has the form ©a.[x, y, z];© where ©a© is an expression with type ©T©, where ©T© supports member access expressions, and ©x, y, z© are all members of ©T© with types ©T$_x$©, ©T$_y$©, and ©T$_z$© respectively.
+Then the type of ©a.[x, y, z]© is ©[T$_x$, T$_y$, T$_z$]©.
+It is possible for a member tuple expression to contain other member access expressions, e.g. ©a.[x, y.[i, j], z.k]©.
+This expression is equivalent to ©[a.x, [a.y.i, a.y.j], a.z.k]©.
+It is guaranteed that the aggregate expression to the left of the ©.© on a member tuple expression is evaluated once.
+
+\subsection{Tuple Indexing}
+Sometimes it is desirable to access a single component of a tuple-valued expression without creating unnecessary temporary variables to assign to.
+Given a tuple-valued expression ©e© and a compile-time constant integer $i$ where $0 \leq i < n$, where $n$ is the number of components in ©e©, ©e.i© will access the $i$\textsuperscript{th} component of ©e©.
+% \footnote{If this syntax cannot be parsed, we can make it ©_i©, and a semantic check ensures that ©_i© has the right form. The capability to access a component of a tuple is helpful internally, and there doesn't seem to be a disadvantage to exposing it to users. On the other hand, it is more general than casting and much more explicit, while also being less verbose.}.
+It is possible to use a member tuple expression with tuple indexing to manually restructure a tuple (rearrange components, drop components, duplicate components, etc.).
+
+% TODO: mention that Tuple.member_name and Aggregate.index could have sensible semantics, but introduce complexity into the model. Agg.idx could mean get the ith member of the aggregate (further, this could be extended for enumerations as well, where the LHS is a type instead of a value), but it's not clear there is a compelling use-case. Tuple.member_name can either mean "distribute the member across the elements of the tuple" [effectively a compile-time map], or alternatively array.member_name (to mean basically the same thing). The problem with this is that it takes this expression's meaning from being clear at compile-time to needing resolver support, as the member name needs to appropriately distribute across every member of the tuple, which could itself be a tuple, etc. Again, the extra complexity is not currently justified.
+
+For example
+\begin{lstlisting}
+  [int, double] x;
+  [double, int, double] y = [x.1, x.0, x.1];  // (1)
+
+  [int, int, int] f();
+  [x.0, y.1] = f().[0, 2];                    // (2)
+\end{lstlisting}
+
+(1) ©y© is initialized using a tuple expression which selects components from the tuple variable ©x©.
+
+(2) A mass assignment of the first and third components from the return value of ©f© into the first component of ©x© and the second component of ©y©.
+
+\subsection{Casting}
+A cast to tuple type is valid when $T_n \leq S_m$, where $T_n$ is the number of components in the target type and $S_m$ is the number of components in the source type, and for each $i$ in $[0, n)$, $S_i$ can be cast to $T_i$.
+Excess elements ($S_j$ for all $j$ in $[n, m)$) are evaluated, but their values are discarded so that they are not included in the result expression.
+This naturally follows the way that a cast to void works in C.
+
+For example,
+\begin{lstlisting}
+  [int, int, int] f();
+  [int, [int, int], int] g();
+
+  ([int, double])f();           // (1)
+  ([int, int, int])g();         // (2)
+  ([void, [int, int]])g();      // (3)
+  ([int, int, int, int])g();    // (4)
+  ([int, [int, int, int]])g();  // (5)
+\end{lstlisting}
+
+(1) discards the last element of the return value and converts the second element to type double.
+
+(2) discards the second component of the second element of the return value of ©g© (if ©g© is free of side effects, this is equivalent to ©[(int)(g().0), (int)(g().1.0), (int)(g().2)]©).
+
+(3) discards the first and third return values (equivalent to ©[(int)(g().1.0), (int)(g().1.1)]©).
+
+(4) is invalid because the cast target type contains 4 components, while the source type contains only 3.
+
+(5) is invalid because the cast ©([int, int, int])(g().1)© is invalid (i.e. it is invalid to cast ©[int, int]© to ©[int, int, int]©)
+
+
+\section{Tuples for Variadic Functions}
+Functions with tuple parameters can be used to provide type-safe variadic functions.
+It appears that it would be possible to leverage tuples to get similar power to what \CC vardiadic templates provide, but with the ability to separately compile them.
+
+\subsection{Option 1: Allow type parameters to match whole tuples, rather than just their components}
+This option could be implemented with two phases of argument matching when a function contains type parameters and the argument list contains tuple arguments.
+If flattening and structuring fail to produce a match, a second attempt at matching the function and argument combination is made where tuple arguments are not expanded and structure must match exactly, modulo implicit conversions. \footnote{It may be desirable to skip the exact matching rule if flattening and structuring produce a match that fails when inferring assertion parameters, at least in the current resolver since our assertion inference appears to be very inefficient.}
+
+For example:
+\begin{lstlisting}
+  forall(otype T, otype U | { T g(U); })
+  void f(T, U);
+
+  [int, int] g([int, int, int, int]);
+
+  f([1, 2], [3, 4, 5, 6]);
+\end{lstlisting}
+With flattening and structuring, the call is first transformed into ©f(1, 2, 3, 4, 5, 6)©.
+Since the first argument of type ©T© does not have a tuple type, unification decides that ©T=int© and ©1© is matched as the first parameter.
+Likewise, ©U© does not have a tuple type, so ©U=int© and ©2© is accepted as the second parameter.
+There are now no remaining formal parameters, there are remaining arguments, and the function is not variadic, so the match fails.
+
+With exact matching, ©T=[int,int]© and ©U=[int,int,int,int]© and so the arguments type check.
+When inferring assertion ©g©, a match is found.
+\footnote{This type of interaction between tuple arguments and type parameters is desirable for perfect forwarding, but it's not obvious to me exactly how this should interact with assertion inference. Ideally, the same rules should apply for assertion satisfaction as apply to argument matching (i.e. flattening \& structuring should be attempted, followed by an exact match attempt on failure), but this may be more complicated than it sounds for assertion satisfaction. Aaron, I'm especially interested to hear your thoughts on this with respect to efficiency in the resolver redesign.
+
+For example, should we allow this to match?
+\begin{lstlisting}
+  forall(otype T, otype U | { T g(U); })
+  void f(T, U);
+
+  [int, int] g(int, ®[int, int]®, int);
+
+  f([1, 2], [3, 4, 5, 6]);
+\end{lstlisting}
+To only have an exact matching rule here feels too strict. At the very least, it would be nice to accept ©[int, int] g(int, int, int, int)©, since that would allow for argument lists to be packaged and sent off to polymorphic functions and then directly forwarded to other functions.}.
+
+The addition of an exact matching rule only affects the outcome for polymorphic type binding when tuples are involved.
+For non-tuple arguments, exact matching and flattening \& structuring are equivalent. For tuple arguments to a function without polymorphic formal parameters, flattening and structuring work whenever an exact match would have worked (the tuple is flattened and implicitly restructured to its original structure).
+Thus there is nothing to be gained from permitting the exact matching rule to take effect when a function does not contain polymorphism and none of the arguments are tuples.
+
+\subsection{Option 2: Add another type parameter kind}
+Perhaps a simpler alternative would be to add another kind of type parameter (e.g., ©ttype©).
+There should be at most one ©ttype© parameter which must occur last in a parameter list.
+Matching against a ©ttype© parameter would consume/package all remaining argument components into a tuple, and would also match no arguments.
+These semantics more closely match normal variadic semantics, while being type-safe. C variadic syntax and ©ttype© polymorphism probably should not be mixed, since it is not clear where to draw the line to decide which arguments belong where.\footnote{In fact, if we go with this proposal, it might be desirable to disallow polymorphic functions to use C variadic syntax to encourage a Cforall style. Aside from maybe calling C variadic functions, it's not obvious to me there would be anything you can do with C variadics that couldn't also be done with ©ttype© parameters. }
+
+Example 1: taken from Wikipedia, demonstrates variadic templates done in a Cforall style
+\begin{lstlisting}
+  void func(void) {}                           // termination version (1)
+  forall(otype T, ttype Params | { void process(const T &); void func(const Params &); })
+  void func(const T& arg1, const Params & p) { // (2)
+    process(arg1);
+    func(p);
+  }
+  void process(int);                           // (3)
+  void process(double);                        // (4)
+  func(1, 2.0, 3.5, 4);
+\end{lstlisting}
+In the call to ©func©, the value ©1© is taken as the first parameter, so ©T© unifies with ©int©, and the arguments ©2.0©, ©3.5©, and ©4© are consumed to form a tuple argument of type ©[double, double, int]©.
+To satisfy the assertions to ©func©, the functions (3) and (2) are implicitly selected to satisfy the requirements of ©void process(const T &)© and ©void func(const Params &)© respectively.
+Since (2) requires assertion parameters, the process repeats selecting (4) and (2).
+The matching process continues recursively until reaching the base case where (3) and (1) are selected.
+The end result is semantically equivalent to ©process(1), process(2.0), process(3.5), process(4)©.
+
+Since (2) is not an exact match for the expected assertion parameter, a thunk is generated that wraps a call to ©func© that accepts an argument of type ©[double, double, int]©.
+This conversion already occurs in the Cforall translator, but may require some modification to handle all of the cases present here.
+
+Example 2: new (i.e. type-safe malloc + constructors)
+\begin{lstlisting}
+  forall(dtype T, ttype Params | sized(T) | { void ?{}(T *, Params); })
+  T * new(Params p) {
+    return malloc(){ p };
+  }
+  array(int) * x = new(1, 2, 3, 4);
+\end{lstlisting}
+In the call to ©new©, ©array(int)© is selected to match ©T©, and ©Params© is expanded ot match ©[int, int, int, int]©. To satisfy the assertions, a constructor with an interface compatible with ©void ?{}(array(int) *, int, int, int, int)© must exist in the current scope.
+
+Assertion inference can also be special cased to match functions that take tuples of any structure only for ttype parameters, if desired.
+
+
+\subsection{Conclusions}
+With either option, we can generate a thunk to perform the conversion from the actual argument's structure to the structure expected by the assertion parameter and that function would be passed as the assertion argument, in a manner similar to the other thunks that are already generated.
+
+I prefer option 2, because it is simpler and I think the semantics are clearer.
+I wouldn't be surprised if it was also noticeably more efficient, because of the lack of backtracking.
+
+As a side note, option 1 also requires calls to be written explicitly, e.g. ©array(int) * x = new([1, 2, 3, 4]);©, which isn't particularly appealing.
+It shifts the burden from the compiler to the programmer, which is almost always wrong, and doesn't match with the way our tuples can be used elsewhere.
+The more I think about it, the more I'm convinced option 1 is the wrong approach, but I'm putting it out anyway in case someone has a good thought on how to make it work correctly.
+
+\addcontentsline{toc}{section}{\refname}
+\bibliographystyle{plain}
+\bibliography{pl}
+
+%\addcontentsline{toc}{section}{\indexname} % add index name to table of contents
+%\begin{theindex}
+%Italic page numbers give the location of the main entry for the referenced term.
+%Plain page numbers denote uses of the indexed term.
+%Entries for grammar non-terminals are italicized.
+%A typewriter font is used for grammar terminals and program identifiers.
+%\indexspace
+%\input{comp_II.ind}
+%\end{theindex}
+
+\end{document}
Index: src/AST/Decl.hpp
===================================================================
--- src/AST/Decl.hpp	(revision c82dad4e91592787d98be7b164b82f68e16bb70d)
+++ src/AST/Decl.hpp	(revision 86841ee36bf28dbbcead51789e9e5ffb8e8843a8)
@@ -119,5 +119,5 @@
 enum ArgumentFlag { FixedArgs, VariableArgs };
 
-/// Object declaration `int foo()`
+/// Function declaration `int foo()`
 class FunctionDecl final : public DeclWithType {
 public:
Index: src/AST/Stmt.hpp
===================================================================
--- src/AST/Stmt.hpp	(revision c82dad4e91592787d98be7b164b82f68e16bb70d)
+++ src/AST/Stmt.hpp	(revision 86841ee36bf28dbbcead51789e9e5ffb8e8843a8)
@@ -269,5 +269,6 @@
 
 	ForeachStmt( const CodeLocation & loc, const std::vector<ptr<Stmt>> && inits,
-			const Expr * range_over, RangeDirection isInc, const Stmt * body, const Stmt * else_ )
+			const Expr * range_over, RangeDirection isInc, const Stmt * body,
+			const Stmt * else_, const std::vector<Label> && labels = {} )
 		: Stmt(loc, std::move(labels)), inits(std::move(inits)), range(range_over),
 		body(body), else_(else_), isIncreasing(isInc) {}
Index: src/Parser/TypedefTable.cpp
===================================================================
--- src/Parser/TypedefTable.cpp	(revision c82dad4e91592787d98be7b164b82f68e16bb70d)
+++ src/Parser/TypedefTable.cpp	(revision 86841ee36bf28dbbcead51789e9e5ffb8e8843a8)
@@ -25,5 +25,5 @@
 #include "ExpressionNode.hpp"							// for LabelNode
 #include "ParserTypes.hpp"								// for Token
-#include "StatementNode.hpp"							// for CondCtl, ForCtrl
+#include "StatementNode.hpp"							// for CondCtrl, ForCtrl
 // This (generated) header must come late as it is missing includes.
 #include "parser.hh"									// for IDENTIFIER, TYPEDEFname, TYPEGENname
