Как обезьянить патч таблицы функций тега универсального типа - PullRequest
4 голосов
/ 21 июня 2011

Мне было интересно прочитать об одном из способов, которыми вы можете выполнять функциональную динамическую диспетчеризацию в sicp - используя таблицу типа tag + name -> функции, из которых вы можете получать или добавлять.

Мне было интересно, это типичный механизм диспетчеризации типов для динамического языка без OO?

Кроме того, каков был бы типичный способ обезьяньего пути, используя цепочечный список таблиц (если вы не найдете его в первой таблице, попробуйте следующую таблицу рекурсивно)? Пересвязать таблицу в локальной области видимости с измененной копией? ЭСТ?

1 Ответ

2 голосов
/ 14 июля 2011

Я считаю, что это типичный механизм диспетчеризации типов, даже для нединамических языков без OO, основанный на этой статье о компиляторе JHC Haskell и о том, как он реализует классы типов.В статье подразумевается, что большинство компиляторов Haskell реализуют классы типов (разновидность диспетчеризации типов), передавая словари.Его альтернативой является прямой анализ случаев, который, скорее всего, не будет применяться в динамически типизированных языках, поскольку вы не знаете заранее, какими будут типы составляющих вашего выражения.С другой стороны, это не расширяемо и во время выполнения.

Что касается динамических неOO-языков, я не знаю многих примеров за пределами Lisp / Scheme.CLOS Common Lisp делает Lisp надлежащим языком OO и обеспечивает динамическую диспетчеризацию, а также множественную диспетчеризацию (вы можете добавлять или удалять универсальные методы и методы во время выполнения, и они могут отключать тип больше, чем просто первый параметр).Я не знаю, как это обычно реализуется, но я знаю, что это, как правило, надстройка, а не встроенная функция, что подразумевает, что она использует функциональные возможности, доступные для потенциального обезьяны-патчера, а также чтонекоторые версии были подвергнуты критике за недостаточную скорость (я думаю, CLISP, но, возможно, они решили эту проблему).Конечно, вы могли бы реализовать этот тип механизма параллельной диспетчеризации и в языке OO, и вы можете найти множество примеров этого.

Если бы вы использовали чисто функциональные постоянные карты или словари, вы могли быконечно, реализовать эту способность, даже не нуждаясь в цепочке унаследованных карт;когда вы «модифицируете» карту, вы получаете новую карту обратно, но все существующие ссылки на старую карту все равно будут действительны и будут видеть ее как старую версию.Если бы вы реализовывали язык с помощью этого средства, вы могли бы интерпретировать его, поместив карту функции type-> в монаду Reader и заключив в нее свой интерпретатор.

...