Предыстория: несколько недель назад я работал над проектом в схеме guile 1.8.8 и, немного заржавев, забыл о встроенной функции (reduce)
, поэтому Я свой закатал. Чуть позже я столкнулся с, казалось бы, безнадежной ошибкой, когда вызов функции без побочных эффектов изменил ход остальной части программы (работает правильно и проходит несколько модульных тестов вместо полного сбоя) ПОСЛЕ того, как функция давно вернулся. Несколько фрагментов кода, которые раньше возвращали что-то вроде (A B C D)
, теперь возвращали только (A)
, вызывая множество проблем.
Минимальный рабочий пример: после нескольких дней урезания я загнал проблему в этот небольшой фрагмент автономного кода:
(define (my-reduce fun ls)
(if (null? (cdr ls))
(car ls)
(my-reduce fun (cons (fun (car ls) (cadr ls))
(cddr ls)))))
(format #t "~a " (my-reduce + '(1 2 3)))
(format #t "~a " (my-reduce or '(1 2 3)))
(format #t "~a~%" (my-reduce + '(1 2 3)))
Что выводит 6 1 1
вместо ожидаемого 6 1 6
.
Дополнительные наблюдения:
- Установка во второй строке значения
+
дает ожидаемое значение6 6 6
. - Установка второй строки на
and
дает6 3 3
. - Дополнительные строки
+
после них производят дополнительные1
s или3
s в зависимости от того, что установлено во второй строке. Итак, последовательность+
or
+
+
приводит к выходу6 1 1 1
. - Дополнительные строки
and
илиor
после первой НЕ переключают вывод обратно. Итак, если последовательность+
and
or
+
, выход6 3 3 3
. Кажется, что как только я передалor
илиand
в(my-reduce)
, функция навсегда "застревает", имея это в качестве аргумента. - Я также заметил, что передача
and
илиor
встроенной функции(reduce)
вызывает ошибку типа, поскольку технически они являются макросами, а не функциями. - В том же духе я замечаю, что замена
or
на(lambda (x y) (or x y))
дает ожидаемый результат. Таким образом, кажется, что критическим моментом здесь является то, что передача макросов в мою домашнюю функцию сокращения вызывает проблему.
Вопрос. Что здесь происходит? Почему вызов (my-reduce)
с помощью and
или or
вызывает такое неожиданное поведение? Связано ли это с тем, что эти «функции» на самом деле являются макросами?
Заранее благодарю за любую помощь. Этот меня действительно поразил!