Смотрите, если часть данных ленивый в clojure - PullRequest
4 голосов
/ 29 марта 2012

Есть ли в clojure функция, которая проверяет, содержат ли данные какую-то ленивую часть?

Фон:

Я создаю небольшой сервер в clojure.Каждое соединение имеет состояние, входной поток и выходной поток

Сервер считывает байт из входного потока и на основании значения вызывает одну из нескольких функций (с состоянием и входом ивыходной поток в качестве параметров).Функции могут решить прочитать больше из входного потока, написать ответ в выходной поток и вернуть состояние.Эта часть зацикливается.

Все будет работать нормально, если в состоянии нет ленивых частей.Если в состоянии есть какая-то ленивая часть, которая может, когда она будет оценена (позже, во время другой функции), начать чтение из потока ввода и запись в поток вывода.

Так что в основном я хочудобавить постусловие ко всем этим функциям, заявив, что никакая часть возвращаемого состояния не может быть ленивой.Есть ли функция, которая проверяет ленивые последовательности.Я думаю, было бы легко проверить, является ли само состояние ленивой последовательностью, но я хочу, например, проверить, есть ли у состояния вектор, который содержит хэш-карту, одно из значений которой является ленивым.

Ответы [ 2 ]

3 голосов
/ 29 марта 2012

легче гарантировать, что он не ленится, форсируя оценку с помощью doall

У меня была эта проблема в криптографическом приложении потоковой обработки пару лет назад и пробовал несколько способов, пока я наконец не принялмоя ленивая сторона и обернула входные потоки в ленивую последовательность, которая закрывалась во входных потоках, когда больше не было данных.эффективно отделить заботу о закрытии потоков от заботы о том, что содержали потоки.Состояние, которое вы отслеживаете, звучит немного сложнее, чем открытое или закрытое, хотя вы можете разделить его аналогичным образом.

1 голос
/ 29 марта 2012

Вы можете, конечно, форсировать оценку с doall , как мудро предлагает Артер.

Однако я бы порекомендовал вместо этого рефакторинг, чтобы решить реальную проблему, заключающуюся в том, что у вашей функции-обработчика есть побочные эффекты (чтение с ввода, запись с вывода).

Вместо этого вы могли бы превратить это в чистую функцию, если бы вы сделали следующее:

  • Обернуть входной поток в ленивую последовательность
  • использовать [состояние последовательности ввода] в качестве входных данных для вашей функции обработчика
  • использовать [list-of-write новое состояние rest-of-input-sequence] в качестве вывода, где список записей - это то, что должно быть впоследствии записано в выходной поток

Если вы сделаете это, ваша функция-обработчик будет чистой, вам просто нужно запустить ее в простом цикле (отправка списка записей в выходной поток на каждой итерации), пока не будут использованы все входные данные и / или некоторые другие условие завершения достигнуто.

...