Сообщение Re[2]: Смысл функционального программирования? от 08.05.2015 18:34
Изменено 08.05.2015 18:35 m.aksenov
Здравствуйте, alexis_ch, Вы писали:
_>У меня, кстати, есть вопрос к знатокам ФП:
_>Как в ФП-стиле грамотно (в смысле — красиво и эффективно) решить задачу вычисления трансцендентной функции разложением в ряд Тейлора (или иной бесконечный ряд) с заданной точностью? В императивном стиле алгогитм решения этой задачи сводится к одному циклу while — красиво, понятно, легко верифицируемо и эффективно с точки зрения расхода процессорного времени и памяти. А в функциональном стиле как?
_>Функции высшего порядка типа foldl тут не подходят, так как они представляют собой примитивно-рекурсивные функции (аналог цикла for в ), а вычисление ряда с заданной точностью — это уже частично рекурсивная функция!
Можно же просто сделать функцию с хвостовой рекурсией. Она дополнительно стек есть не будет. Вот, например на Clojure:
Т.к. JVM оптимизировать хвостовые вызовы не умеет, то используется конструкция loop. Ее можно считать функцией, потому что recur вызывает loop с новыми значениями аргументов. Возможно, есть более красивое решение, но такое вполне в функциональном стиле.
_>У меня, кстати, есть вопрос к знатокам ФП:
_>Как в ФП-стиле грамотно (в смысле — красиво и эффективно) решить задачу вычисления трансцендентной функции разложением в ряд Тейлора (или иной бесконечный ряд) с заданной точностью? В императивном стиле алгогитм решения этой задачи сводится к одному циклу while — красиво, понятно, легко верифицируемо и эффективно с точки зрения расхода процессорного времени и памяти. А в функциональном стиле как?
_>Функции высшего порядка типа foldl тут не подходят, так как они представляют собой примитивно-рекурсивные функции (аналог цикла for в ), а вычисление ряда с заданной точностью — это уже частично рекурсивная функция!
Можно же просто сделать функцию с хвостовой рекурсией. Она дополнительно стек есть не будет. Вот, например на Clojure:
(defn sint
[x eps]
(loop [term 1.0
sum 0.0
i 1]
(if-not (< term eps)
(let [t (* term (/ x i))]
(recur
t
(cond
(= (mod i 4) 1) (+ sum t)
(= (mod i 4) 3) (- sum t)
:else sum)
(inc i)))
sum)))Т.к. JVM оптимизировать хвостовые вызовы не умеет, то используется конструкция loop. Ее можно считать функцией, потому что recur вызывает loop с новыми значениями аргументов. Возможно, есть более красивое решение, но такое вполне в функциональном стиле.
Re[2]: Смысл функционального программирования?
Здравствуйте, alexis_ch, Вы писали:
_>У меня, кстати, есть вопрос к знатокам ФП:
_>Как в ФП-стиле грамотно (в смысле — красиво и эффективно) решить задачу вычисления трансцендентной функции разложением в ряд Тейлора (или иной бесконечный ряд) с заданной точностью? В императивном стиле алгогитм решения этой задачи сводится к одному циклу while — красиво, понятно, легко верифицируемо и эффективно с точки зрения расхода процессорного времени и памяти. А в функциональном стиле как?
_>Функции высшего порядка типа foldl тут не подходят, так как они представляют собой примитивно-рекурсивные функции (аналог цикла for в ), а вычисление ряда с заданной точностью — это уже частично рекурсивная функция!
Можно же просто сделать функцию с хвостовой рекурсией. Она дополнительно стек есть не будет. Вот, например на Clojure:
Т.к. JVM оптимизировать хвостовые вызовы не умеет, то используется конструкция loop. Ее можно считать функцией, потому что recur вызывает loop с новыми значениями аргументов. Возможно, есть более красивое решение, но такое вполне в функциональном стиле.
_>У меня, кстати, есть вопрос к знатокам ФП:
_>Как в ФП-стиле грамотно (в смысле — красиво и эффективно) решить задачу вычисления трансцендентной функции разложением в ряд Тейлора (или иной бесконечный ряд) с заданной точностью? В императивном стиле алгогитм решения этой задачи сводится к одному циклу while — красиво, понятно, легко верифицируемо и эффективно с точки зрения расхода процессорного времени и памяти. А в функциональном стиле как?
_>Функции высшего порядка типа foldl тут не подходят, так как они представляют собой примитивно-рекурсивные функции (аналог цикла for в ), а вычисление ряда с заданной точностью — это уже частично рекурсивная функция!
Можно же просто сделать функцию с хвостовой рекурсией. Она дополнительно стек есть не будет. Вот, например на Clojure:
(defn sint
[x eps]
(loop [term 1.0
sum 0.0
i 1]
(if-not (< term eps)
(let [t (* term (/ x i))]
(recur
t
(cond
(= (mod i 4) 1) (+ sum t)
(= (mod i 4) 3) (- sum t)
:else sum)
(inc i)))
sum)))Т.к. JVM оптимизировать хвостовые вызовы не умеет, то используется конструкция loop. Ее можно считать функцией, потому что recur вызывает loop с новыми значениями аргументов. Возможно, есть более красивое решение, но такое вполне в функциональном стиле.