"Represents an iterable collection of elements of finite 
 size, with a well-defined notion of value equality. 
 `Collection` is the abstract supertype of [[List]], 
 [[Map]], and [[Set]].
 
 A `Collection` forms a [[Category]] of its elements, and 
 is [[Iterable]]. The elements of a collection are not
 necessarily distinct when compared using [[Object.equals]].
 
 A `Collection` may be [[cloned|clone]]. If a collection is
 immutable, it is acceptable that `clone()` produce a
 reference to the collection itself. If a collection is
 mutable, `clone()` should produce a collection containing 
 references to the same elements, with the same structure as 
 the original collection—that is, it should produce a 
 shallow copy of the collection.
 
 All `Collection`s are required to support a well-defined
 notion of [[value equality|Object.equals]], but the
 definition of equality depends upon the kind of collection.
 Equality for `Map`s and `Set`s has a quite different
 definition to equality for `List`s."
see (`interface List`, `interface Map`, `interface Set`)
shared interface Collection<out Element>
        satisfies {Element*} {
    
    "A shallow copy of this collection, that is, a 
     collection with identical elements which does not
     change if this collection changes. If this collection
     is immutable, it is acceptable to return a reference to
     this collection. If this collection is mutable, a newly
     instantiated collection must be returned."
    shared formal Collection<Element> clone();
    
    "Determine if the collection is empty, that is, if it 
     has no elements."
    shared actual default Boolean empty => size==0;
    
    "Return `true` if the given object is an element of
     this collection. In this default implementation, and in 
     most refining implementations, return `false` 
     otherwise. An acceptable refining implementation may 
     return `true` for objects which are not elements of the 
     collection, but this is not recommended. (For example, 
     the `contains()` method of `String` returns `true` for 
     any substring of the string.)"
    shared actual default Boolean contains(Object element) {
        for (elem in this) {
            if (exists elem, elem==element) {
                return true;
            }
        }
        else {
            return false;
        }
    }
        
    "A string of form `\"{ x, y, z }\"` where `x`, `y`, and 
     `z` are the `string` representations of the elements of 
     this collection, as produced by the iterator of the 
     collection, or the string `\"{}\"` if this collection 
     is empty. If the collection iterator produces the value 
     `null`, the string representation contains the string 
     `\"<null>\"`."
    shared actual default String string => 
            empty then "{}" else "{ ``commaList(this)`` }";
    
}

String commaList({Anything*} elements) 
        => ", ".join { for (element in elements) 
                           element else "<null>" };