Макрос
Clojure for
используется с произвольными последовательностями Clojure.
Эти последовательности могут предоставлять или не предоставлять произвольный доступ, как это делают векторы. Таким образом, в общем случае у вас нет доступа к последнему элементу последовательности Clojure, не пройдя весь путь до него, что сделало бы невозможным выполнение прохода в обратном порядке.
Я предполагаю, что вы имели в виду нечто подобное (псевдокод, подобный Java):
for(int i = n-1; i--; i<=0){
doSomething(array[i]);
}
В этом примере мы заранее знаем размер массива n
и можем получить доступ к элементам по его индексу. С последовательностями Clojure мы этого не знаем. В Java имеет смысл делать это с массивами и ArrayLists. Последовательности Clojure, однако, гораздо больше похожи на связанные списки - у вас есть элемент и ссылка на следующий.
Кстати, даже если бы существовал (возможно, не идиоматический) * способ сделать это, его временная сложность была бы чем-то вроде O (n ^ 2), который просто не стоил бы усилий по сравнению с Гораздо более простое решение в связанном посте: O (n ^ 2) для списков и намного лучшее O (n) для векторов (и это довольно элегантно и идиоматично. Фактически, официальная реализация reverse
имеет такую реализацию).
EDIT:
Общий совет: не пытайтесь заниматься императивным программированием в Clojure, оно не было предназначено для этого. Хотя многие вещи могут показаться странными или нелогичными (в отличие от общеизвестных идиом из императивного программирования), когда вы привыкнете к функциональному способу выполнения вещей, это намного, и я имею в виду намного проще.
Специально для этого вопроса, несмотря на одно и то же имя Java (и другие C-подобные) for
и Clojure for
не одно и то же! Первый - это реальный цикл - он определяет управление потоком. Второй - понимание - концептуально рассматривайте его как высшую функцию последовательности и функцию f , которую нужно выполнить для каждого ее элемента, который возвращает другую последовательность f (элемент) с. Java for
- это утверждение, оно ни к чему не приводит, Clojure for
(как и все остальное в Clojure) - это выражение - оно вычисляется в последовательности f (element) s. .
Вероятно, самый простой способ получить идею - поиграть с библиотекой функций последовательности: http://clojure.org/sequences. Кроме того, вы можете решить некоторые проблемы на http://www.4clojure.com/. Первые проблемы очень просты, но постепенно они усложняются по мере прохождения через них.
* Как показано в ответе Александра, решение проблемы на самом деле идиоматическое и довольно умное. Слава за это! :)