В продолжение
про интерфейсы.
В принципе, можно использовать паттерн Factory для параметризации реализаций функции, создающей новый стек -- параметр типа для привязки фабрик к соответствующим стекам. Однако, если подумать и поэкспериментировать, окажется, что этого маловато будет :)
Тут ещё потребуется
нечто , называемое F-ограниченным полиморфизмом (
F-bounded_quantification ), чтобы убедиться, что "входящие" и "выходящие" стеки имеют одинаковую реализацию.
Что-то вроде
interface Stack<T extends Stack<T>> ...
И всё равно это кривоватые приляпки (например,
Curiously recurring template pattern, на котором была основана вся Microsoft C++ Active Template Library :), мешающие наглядно показать в коде, как программа может использовать стек, не зная, какая именно это реализация...
...Модули основополагающи, и многое из того, что делается в других языках -- от конфигураций сборки до инъекции зависимостей и шаблона Adapter -- в значительной степени попытка кодирования того, что легко выразить с помощью модулей.
(Из свежего материала в СильныхИдеях "Модули важнее всего", где поясняется с помощью Роберта Харпера, как об этом всём правильнее думать и рассуждать)