Explicaciones de Racket / Scheme Flatten

¿Puede alguien ayudarme a desglosar exactamente el orden de ejecución para las siguientes versiones de aplanar? Estoy usando la raqueta.

¿La versión 1 es de la raqueta en sí misma, mientras que la versión dos es más común? implementación.

(define (flatten1 list)
  (let loop ([l list] [acc null])
    (printf "l = ~a acc = ~a\n" l acc)
    (cond [(null? l) acc]
          [(pair? l) (loop (car l) (loop (cdr l) acc))]
          [else (cons l acc)])))

(define (flatten2 l)
  (printf "l = ~a\n" l)
  (cond [(null? l) null]
        [(atom? l) (list l)]
        [else (append (flatten2 (car l)) (flatten2 (cdr l)))]))

Ahora, ejecutar el primer ejemplo con '(1 2 3) produce:

l = (1 2 3) acc = ()
l = (2 3) acc = ()
l = (3) acc = ()
l = () acc = ()
l = 3 acc = ()
l = 2 acc = (3)
l = 1 acc = (2 3)
'(1 2 3)

mientras que el segundo produce:

l = (1 2 3)
l = 1
l = (2 3)
l = 2
l = (3)
l = 3
l = ()
'(1 2 3)

El orden de ejecución parece diferente. En el primer ejemplo, parece que el segundo bucle(loop (cdr l) acc) se dispara antes del primer bucle, ya que '(2 3) se está imprimiendo de inmediato. Mientras que en el segundo ejemplo, 1 imprime antes de '(2 3), que parece que la primera llamada a aplanar dentro de apéndice se evalúa primero.

Estoy revisando el Little Schemer, pero estos son ejemplos más difíciles en los que realmente podría necesitar ayuda.

Muchas gracias.

Respuestas a la pregunta(2)

Su respuesta a la pregunta