Сцитирую ответ, который давал недавно в ЛС. (В квадратных скобках — дополнения, внесённые сейчас для большей ясности.)
Можно почитать
тут (код на Ruby вместе с определением).
amb — это функция, которой передаётся последовательность значений, и она возвращает то из них, которое в будущем не приведёт к проблемам [если таких не одно — любое, возможно недетерминированно]. Проблемы — это когда эту функцию вызывают совсем без значений (тогда ей действительно нечего вернуть [а она обязана по определению], это плохо) или когда любое из переданных значений приводит к проблемам. Этакое индуктивное определение. «Под капотом», как можно видеть, используются continuations, как и исходно в лиспе, и при неудаче выполнение просто начинается с предыдущего использования
amb с другой альтернативой — а когда они все кончатся, отматывается ещё дальше.
Этот неограниченный
amb, как и unbounded continuations, обычно довольно проблемно иметь в языке [программирования], потому что для трансляции всего этого дела надо попотеть, когда даже обычные генераторы [*] трудноваты (например, надо возвратиться из блока обработки исключения — это надо будет и все накопленные к этому моменту исключения отмотать тоже…). Можно сделать ограниченный
amb, который имеет власть только надо определённым куском кода. Его легко написать на чём угодно, где есть исключения, хотя зависит от языка, будет ли код с ним удобно писать.
Теперь представьте, что у мира (для простоты с абсолютным временем) есть свой
amb.
Он будет должен перематываться назад каждый раз, когда кто-то попросит невозможного (в простейшем случае сказав
amb без параметров)! И при этом никто этого никогда не успеет почувствовать. Всё будет выглядеть так, как будто никто никогда такого не делал. Если теперь кто-то обязательно решит говорить
amb в ответ на какую-то ситуацию, она тоже никогда не будет происходить. Разумеется, если мир не окажется совсем плохим и в любом случае натыкающемся на
amb. Но тогда в каком-то писательском смысле можно считать, что ничего [буквально вообще ничего] и не было.
[* Генераторы (generators) — синтаксис для определения функций, выдающих последовательность значений как функций, возвращающих значение много раз (обычно в цикле). Компилятор разрезает такое определение по операторам возврата, вводит внешнее к функции локальное состояние и т. д.. Кажется, это почти то же, что сопрограммы.]