Как решить «проблемы с состоянием» в Clojure? - PullRequest
1 голос
/ 13 октября 2019

Я новичок в clojure, и у меня возникают трудности с пониманием некоторых концепций, особенно чистых функций и неизменности.

Одна вещь, которую я до сих пор не могу понять, это то, как вы решаете проблему, подобную этой, вclojure:

Простое консольное приложение с методом входа в систему, где пользователь не может попытаться войти более 3 раз с интервалом в 1 минуту.

Например, в C # я мог бы добавитьUserId и метка времени для коллекции каждый раз, когда пользователь пытается войти в систему, тогда я бы проверил, было ли больше 3 попыток за последнюю минуту.

Как мне это сделать в Clojure, учитывая, что я не могу изменить свою коллекцию?

Это не практический вопрос (хотя некоторые примеры кода приветствуются), я хочу понять, каквы подходите к такой проблеме.

1 Ответ

5 голосов
/ 13 октября 2019

В большинстве случаев вы не изменяете объекты, вы создаете новые версии старых объектов:

(loop [attempt-dates []]
  (if (login-is-correct)
    (login)
    (recur (conj attempt-dates (current-date-stamp)))))

В этом случае я использую loop. Все, что я даю recur, будет передано следующей итерации loop. Я создаю новый список, который содержит новый штамп, когда я пишу (conj attempt-dates (current-date-stamp)), затем этот новый список передается на следующую итерацию loop.

Вот как это делается в большинстве случаев. Вместо того, чтобы думать об изменении объекта, подумайте о создании преобразованной копии объекта и передаче этой копии.

Если вам действительно действительно требуется изменяемое состояние, вы можете использовать изменяемый atom для хранениянеизменяемое состояние:

(def mut-state (atom []))

(swap! mut-state conj 1)

(println @mut-state)  ; Prints [1]

[] все еще остается неизменным, новая версия просто заменяет старую версию в изменяемом контейнере atom.

Если вам не нужно общатьсяхотя с обратными вызовами пользовательского интерфейса или чем-то подобным, вам обычно не нужна изменчивость. Попрактикуйтесь в использовании loop / recur и reduce.

...