Previous section: Functions for Collections

Dylan reference manual -- Functions for Sequences

## Functions for Sequences

Dylan provides default implementations for all of the functions described in this section.

The default methods for add, add-new, remove, choose, choose-by, intersection, union, remove-duplicates, copy-sequence, concatenate, reverse, and sort all return new sequences that are instances of the class-for-copy of the primary sequence argument. However, more specialized methods are permitted to choose a more appropriate result class; for example, copy-sequence of a range returns another range, even though the class-for-copy value of a range is the <list> class.

```size-settern stretchy-sequence  => n	[Generic Function]
```
Sets the size of stretchy-sequence to be n . stretchy-sequence is destructively modified.

If n is less than or equal to the original size of stretchy-sequence , then the first n elements of stretchy-sequence are retained at the same positions. If n is greater than the original size of stretchy-sequence , then the previous elements of the stretchy-sequence are retained at the same positions, and enough new elements are added to reach the new size. The value of each new element is the same as would have been used if stretchy-sequence had been created with make, specifying size: n but not fill:.

It is not specified how size-setter adds new elements to a stretchy-sequence . In particular, it is not required to call add! or any other predefined Dylan function.

```add   sequence new-element  =>  new-sequence	[Generic Function]
```
add returns a new sequence that contains new-element and all the elements of sequence. The resultant sequence's size is one greater than the size of sequence. The resultant sequence shares no structure with sequence, and sequence will be unmodified. The generic function add doesn't specify where the new element will be added, although individual methods may do so.
```? define variable numbers = #(3, 4, 5)
numbers
#(1, 3, 4, 5)
? numbers
#(3, 4, 5)
```
```add!   sequence1 new-element  =>  sequence2	[Generic Function]
```
add! returns a sequence made from sequence1 that includes new-element. The result may or may not be == to sequence1. The size of sequence2 is one greater than the size of sequence1. sequence1 may be modified as a side effect of this operation. sequence2 may share structure with sequence1.
```? define variable numbers = list (3, 4, 5)
numbers
#(1, 3, 4, 5)
```
```add-new  sequence new-element #key test  =>  new-sequence	[Generic Function]
```
If new-element is not already a member of sequence (as determined by the test function, which defaults to ==), then add-new operates just as add would. If new-element is already a member of sequence, then sequence is returned. sequence is never modified by this operation. The test function may be non-commutative: it is always called with an element from sequence as its first argument and new-element as its second argument.
```? add-new (#(3, 4, 5), 1)
#(1, 3, 4, 5)
? add-new (#(3, 4, 5), 4)
#(3, 4, 5)
```
```add-new!   sequence new-element #key test  => new-sequence	[Generic Function]
```
If new-element is not already a member of sequence (as determined by the test function, which defaults to ==), then add-new! operates just as add! would. If new-element is already a member of sequence, then sequence is returned. sequence may be modified by this operation. The test function may be non-commutative: it is always called with an element from sequence as its first argument and new-element as its second argument.
```? add-new! (list (3, 4, 5), 1)
#(1, 3, 4, 5)
? add-new! (list (3, 4, 5), 4)
#(3, 4, 5)
```
```remove   sequence value #key test count  =>  new-sequence	[Generic Function]
```
remove returns a new sequence consisting of the elements of sequence not equal to value. test, which defaults to ==, is a function which determines whether an element is equal to value. If count is specified, then no more than count copies of value are removed (so additional elements equal to value might remain). The resultant sequence must share no structure with sequence and sequence will not be modified by this operation. The test function may be non-commutative: it is always called with an element from sequence as its first argument and value as its second argument.
```? remove (#(3, 1, 4, 1, 5, 9), 1)
#(3, 4, 5, 9)
```
```remove!   sequence value #key test count  =>  new-sequence[	Generic Function]
```
remove! returns a sequence consisting of the elements of sequence which are not equal to value. test, which defaults to ==, is a function which determines whether an element is equal to value. If count is specified, then no more than count copies of value are removed (so additional elements equal to value might remain). The resultant sequence may or may not be == to sequence and may share structure with sequence. sequence may be modified by this operation. The test function may be non-commutative: it is always called with an element from sequence as its first argument and value as its second argument.
```? remove! (list (3, 1, 4, 1, 5, 9), 1)
#(3, 4, 5, 9)
```
```choose   predicate sequence  =>  new-sequence	[Generic Function]
```
choose returns a new sequence containing only those elements of sequence that satisfy predicate.
```? choose (even?, #(3, 1, 4, 1, 5, 9))
#(4)
```
```choose-by   predicate test-sequence value-sequence  	[Generic Function]
=>  new-sequence
```
choose-by returns a new sequence formed of elements from value-sequence whose corresponding elements in test-sequence satisfy predicate.
```? choose-by (even?, range (from: 1),
#("a", "b", "c", "d", "e", "f", "g", "h", "i"))
#("b", "d", "f", "h")
```
```intersection   sequence1 sequence2 #key test  	[Generic Function]
=>  new-sequence
```
intersection returns a new sequence containing only those elements of sequence1 that also appear in sequence2. test, which defaults to ==, is used to determine whether an element appears in sequence2. It is always called with an element of sequence1 as its first argument and an element from sequence2 as its second argument. The order of elements in the result sequence is not specified. The result sequence may or may not share structure with the argument sequences.
```? intersection (#("john", "paul", "george", "ringo"),
#("richard", "george", "edward", "charles"),
test: \=)
#("george")
```
```union   sequence1 sequence2 #key test  =>  new-sequence	[Generic Function]
```
union returns a sequence containing every element of sequence1 and sequence2. If the same element appears in both argument sequences, this will not cause it to appear twice in the result sequence. However, if the same element appears more than once in a single argument sequence, it may appear more than once in the result sequence. test, which defaults to ==, is used for all comparisons. It is always called with an element from sequence1 as its first argument and an element from sequence2 as its second argument. The order of elements in the result is not specified. The result sequence may or may not share structure with the argument sequences.
```? union (#("butter", "flour", "sugar", "salt", "eggs"),
#("eggs", "butter", "mushrooms", "onions", "salt"),
test: \=)
#("salt", "butter", "flour", "sugar", "eggs", "mushrooms", "onions")
```
```remove-duplicates  sequence #key test  =>  new-sequence	[Generic Function]
```
This function returns a new sequence that contains all the unique elements from sequence but no duplicate elements. The result shares no structure with sequence, and sequence will not be modified by the operation. test , which defaults to ==, is the function used to determine whether one element is a duplicate of another. The test argument may be non-commutative; it will always be called with its arguments in the same order as they appear in sequence.
```? remove-duplicates (#("spam", "eggs", "spam",
"sausage", "spam", "spam"),
test: \=)
#("spam", "eggs", "sausage")
```
```remove-duplicates!  sequence #key test  => new-sequence	[Generic Function]
```
This function returns a sequence that contains all the unique elements from sequence but no duplicate elements. The result may or may not share structure with sequence, the result may or may not be == to sequence, and sequence may or may not be modified by the operation. test , which defaults to ==, is the function used to determine whether one element is a duplicate of another. The test argument may be non-commutative; it will always be called with its arguments in the same order as they appear in sequence.
```? remove-duplicates! (#("spam", "eggs", "spam",
"sausage", "spam", "spam"),
test: \=)
#("spam", "eggs", "sausage")
```
```copy-sequence   source #key start end  =>  new-sequence 	[Generic Function]
```
copy-sequence creates a new sequence containing the elements of source between start (default 0) and end (which defaults to the size of source).
```? define constant hamlet = #("to", "be", "or", "not", "to", "be")
hamlet
? hamlet == copy-sequence (hamlet)
#f
? copy-sequence (hamlet, start: 2, end: 4)
#("or", "not")
```
```concatenate-as   class sequence1 #rest more-sequences  	 [Function]
=>  new-sequence
```
concatenate-as returns a new sequence, of class class, containing all the elements of all the sequences, in order. class must be a subclass of <mutable-sequence> and acceptable as the required argument to make. size: with a non-negative integer value must be an acceptable initarg for make of the class. The new sequence is created by calling make on the indicated class, with a size: initialization argument whose value is the sum of the sizes of the arguments.
```? concatenate-as (<string>, #('n', 'o', 'n'), #('f', 'a', 't'))
"nonfat"
```
```concatenate   sequence1 #rest sequences  =>  new-sequence	 [Function]
```
concatenate returns a new sequence containing all the elements of all the sequences, in order. new-sequence may non-destructively share structure with any of the input sequences, but it is not guaranteed to do so. concatenate returns a sequence whose value is an instance of the class-for-copy value for the first sequence. The class-for-copy value for the first sequence must be a subclass of <mutable-collection>, and it must support the init-keyword size: The new-sequence is created by calling make on the indicated class, with a size: initialization argument whose value is the sum of the sizes of the argument sequences.
```? concatenate ("low-", "calorie")
"low-calorie"
```
```replace-subsequence! sequence insert-sequence #key start end 	[Generic Function]
```
=> result-sequence

