A library of immutable abstract data types inspired by LINQ. Plato.Collections is built in Platonic C# and is fully compatible with .NET Standard 2.0.
Platonic C# is a set of coding guidelines for using C# that enable data structures and algorithms to be machine translated into the Plato language. Plato is being developed as a high-performance pure functional language that can target multiple platforms.
Plato.Collections is designed starting from simple generic immutable interfaces, with a rich library extension methods, and factory functions.
- All collections are immutable, side-effect free, and thread-safe.
- Simplicity is chosen over performance
- Required API for an Interfaces should each be as small as possible
- Each interface should describe a single well-defined concept
- Data types with different algorithmic complexity need different representations
- Low-level performance concerns beyond should be primarily the concern of optimization tools
The System.IEnumerable<T>
interface represents a potentially mutable type and has the following interfaces:
interface IEnumerable<T>
{
IEnumerator<T> GetEnumerator();
}
The Plato.ISequence<T>
type is quite similar, but only represents immutable types. One of the advantages
of an ISequence
is that it can safely be enumerated multiple times, and has a hard guarantee of never
changing under.
interface ISequence<T>
{
IIterator<T> Iterator { get; }
}
The IIterator<T>
type returned from the Iterator
property, is also an immutable type unlike IEnumerable
.
This affords several advantages such as the fact that a collection of iterators can be safely made representing different
locations in a sequence.
The System.IEnumerator<T>
interface represents a mutable type and has the following interfaces:
interface IEnumerator<T>
{
T Current { get; }
bool MoveNext();
void Reset();
void Dispose();
}
The comparable interface Plato.IIterator<T>
on the other hand is immutable and has the following interface:
interface IIterator<T>
{
T Value { get; }
bool HasValue { get; }
IIterator<T> Next { get; }
}
Notice that IIterator<T>
cannot be disposed, nor can it be reset. Unlike the IEnumerator
it is initialized to point to the first element in a sequence, as opposed to pointing to a location before the
first spot (IEnumerator
requires an initial call to MoveNext()
before values can be retrieved).
The Plato.IArray
interface provides a read-only interface to arrays.
Unlike Plato.ISequence
or System.IEnumerable
, many of the IArray
operations
return an IArray
, which retains algorithmic complexity O(1) for
querying the count, or random access of elements.
interface IArray<T>
{
int Count { get; }
this[int n] { get; }
}
The IArray<T>
implementation is based on the LinqArray library, which in turn
is based on article at CodeProject.com called LINQ for Immutable Arrays.
Some of the additional types provided by Plato.Collections library includes:
ICountedSequence<T>
ISet<T>
IQueue<TKey>
IDequeue<TKey>
IStack<TKey>
IHeap<TKey>
IDictionary<TKey, TValue>
IMultiDictionary<TKey, TValue>
IBiDictionary<TKey, TValue>