Некоторые отличные ответы на этот (по общему признанию) старый вопрос, но я чувствую, что должен бросить свои несколько центов.
Нет способа, которым я мог бы каким-то образом добавить другую опцию к этому типу позже без изменения этого объявления. Так каковы преимущества этой системы? Похоже, что ОО путь будет гораздо более расширяемым.
Ответ, на мой взгляд, заключается в том, что расширяемость, которую дают открытые суммы, , а не всегда плюс, и, соответственно, тот факт, что OO заставляет это на тебе слабость.
Преимущество закрытых союзов заключается в их исчерпываемости : если вы исправили все альтернативы во время компиляции, тогда вы можете быть уверены, что не будет непредвиденных случаев, которые ваш код не сможет обработать. Это ценное свойство во многих проблемных областях, например, в деревьях абстрактного синтаксиса для языков. Если вы пишете компилятор, выражения языка попадают в предопределенный закрытый набор вложенных случаев - вы действительно не хотите, чтобы люди могли добавлять новые вспомогательные случаи во время выполнения, которые ваш компилятор не понимает !
Фактически, AST компилятора являются одним из классических мотивирующих примеров «Банды четырех» для шаблона посетителя, который является ООП аналогом закрытых сумм и исчерпывающего сопоставления с шаблоном. Полезно поразмышлять над тем фактом, что ОО-программисты в итоге изобрели шаблон для восстановления закрытых сумм.
Аналогично, процедурные и функциональные программисты изобрели шаблоны для получения эффекта сумм. Простейшим является кодирование «запись функций», соответствующее интерфейсам ОО. Запись функций - это, по сути, таблица отправки . (Обратите внимание, что программисты на Си использовали эту технику целую вечность!) Хитрость заключается в том, что очень часто существует большое количество возможных функций данного типа - часто бесконечно много. Таким образом, если у вас есть тип записи, чьи поля являются функциями, тогда он может легко поддерживать астрономически большой или бесконечный набор альтернатив. И более того, поскольку записи создаются во время выполнения и могут быть выполнены гибко в зависимости от условий выполнения, альтернативы имеют поздний предел .
Последний комментарий, который я хотел бы сделать, заключается в том, что, по моему мнению, ОО заставил слишком многих людей поверить, что расширяемость является синонимом позднего связывания (например, возможность добавлять новые подслучаи в тип время выполнения), когда это просто не так. Позднее связывание составляет один метод для расширяемости. Другой метод - композиция - построение сложных объектов из фиксированного словаря строительных блоков и правил их сборки. Словарный запас и правила в идеале невелики, но спроектированы так, чтобы иметь богатые взаимодействия, которые позволяют создавать очень сложные вещи.
Функциональное программирование - и, в частности, статически типизированные разновидности ML / Haskell - давно подчеркивали композицию над поздним связыванием. Но в действительности оба вида техники существуют в обеих парадигмах и должны быть в наборе инструментов хорошего программиста.
Стоит также отметить, что сами языки программирования являются фундаментальными примерами композиции. Язык программирования имеет конечный, надеюсь, простой синтаксис, который позволяет комбинировать его элементы для написания любой возможной программы. (На самом деле это восходит к приведенному выше примеру с компилятором / шаблоном посетителя и мотивирует его.)