я увидел следующий пример в видео Рича на последовательностях http://blip.tv/file/734409 около 33-36 минут в него:Об исполнении `first` функции Clojure в
(first "abcd") => \a
Теперь он говорит, что это расширяется (вроде):
(first "abcd") => (first (seq "abcd")) => (first '(\a \b \c \d))
Таким образом, это выглядит как O(N)
операции, так как полная копия строки делается. Прежде всего, если значение String
является неизменным, то почему оно копируется? (Редактирование: на основе ответа, вероятно, это не так, просто выглядели так, когда печатались.) Во-вторых, предположим, что first
работает на чем-то другом в Java, который изменен, скажем, связанный список целых чисел. Должно ли first
действовать ленивым способом (например, сначала создать постоянную последовательность)? Разве это не имеет смысла оценивать это сразу и сохранять его? Это был бы какой-то хак, который сломал бы хорошую абстракцию, но, я думаю, быстро проделайте эту работу. Когда вы вызываете (seq "abcd")
, вы не знаете, как он будет использоваться. Когда вы вызываете first
на seq
, вы знаете, что делать. Но, когда вы вызываете first
на "abcd"
, я думаю, что выполнение хакерских и быстрых «захватов и сохранения», подход лучше, чем захватить последовательность, а затем позвонить first
.
Я что-то упустил? Разве Рик Хики пропустил несколько шагов?
Дайте мне знать, если у меня есть вопросы. Благодаря!
Спасибо, какой-нибудь дополнительный ввод при работе с изменяемыми объектами Java, которые можно превратить в последовательность? –
IIRC, вызывающий seq возвращает ленивую последовательность Clojure, поддерживаемую итератором Java по коллекции. Так как ленивая последовательность реализуется, она должна следовать всем правилам, которые относятся к итераторам (насколько мутирует базовый объект). Однако, когда это было реализовано, это неизменная последовательность Clojure. – levand
@Hamish - если вы хотите превратить изменяемый объект Java в последовательность, тогда вам нужно либо сделать защитную копию с стоимостью O (n), либо риск того, что базовые данные могут быть изменены (что нарушит нормальные ожидания seq поведение и, возможно, вызывают тонкие ошибки). Первый подход (копирование), вероятно, предпочтительнее, последний очень опасен, если вы абсолютно не уверены, что ничего не изменится в неподходящий момент. – mikera