Проверьте запуском
LISPEX
(fold-right cons (list) (list 1 2 3))Наблюдаемый результат
OUTPUT
(1 2 3)Как рассуждать
- Списки, строки и векторы обходятся слева направо. Исключение составляет
fold-right, который вызывает(f element accumulator)справа налево. reduceиfold-leftдают одну и ту же левую свёртку с вызовом(f accumulator element).all?иany?останавливаются, как только ответ известен, и принимают от предиката только#tили#f.filterиспользует обычную истинность Лиспекса.for-eachвыполняется ради эффекта, отбрасывает любое число значений функции обратного вызова и сам возвращает ноль значений.- Ошибки и одноразовые выходы функции обратного вызова остаются внутри
программы, выполняющей правило. LIL не передаёт процедуру в
applyхоста или в функцию обратного вызова хоста.
Контракты функций обратного вызова
| Сигнатура | Обход / результат | Контекст значений |
|---|---|---|
| (map proc list) | слева направо, новый правильный список | функция возвращает ровно одно значение |
| (filter predicate list) | слева направо, сохранённые элементы | предикат возвращает ровно одно значение, исключает только #f |
| (all? predicate list), (any? predicate list) | слева направо с остановкой сразу после ответа, строгий boolean | предикат возвращает ровно один boolean |
| (reduce proc init list), (fold-left proc init list) | левый аккумулятор | функция возвращает ровно одно значение |
| (fold-right proc init list) | правый аккумулятор | функция возвращает ровно одно значение |
| (string-map proc string), (vector-map proc vector) | слева направо, новый результат | ровно одно значение, а для строки это должен быть символ |
| строковый/векторный/списочный for-each | эффекты слева направо, в итоге ноль значений | результаты обратного вызова отбрасываются |
| (apply proc arg ... final-list) | общий диспетчер, хвостовая безопасность | все значения, которые вернула процедура, сохраняются |
Частая ошибка
Эти процедуры принимают одну коллекцию, а не варианты с несколькими списками из некоторых реализаций Scheme. Символы строки и элементы вектора копируются до первого обратного вызова, поэтому изменение исходного вектора во время обхода не меняет того, какие элементы будут посещены.
Куда дальше
Как собрать эти процедуры в один рабочий конвейер, показывает практическая страница, а место семейства среди остальных показывает указатель.