On Tuesday, 12 March 2024 at 05:38:03 UTC, Liam McGillivray wrote:
I am in need of a data type for holding direction information;
one of 8 directions on a single axis. They are named in terms
of compass directions. If D had a 4-bit datatype, I would just
use this and do `+=2` whenever I want to change the datatype,
but it doesn't.
Perhaps this would be a good programming challenge for someone
more experienced than me. Make a data type (probably a struct)
for holding one of 8 directional values using 3 bits. It should
accept the use of increment operators to change the angle.
Ideally (but optionally), it should work as an enum of the same
name; "Direction".
Here's a unittest that it should ideally pass:
```
unittest
{
Direction direction = Direction.N;
direction++;
assert(direction == Direction.NE);
direction+=3;
assert(direction == Direction.S);
direction--;
assert(direction == Direction.SE);
direction-=4;
assert(direction == Direction.NW);
}
```
While there are workarounds (as proposed in the other answers,
using operator overloads) I tend to think that the way currently
enums work with arithmetic operators is a symptom of an
incomplete type-system. Enums made of integer numbers are sub
classes of the parent [integral
sequence](https://en.wikipedia.org/wiki/Integer_sequence).
The semantics of the operators are actually not as clear as that.
What if you define
```d
enum Direction
{
N = 1, NE, S = 45, SW
}
```
?
You directly see that the proposed workarounds dont work anymore.
There are natural numbers, sub-sets of natural numbers, unordered
sequences, etc.
The type system does not represent that. Anyway, I dont blame D,
plenty of languages have the exact same problem.