This function returns a sequence with the same elements as sequence, except that elements of the indicated subsequence are replaced by all the elements of insert-sequence. The subsequence to be overridden begins at index start and ends at index end. If start is not supplied, it defaults to 0. If end is not supplied, it defaults to size(sequence). result-sequence may or may not share structure with sequence , it may or may not be == to sequence , and sequence may or may not be modified by the operation. result-sequence will not share structure with insert-sequence. result-sequence is not destroyed.

```? define variable x = list ("a", "b", "c", "d", "e")
// unspecified
? abcde := replace-subsequence! (x, #("x", "y", "z"), end: 1))
#("x", "y", "z", "b", "c", "d", "e")
? abcde := replace-subsequence! (x, #("x", "y", "z"), start: 4))
#("x", "y", "z", "b", "x", "y", "z")
? abcde := replace-subsequence! (x, #("a", "b", "c"),
start: 2, end: 4))
#("x", "y", "a", "b", "c", "x", "y", "z")
```
```reverse   sequence  =>  new-sequence	[Generic Function]
```
reverse creates a new sequence containing the same elements as sequence, but in reverse order. The result is generally of the same class as the sequence argument.
```? define constant x = #("bim", "bam", "boom")
x
? reverse(x)
#("boom", "bam", "bim")
? x
#("bim", "bam", "boom")
```
```reverse!   sequence1  =>  sequence2	[Generic Function]
```
reverse! returns a sequence containing the same elements as sequence, but in reverse order, possibly reusing sequence's storage to hold the result. Even if the storage is recycled, the result may or may not be == to sequence.
```sort   sequence  #key test stable  =>  new-sequence	[Generic Function]
```
sort returns a new sequence containing the elements of sequence sorted into ascending order. test, which defaults to <, is used to determine what an "ascending order" is. If stable is supplied and not #f, a possibly slower algorithm will be used that will leave in their original order any two elements, x and y, such that test(x, y) and test(y, x) are both false.
```? define variable numbers = #(3, 1, 4, 1, 5, 9)
numbers
? sort (numbers)
#(1, 1, 3, 4, 5, 9)
? numbers
#(3, 1, 4, 1, 5, 9)
```
```sort!   sequence1 #key test stable  =>  sequence2	[Generic Function]
```
This function is like sort, but may reuse the storage from sequence to form the result. The result may or may not be == to sequence.
```first   sequence  #key default =>  value	[Function]
second   sequence  #key default => value	[Function]
third   sequence  #key default =>  value	[Function]
```
Each of these functions returns the indicated element of the sequence by calling element with the supplied arguments and the corresponding index.

