Challenge: Make a data type for holding one of 8 directions allowing increment and overflow

Basile B. b2.temp at gmx.com
Wed Mar 13 10:27:49 UTC 2024


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.


More information about the Digitalmars-d-learn mailing list