Полиморфизм высшего порядка типы значений

#generics #types #higher-order-functions #value-type #higher-kinded-types

#обобщения #типы #функции более высокого порядка #тип значения #типы более высокого порядка

Вопрос:

Я где-то читал, что полиморфизм высшего порядка не может быть использован / реализован в системах типов с типами значений (например, .NET). Правильно ли это и почему?

Ответ №1:

Проблема заключается в представлении значений.

Традиционные языки полиморфизма высшего порядка сделали упрощающий выбор в пользу того, что все значения представлены единообразно, обычно одним словом, с некоторыми хитроумными тегами, указывающими, является ли это непосредственное целое число или указатель на структуру с общим представлением (некоторый тег и т.д.) Для всех других значений, таких как структуры данных или функции.

Если у вас есть это предположение, вы можете скомпилировать каждую полиморфную функцию один раз и использовать ее для всех аргументов всех типов: они имеют представление, предполагаемое скомпилированной функцией.

Теперь предположим, что вы создаете типы с другими представлениями, например. несколько непрерывных слов в стеке. Вы больше не можете использовать свою единственную скомпилированную функцию, потому что она будет ожидать одно слово, поэтому соглашение о вызове неверно. Что-то сломано.

Это может быть исправлено различными способами, такими как :

  • пройти вместе со значениями некоторой информацией об их представлении (вы могли бы рассмотреть эту информацию, чтобы быть своего рода выполнения «тип» информации, но на самом деле вам не нужен полный тип информации, просто некоторая информация о представительстве); это то, что наклон компилятор исследовал например

  • попробуйте скомпилировать несколько специализированных версий вашей полиморфной функции для каждого возможного представления, затем решите (также на основе своего рода тега или некоторой статически доступной информации), какую версию вызывать. Это может быть разумно при использовании схемы оптимизации всей программы, такой как MLton. Это более или менее версия первой идеи по выбору вызывающего абонента (а не по выбору вызываемого абонента).

  • ограничьте полиморфизмы, используя систему сортировки, чтобы различать «типы из одного слова», «типы кортежей». Вместо обычного полиморфизма «для всех типов» у вас была бы релятивизированная версия «для всех типов такого рода …». Это позволяет программисту статически рассуждать о том, какая функция может принимать аргументы какого типа («ой, эта функция полиморфна, поэтому я должен указать здесь свой тип значения») вместо того, чтобы надеяться, что компилятор правильно выполнит принудительные действия, но это также утяжеляет систему типов: вы не сохраняете иллюзию единообразия.

Короче говоря, комбинированный (некоторая форма) полиморфизм с широким выбором представления данных возможен, но намного сложнее, чем в случае единообразного представления.

Комментарии:

1. Типы значений с полиморфной рекурсией проблематичны для решения № 2, поскольку вам может потребоваться скомпилировать бесконечно много версий кода. Возможно ли обнаружить такие случаи?

2. На практике вам все равно не захочется заполнять свой стек типами значений, размер которых неограничен из-за рекурсивных вызовов. Моя интуиция заключается в том, что установление статического ограничения на размер (и боксирование выше) или принудительное использование рекурсий типов для прохождения хотя бы по одному указателю в большинстве случаев являются более разумными решениями, чем добавление полного JIT в ваш язык для обработки этого.

Ответ №2:

Нет, это неверно. вы можете достичь «полиморфизма более высокого порядка» (функции, которые ведут себя одинаково для всех типов), определив типы параметров либо как generics, либо типа object (типы значений будут автоматически «упакованы» в объекты)