Note that because element is zero-based, first(seq) is equivalent to element (seq, 0) and seq[0].

```first-setter   new-value  sequence =>  new-value	[Function]
second-setter   new-value  sequence =>   new-value	[Function]
third-setter   new-value  sequence =>  new-value	[Function]
```
Each of these functions sets the indicated element of the sequence and returns the new-value, by calling element-setter with the supplied arguments and the corresponding index.

Note that because element is zero-based, first-setter(val, seq) is equivalent to element-setter (val, seq, 0) and seq[0] := val.

```last   sequence  #key default =>  value	[Generic Function]
```
last returns the last element of sequence. If the sequence is empty, then the behavior of last depends on whether it was called with a default argument. If the default argument was supplied, its value is returned; otherwise, an error is signaled.
```? last (#("emperor", "of", "china"))
"china"
```
```last-setter new-value  mutable-sequence =>  new-value	      [Generic Function]
```
Replaces the last element of mutable-sequence with new-value. new-value must obey any type restrictions for elements of mutable-sequence . An error is signaled if mutable-sequence is empty or unbounded.

```? define variable my-list = list (1, 2, 3)
? my-list
#(1, 2, 3)
? last (my-list) := 4
4
? my-list
#(1, 2, 4)

? define variable my-empty-vector = vector()
? my-empty-vector
#[]
? last (my-empty-vector) := 4
// error
```
```subsequence-position   big pattern #key test count  =>  index	[Generic Function]
```
big and pattern must be sequences. Searches big for a subsequence that is element-for-element equal to pattern, as determined by the test argument (which defaults to ==). That is, test is applied to the subsequence of big and corresponding elements of the pattern to determine whether a match has occurred. If count is specified, then the countth such subsequence is selected. If a subsequence is found, returns the index at which the subsequence starts; otherwise, returns #f.
```? subsequence-position ("Ralph Waldo Emerson", "Waldo")
6
```
```sequence1  = sequence2  =>  boolean	[G.F. Method]
```
For sequences, = returns #f unless sequence1 and sequence2 have the same size and elements with = keys are =.
```key-test sequence  => test-function	[G.F. Method]
```
The method of key-test for sequences returns the function ==.

Next section: The Instantiable Collection Classes