Por alguna razón, estoy teniendo problemas para pensar en una buena forma de reescribir esta función, así que usa un espacio de pila constante. La mayoría de las discusiones en línea sobre la recurrencia de árboles hacen trampa al usar la función de Fibonacci y explotar las propiedades de ese problema en particular. ¿Alguien tiene alguna idea para este uso del "mundo real" (bueno, más del mundo real que la serie de Fibonacci) de la recursión?¿Cuál es una buena manera de reescribir esta función no recursiva?
Clojure es un caso interesante ya que no tiene la optimización de la cola de llamadas, sino que solo se repite la cola a través del formulario especial "recurrir". También desaconseja fuertemente el uso del estado mutable. Tiene muchas construcciones perezosas que incluyen tree-seq, pero no puedo ver cómo pueden ayudarme en este caso. ¿Alguien puede compartir algunas técnicas que han recogido de C, Scheme, Haskell u otros lenguajes de programación?
(defn flatten [x]
(let [type (:type x)]
(cond (or (= type :NIL) (= type :TEXT))
x
(= type :CONCAT)
(doc-concat (flatten (:doc1 x))
(flatten (:doc2 x)))
(= type :NEST)
(doc-nest (:level x)
(flatten (:doc x)))
(= type :LINE)
(doc-text " ")
(= type :UNION)
(recur (:doc1 x)))))
edición: Por petición en los comentarios ...
reformulado en términos generales y usando Esquema - ¿cómo puedo volver a escribir el siguiente patrón de recurrencia por lo que no consume espacio de pila ni requiere cola- ¿Optimización de llamada de llamadas no auto?
(define (frob x)
(cond ((foo? x)
x)
((bar? x)
(macerate (f x) (frob (g x))))
((thud? x)
(frobnicate (frob (g x))
(frob (h x))))))
me eligieron nombres molestos para llevar a casa el punto de que estoy en busca de respuestas que no se basan en las propiedades algebraicas de x, maceran, zorglub, f, g, h o. Solo quiero reescribir la recursión.
ACTUALIZACIÓN:
Rich Hickey ha añadido amablemente una explícita trampoline function a Clojure.
yo diría "C++", pero eso sería inútil ;-) –
que sería más fácil para ayudar si se le explica lo que hace la función de hacer. tal vez también usando un dialecto LISP más común, me gusta usar Scheme en casa, pero realmente no me gusta el aspecto de clojure – Javier
Agregué una versión Scheme de la pregunta, pero dudo que sea de mucha ayuda para usted. :) –