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