"""A _tuple_ is a typed linked list. Each instance of `Tuple` represents the value and type of a single link. The attributes `first` and `rest` allow us to retrieve a value form the list without losing its static type information. value point = Tuple(0.0, Tuple(0.0, Tuple("origin"))); Float x = point.first; Float y = point.rest.first; String label = point.rest.rest.first; Usually, we abbreviate code involving tuples. [Float,Float,String] point = [0.0, 0.0, "origin"]; Float x = point[0]; Float y = point[1]; String label = point[2]; A list of types enclosed in brackets is an abbreviated tuple type. An instance of `Tuple` may be constructed by surrounding a value list in brackets: [String,String] words = ["hello", "world"]; The index operator with a literal integer argument is a shortcut for a chain of evaluations of `rest` and `first`. For example, `point[1]` means `point.rest.first`. A _terminated_ tuple type is a tuple where the type of the last link in the chain is `Empty`. An _unterminated_ tuple type is a tuple where the type of the last link in the chain is `Sequence` or `Sequential`. Thus, a terminated tuple type has a length that is known statically. For an unterminated tuple type only a lower bound on its length is known statically. Here, `point` is an unterminated tuple: String[] labels = ... ; [Float,Float,String*] point = [0.0, 0.0, *labels]; Float x = point[0]; Float y = point[1]; String? firstLabel = point[2]; String[] allLabels = point[2...];""" by ("Gavin") shared final class Tuple<out Element, out First, out Rest=[]> (first, rest) extends Object() satisfies [Element+] & Cloneable<Tuple<Element,First,Rest>> given First satisfies Element given Rest satisfies Element[] { "The first element of this tuple." shared actual First first; "A tuple with the elements of this tuple, except for the first element." shared actual Rest rest; size => 1 + rest.size; shared actual Element? get(Integer index) { switch (index<=>0) case (smaller) { return null; } case (equal) { return first; } case (larger) { return rest[index-1]; } } shared actual Integer lastIndex { if (exists restLastIndex = rest.lastIndex) { return restLastIndex+1; } else { return 0; } } shared actual Element last { if (nonempty rest) { return rest.last; } else { return first; } } shared actual Element[] segment(Integer from, Integer length) { if(length <= 0){ return []; } Integer realFrom = from < 0 then 0 else from; if (realFrom==0) { return length==1 then [first] else rest[0:length+realFrom-1] .withLeading(first); } return rest[realFrom-1:length]; } shared actual Element[] span(Integer from, Integer end) { if (from<0 && end<0) { return []; } Integer realFrom = from < 0 then 0 else from; Integer realEnd = end < 0 then 0 else end; return realFrom<=realEnd then this[from:realEnd-realFrom+1] else this[realEnd:realFrom-realEnd+1].reversed.sequence; } spanTo(Integer to) => to<0 then [] else span(0, to); spanFrom(Integer from) => span(from, size); clone => this; reversed => rest.reversed.withTrailing(first); shared actual Iterator<Element> iterator() { object iterator satisfies Iterator<Element> { variable Element[] current = outer; shared actual Element|Finished next() { if (nonempty c = current) { current = c.rest; return c.first; } else { return finished; } } } return iterator; } shared actual Boolean contains(Object element) { if (exists first, first==element) { return true; } else { return element in rest; } } "Returns a new tuple that starts with the specified element, followed by the elements of this tuple." shared actual Tuple<Element|Other,Other,Tuple<Element,First,Rest>> withLeading<Other>( "The first element of the resulting tuple." Other element) => Tuple(element, this); }