Parse, don’t validate
‘Make invalid states unrepresentable’ considered harmful
Две статьи с разными взглядами на использование типов для представления доменной области.
В геймдеве традиционно для доменной области данные должны быть максимально гибкими, так что тут уходят максимально далеко в сторону полюса data-driven и валидации.
Существуют и другие причины нелюбви к сложным описаниям логики над типами:
📍 Синтаксис для вычислений на типах отличается от синтаксиса для значений
- C++ computational quadrants — примеры синтаксиса на C++
Zig’s Lovely Syntax - в разделе “Everything is expression” описывается интересная особенность Zig, в нём сделана попытка унифицировать синтаксис выражений для типов и значений. Nim немного пытается делать то же.
📍 Время компиляции
. Мало кто задумывается над тем, чтобы оптимизировать время вычислений над типами, и оно может быстро стать проблемой (время компиляции — и так проблема в геймдеве)
- Template optimizations — существуют и приёмы оптимизации для шаблонов C++, но это не мейнстрим
📍 Сложность описания типа не всегда окупает выгоду от более точного ограничения области опредения функции
Иногда комментарий о том, что именно ожидает функция, и валидация входных данных может просто быть сильно читабельнее, чем кодирование ограничений в типе аргумента.
То есть в коде игры, в каком-нибудь очередном компоненте окна свойство для задания префаба этого окна скорее будет иметь простой тип string, а не какой-нибудь продвинутый тип-сумму с опцией задания функции выбора этой строки, или требований к структуре этого префаба, или закодированную в типе мета-информацию о верификации системой сборки и т.п.
Это всё, в общем, тривиальные соображения, для геймдева и C++.
Но вторая ссылка из начала поста заставила задуматься, а много ли вообще практических областей, где выгода от жёсткого описания ограничений типов при описании доменной области действительно неоспорима? Или тут как с объектно-ориентированным проектированием, полезность сильно преувеличена?