бесконечный цикл в функциональном программировании?

  • Мне было интересно: можно ли делать бесконечные циклы в функциональном программировании?

Пример: при использовании Windows API для получения сообщений Windows это обычно реализуется в цикле.

Я знаю, что можно создать функцию, которая будет продолжать рекурсию бесконечно. Я ожидаю, что это приведет к переполнению стека.

  • бесконечный цикл - неправильный образ мышления для функционального программирования?

  • проблема в интерфейсе операционной системы или в оборудовании?

мне это не кажется функциональной программой / o.s. мог продолжать работать сам по себе

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


person symbiont    schedule 14.08.2010    source источник
comment
Попробуйте погуглить "хвостовая рекурсия".   -  person sje397    schedule 14.08.2010
comment
спасибо за ваш вклад всем   -  person symbiont    schedule 15.08.2010


Ответы (4)


Как уже писали другие, бесконечный цикл возможен через хвостовые рекурсии .

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

let loop() = do {
  println("foo")
  loop()
}

Но

бесконечный цикл - неправильный образ мышления для функционального программирования?

все еще есть точка. Рассмотрим ваш пример Windows-API с бесконечным циклом. Это совсем не функционально. Помните - функциональность означает мышление в ценностяхв том, что они означают). Следовательно, предпочтительнее использовать реактивный / событийный подход, подобный этому [Псевдофункциональный код]

  (onClick form1)
|> Event.subscribe (\pt-> do { print $ "I was clicked at " ++ (show pt) })

So

мне это не кажется функциональной программой / o.s. мог продолжать работать сам по себе

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

person Dario    schedule 14.08.2010
comment
интересный. Я не думал, что функциональное программирование может обойтись без бесконечных рекурсий (полезно знать). спасибо за информацию и ваши идеи. мне нравится идея реактивного программирования. - person symbiont; 15.08.2010
comment
В качестве примера того, почему вы бы это сделали: ядро ​​программы часто лучше всего представлено как потенциально бесконечная последовательность преобразований в состоянии мира (например, Pac-Man собирается съесть таблетку, Pac-Man - на один шаг впереди). и съел таблетку и т. д.). По моему опыту, это также наиболее частый случай бесконечных циклов. - person Chuck; 16.08.2010

Если вы используете хвостовую рекурсию, у вас фактически есть итерация, такая как цикл for / while. Следовательно, я думаю, у вас может быть бесконечный цикл без переполнения стека.

На ваш вопрос: «Неужели бесконечный цикл - неправильный образ мышления для функционального программирования?», возможно, это поможет: - Пока или хвостовая рекурсия в F #, что использовать и когда?

person JohnB    schedule 14.08.2010

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

Изменить. Я не хочу не соглашаться с другими ответами, но "бесконечные" хвостовые рекурсивные циклы - это обычная идиома для работы с внешним миром. Следующий пример взят из Real World Haskell и является представителем этой идиомы.

mainloop :: Handle -> Handle -> IO ()
mainloop inh outh = 
    do ineof <- hIsEOF inh
       if ineof
           then return ()
           else do inpStr <- hGetLine inh
                   hPutStrLn outh (map toUpper inpStr)
                   mainloop inh outh

По сути, мы рассматриваем внешний мир как поток.

person deinst    schedule 14.08.2010

Большинство, если не все виды использования «бесконечных циклов» в функциональном программировании можно смоделировать с помощью совместной рекурсии . Другие ответы до сих пор указывали на общую рекурсию, но неограниченное использование рекурсии, возможно, является плохим подходом, поскольку может привести к плохо структурированному коду.

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

person func    schedule 16.08.2010