Collections Language
An extension to the Base Language that adds support for collections.
Introduction
Collection language provides a set of abstractions that enable the use of a few most commonly used containers, as well as a set of powerful tools to construct queries. The fundamental type provided by the collections is sequence, which is an abstraction analogous to Iterable in Java, or IEnumerable in .NET . The containers include list (both array-based and linked list), set and map. The collections language also provides the means to build expressive queries using closures, in a way similar to what LINQ does.
Null handling
Collections language has a set of relaxed rules regarding null elements and null sequences.
Null sequence is still a sequence
Null is a perfectly accepted value that can be assigned to a sequence variable. This results simply in an empty sequence.
sequence<Type> nullSeq = null;
Null values are ignored
A null value passed as a parameter to a modifying operation will be ignored. Similarly, a null value returned from the select/translate closure will not affect the resulting sequence. This effectively prohibits the use of null values in the containers.
list<Type> list = new arraylist <Type> {}; list.add (null);
Null is returned instead of exception throwing
Whereas the standard collections framework would have to throw an exception, as a result of calling a method that cannot successfully complete, the collection language's sequence and its subtypes would return null value. For example, invoking first operation on an empty sequence will yield a null value instead of throwing an exception.
sequence<Type> nullSeq = null;
Type nullValue = nullSeq.first;
Skip and stop statements
skip
Applicable within a translate, select, or visitAll closure. The effect of the skip statement is that the processing of the current input element stops, and the next element (if available) is immediately selected.
stop
Applicable within a translate closure or a sequence initializer closure. The stop statement causes the construction of the output sequence to end immediately, ignoring all the remaining elements in the input sequence (if any).
Sequence
A sequence is an abstraction of an order defined on a collection of elements of some type. The only operation that is allowed on a sequence is iterating its elements from first to last. A sequence is immutable. All operations defined in the following subsections and declared to return a sequence, always return a new instance of a sequence or the original sequence.
Although it is possible to create a sequence that produces infinite number of elements, it is not recommended. Some operations may require one or two full traversals of the sequence in order to compute, and invoking such an operation on an infinite sequence would never yield result.
Sequence type
sequence<Type>
| Subtypes | Supertypes | Comparable types |
|---|---|---|
| list<Type> set<Type> |
none | java.lang.Iterable<Type> |
Creation
new sequence
| Parameter type | Result type |
|---|---|
| { => sequence<Type> } | sequence<Type> |
Sequence can be created with initializer.
sequence<Type> seq = new sequence<Type>({=> /* code with yield keywords */ })
closure invocation
| Result type |
|---|
| sequence<Type> |
A sequence may be returned from a closure (see Closures).
sequence<Type> seq = {=> /* code with yield keywords producing a sequence */ }.invoke;
A list and a set are sequences, too. All operations defined on a sequence are also available on an instance of any of these types.
Sequence type is comparable with Classifier type <java.lang.Iterable>. They can be used interchangeably.
Iteration and querying
foreach
Loop statement
foreach foo in bar {
...
}
is equivalent to
for (Type foo: bar) {
...
}
visitAll
| Operand type | Parameter type | Result type |
|---|---|---|
| sequence<Type> | { Type => void } | void |
The code passed as a parameter (as a closure literal or by reference) is executed once for each element.
seq.visitAll({=> /* arbitrary code*/});
size
| Operand type | Parameter type | Result type |
|---|---|---|
| sequence<Type> | none | int |
Gives number of elements in a sequence.
isEmpty
isNotEmpty
| Operand type | Parameter type | Result type |
|---|---|---|
| sequence<Type> | none | boolean |
Test whether a sequence contains any elements.
indexOf
| Operand type | Parameter type | Result type |
|---|---|---|
| sequence<Type> | Type | int |
Gives the index of a first occurrence in a sequence of an element that is passed to it as a parameter.
int idx = seq.indexOf(elm)
contains
| Operand type | Parameter type | Result type |
|---|---|---|
| sequence<Type> | Type | boolean |
Produces boolean value, indicating whether or not a sequence contains the specified element.
if (seq.contains(elm)) {
...
}
Selection and filtering
first
| Operand type | Parameter type | Result type |
|---|---|---|
| sequence<Type> | none | Type |
Yields the first element.
last
| Operand type | Parameter type | Result type |
|---|---|---|
| sequence<Type> | none | Type |
Yields the last element.
take
| Operand type | Parameter type | Result type |
|---|---|---|
| sequence<Type> | int | sequence<Type> |
Produces a sequence that is sub-sequence of the original one, starting from first element and of size count.
seq.take (count)
skip
| Operand type | Parameter type | Result type |
|---|---|---|
| sequence<Type> | int | sequence<Type> |
Produces a sequence that is sub-sequence of the original one, containing all elements starting with the element at index count.
seq.skip (count)
cut
| Operand type | Parameter type | Result type |
|---|---|---|
| sequence<Type> | int | sequence<Type> |
Produces a sequence that is a sub-sequence of the original one, containing all elements starting with first and up to (but not including) the element at index size minus count. In other words, this operation returns a sequence with all elements from the original one except the last count elements.
seq.cut (count)
tail
| Operand type | Parameter type | Result type |
|---|---|---|
| sequence<Type> | int | sequence<Type> |
Produces a sequence that is a sub-sequence of the original one, containing all elements starting with the element at index size minus count. In other words, this operations returns a sequence with count elements from the end of the original sequence, in the original order.
seq.tail (count)
page
| Operand type | Parameter type | Result type |
|---|---|---|
| sequence<Type> | int int |
sequence<Type> |
Results in a sequence that is a sub-sequence of the original one, containing all elements starting with the element at index start and up to (but not including) the element at index end.
seq.page (start, end)
This is equivalent to
seq.skip (skip).take (count)
Where skip = start, count = end - start .
where
| Operand type | Parameter type | Result type |
|---|---|---|
| sequence<Type> | { Type => boolean } | sequence<Type> |
Produces a sequence that is a sub-sequence of the original one, with all elements for which the code passed as a parameter (as a closure literal or by reference) returns true.
seq.where ({ => ... })
Transformation and sorting
select
| Operand type | Parameter type | Result type |
|---|---|---|
| sequence<Type> | { Type => Type2 } | sequence<Type2> |
Results in a sequence consisting of elements, each of which is the result of applying the parameter function (passed as a closure literal or by reference) to each element of the original sequence in turn.
seq.select ({ Type element => /* code returning single element of same or some other type */ })
translate
| Operand type | Parameter type | Result type |
|---|---|---|
| sequence<Type> | { Type => sequence<Type2> } | sequence<Type2> |
Produces a sequence that is a concatenation of all sequences, which are all the results of applying the parameter function (passed as a closure literal or by reference) to each element of the original sequence in turn.
seq.translate ({ <Type> element => /* code returning a sequence. May utilize yield keyword.*/ })
concat
| Operand type | Parameter type | Result type |
|---|---|---|
| sequence<Type> | sequence<Type> } | sequence<Type> |
Produces a sequence, which is a concatenation of the original one with the sequence passed as a parameter
seq.concat (otherSeq)
distinct
| Operand type | Parameter type | Result type |
|---|---|---|
| sequence<Type> | none | sequence<Type> |
Produces a sequence, which contains all elements from the original sequence in the original order, with all the elements having cardinality exactly 1. Of all occurrences of an element in the original sequence, only the first occurrence is included in the resulting sequence.
sortBy
| Operand type | Parameter type | Result type |
|---|---|---|
| sequence<Type> | { Type => Type2 } boolean |
sequence<Type> |
Produces a sequence with all elements from the original one in the order, which corresponds to an order induced by an imaginary sequence produced by applying the selector function (passed as a closure literal or by reference) to each element in the original sequence in turn. The selector function can be thought of as returning a key, which is used to sort elements in a sequence. The ascending parameter controls the sort order.
seq.sortBy ({ => /* code returning a sorting key */ }, ascending)
sort
| Operand type | Parameter type | Result type |
|---|---|---|
| sequence<Type> | { Type, Type => int } boolean |
sequence<Type> |
Produces a sequence containing all elements from the original one in the order produced by applying the comparator function (passed as a closure literal or by reference) to a list with elements from the original sequence. The ascending parameter controls the sort order (order is reversed if the value is false).
seq.sort ({ <Type> a, <Type> b => /* code returning -1, 0 or 1 according to java.util.Comparator */}, ascending)
Comparison
intersect
| Operand type | Parameter type | Result type |
|---|---|---|
| sequence<Type> | sequence<Type> | sequence<Type> |
Produces a sequence containing elements contained both by the original sequence and the parameter sequence.
seq.intersect (anotherSeq)
except
| Operand type | Parameter type | Result type |
|---|---|---|
| sequence<Type> | sequence<Type> | sequence<Type> |
Produces a sequence containing all elements from the original sequence that are not also members of the parameter sequence.
seq.except (anotherSeq)
union
| Operand type | Parameter type | Result type |
|---|---|---|
| sequence<Type> | sequence<Type> | sequence<Type> |
Produces a sequence containing elements both from the original sequence and the one passed as a parameter.
seq.union (anotherSeq)
disjunction
| Operand type | Parameter type | Result type |
|---|---|---|
| sequence<Type> | sequence<Type> | sequence<Type> |
Produces exclusive disjunction of the original sequence and the one passed as a parameter.
seq.disjunction (anotherSeq)
Conversion
toList
| Operand type | Parameter type | Result type |
|---|---|---|
| sequence<Type> | none | list<Type> |
Returns new list containing all the elements from the original sequence.
seq.toList
toArray
| Operand type | Parameter type | Result type |
|---|---|---|
| sequence<Type> | none | Type*[]* |
Returns new array containing all the elements from the original sequence.
seq.toArray
List
A basic list container backed by either array list or linked list.
List type
list<Type>
| Subtypes | Supertypes | Comparable types |
|---|---|---|
| none | sequence<Type> | java.util.List<Type> |
Creation
new arraylist
new linkedlist
| Parameter type | Result type |
|---|---|
| Type... | list<Type> |
Creates an empty list. Optionally, initial values may be specified right in the new list creation expression.
list<Type> = new arraylist<Type> ( ... );
Access
get
| Operand type | Parameter type | Result type |
|---|---|---|
| list<Type> | int | Type |
Yields the element at index position.
list.get (index);
indexed access
list[index];
Modification
set
| Operand type | Parameter type | Result type |
|---|---|---|
| list<Type> | int Type |
Type |
Sets the element at index position to the specified value. Yields the new value.
list.set (index, value);
indexed access
list[index] = value;
add
| Operand type | Parameter type | Result type |
|---|---|---|
| list<Type> | Type | Type |
Adds an element to the list.
list.add (value);
addFirst
| Operand type | Parameter type | Result type |
|---|---|---|
| list<Type> | Type | Type |
Adds an element to the list as the first element.
list.addFirst (value);
addLast
| Operand type | Parameter type | Result type |
|---|---|---|
| list<Type> | Type | Type |
Adds an element to the list as the last element.
list.addLast (value);
insert
| Operand type | Parameter type | Result type |
|---|---|---|
| list<Type> | int Type |
Type |
Inserts an element into the list at the position index.
list.insert (index, value);
remove
| Operand type | Parameter type | Result type |
|---|---|---|
| list<Type> | Type | Type |
Removes an element from the list.
list.remove (value);
removeFirst
| Operand type | Parameter type | Result type |
|---|---|---|
| list<Type> | none | Type |
Removes the first element from the list.
list.removeFirst;
removeLast
| Operand type | Parameter type | Result type |
|---|---|---|
| list<Type> | none | Type |
Removes the last element from the list.
list.removeLast;
removeAt
| Operand type | Parameter type | Result type |
|---|---|---|
| list<Type> | int | Type |
Removes an element from the list located at the position index.
list.removeAt (index);
addAll
| Operand type | Parameter type | Result type |
|---|---|---|
| list<Type> | sequence<Type> | list<Type> |
Adds all elements in the parameter sequence to the list.
list.addAll (seq);
removeAll
| Operand type | Parameter type | Result type |
|---|---|---|
| list<Type> | sequence<Type> | list<Type> |
Removes all elements in the parameter sequence from the list.
list.removeAll (seq);
clear
| Operand type | Parameter type | Result type |
|---|---|---|
| list<Type> | none | void |
Clears all elements from the list.
list.clear;
Transformation
reverse
| Operand type | Parameter type | Result type |
|---|---|---|
| list<Type> | none | list<Type> |
Produces a list with all elements from the original list in the reversed order.
list.reverse;
| Important The reverse operation does not modify the original list, but rather produces another list. |
Set
Set type
set<Type>
| Subtypes | Supertypes | Comparable types |
|---|---|---|
| none | sequence<Type> | java.util.Set<Type> |
Creation
new hashset
| Parameter type | Result type |
|---|---|
| Type... | set<Type> |
Creates an empty set. Optionally, initial values may be specified right in the new set creation expression.
set<string> test = new hashset<string> {"A", "B", "C"};
Modification
add
| Operand type | Parameter type | Result type |
|---|---|---|
| set<Type> | Type | Type |
Adds an element to the set.
set.add (value);
addAll
| Operand type | Parameter type | Result type |
|---|---|---|
| set<Type> | sequence<Type> | set<Type> |
Adds all elements in the parameter sequence to the set.
set.addAll (seq);
remove
| Operand type | Parameter type | Result type |
|---|---|---|
| set<Type> | Type | Type |
Removes an element from the set.
set.remove (value);
removeAll
| Operand type | Parameter type | Result type |
|---|---|---|
| set<Type> | sequence<Type> | set<Type> |
Removes all elements in the parameter sequence from the set.
set.removeAll (seq);
clear
| Operand type | Parameter type | Result type |
|---|---|---|
| set<Type> | none | void |
Clears all elements from the set.
set.clear;
Map
Map type
map<KeyType, ValueType>
| Subtypes | Supertypes | Comparable types |
|---|---|---|
| none | none | java.util.Map<KeyType, ValueType> |
Creation
new map
| Parameter type | Result type |
|---|---|
| (KeyType => ValueType)... | map<KeyType, ValueType> |
Creates an empty map. Optionally, initial values may be specified right in the new map creation expression.
map<string, int> map = new hashmap<string, int> {"A" => 1, "B" => 2, "C" => 3};
Access
get value by key
int value = map["key"];
keys
| Parameter type | Result type |
|---|---|
| none | sequence<KeyType> |
Yields a sequence containing all the keys in the map.
sequence<string> keys = map.keys;
containsKey
| Parameter type | Result type |
|---|---|
| none | sequence<KeyType> |
Yields a sequence containing all the keys in the map.
sequence<string> keys = map.keys;
Modification
assign value to a key
map["key"] = value;
remove
| Parameter type | Result type |
|---|---|
| KeyType | void |
Removes the specified key and the associated value from the map.
map.remove ("key");
clear
| Parameter type | Result type |
|---|---|
| none | void |
Clears all key-value pairs from the map.
map.clear;
Add Comment