Code That Says Exactly What It Means
Kagamin
spam at here.lot
Thu Oct 30 15:24:03 UTC 2025
On Thursday, 30 October 2025 at 05:23:29 UTC, Peter C wrote:
> An putting aside any idea of adding scopeprivate to D, let's
> remind ourselves that abstraction is one of the central
> principles of software engineering, what an abstract data type
> actually is, and why it's important for it to have the capacity
> to establish and maintain its own invariants:
>
> https://learn.adacore.com/courses/ada-in-practice/chapters/abstract_data_types.html
>
> If I put these two types in the same module, where you can
> reasonably argue they belong, then the concerns in the article
> above become an immediate reality in D:
Ironically in C# enumerator accesses all collection members
directly, including `_version`. Here's
System.Collections.Generic.List:
```
public struct Enumerator : IEnumerator<T>, IEnumerator
{
private readonly List<T> _list;
private int _index;
private readonly int _version;
private T? _current;
internal Enumerator(List<T> list)
{
_list = list;
_index = 0;
_version = list._version;
_current = default;
}
public void Dispose()
{
}
public bool MoveNext()
{
List<T> localList = _list;
if (_version == localList._version && ((uint)_index <
(uint)localList._size))
{
_current = localList._items[_index];
_index++;
return true;
}
return MoveNextRare();
}
private bool MoveNextRare()
{
if (_version != _list._version)
{
ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumFailedVersion();
}
_index = _list._size + 1;
_current = default;
return false;
}
public T Current => _current!;
object? IEnumerator.Current
{
get
{
if (_index == 0 || _index == _list._size + 1)
{
ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumOpCantHappen();
}
return Current;
}
}
void IEnumerator.Reset()
{
if (_version != _list._version)
{
ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumFailedVersion();
}
_index = 0;
_current = default;
}
}
```
More information about the Digitalmars-d
mailing list