Информация об изменениях

Сообщение Re[2]: Смысл функционального программирования? от 08.05.2015 18:34

Изменено 08.05.2015 18:35 m.aksenov

Здравствуйте, alexis_ch, Вы писали:

_>У меня, кстати, есть вопрос к знатокам ФП:

_>Как в ФП-стиле грамотно (в смысле — красиво и эффективно) решить задачу вычисления трансцендентной функции разложением в ряд Тейлора (или иной бесконечный ряд) с заданной точностью? В императивном стиле алгогитм решения этой задачи сводится к одному циклу 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:

(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 с новыми значениями аргументов. Возможно, есть более красивое решение, но такое вполне в функциональном стиле.