В Clojure нет произвольного доступа для ленивых последовательностей.
В некотором смысле вы можете считать их эквивалентными односвязным спискам - у вас всегда есть текущий элемент и функция для получения следующего.
Так что, даже если вы просто вызываете (last some-seq)
он будет оценивать все элементы последовательности, даже если последовательность ленивая. Если последовательность конечна и достаточно мала (и если вы не держите начало последовательности в ссылке), то это нормально, когда дело доходит до памяти.Как вы заметили, существует проблема со временем выполнения, которая может возникнуть, если функция, используемая для получения следующего элемента, является дорогой.
В этом случае вы можете пойти на компромисс, чтобы использовать дешевую функцию для ходьбывплоть до последнего элемента:
(last some-seq)
и затем примените функцию только к этому результату:
(expensive (last some-seq))