It turns out that I omitted the implementation of
.Reverse() from my recent post Immutable Stacks Miscellany. Given that a friend has identified an alternative way to implement this, we’ll take a minor detour.
Perhaps the simplest approach (and the one that I had originally) is to create an extension method, based on the
IImmutableStack<T> interface to return a new stack:
.Aggregate() method makes the implementation quite simple. (If you’re not familiar with
.Aggregate(), check out this StackOverflow answer for a really good explanation.)
The suggested alternative is to instead extend our existing
Taking this approach requires us to write a separate method for each implementation of the stack, allowing us to optimize for each context.
For an empty stack, reversing the stack is trivially simple, because we just need an empty stack:
For our simple stack, we can also include an optimization to handle the case of a stack with just one item:
Which approach is better?
On the one hand, we have the
.Reverse() extension method that allows us to reverse any implementation of
IImmutableStack<T>. This is the exact use case for which extension methods were introduced into C#, allowing implementors to create a rich set of functionality on the base of a simple interface.
However, on the other hand, we only have a couple of implementations of
IImmutableStack<T> to worry about, not dozens. Further, writing separate implementations allows us to make some memory saving optimizations with negligable execution cost.
Given that one of the premises of well written immutable data structures is that they make extensive reuse of data wherever possible, I’m leaning towards separate implementations as the preferred approach.