Pregunta

El siguiente procedimiento es válido en ambas R6RS esquema y raqueta:

;; create a list of all the numbers from 1 to n
(define (make-nums n)
  (do [(x n (- x 1)) (lst (list) (cons x lst))]
    ((= x 0)
     lst)))

Lo he probado tanto para R6RS y raqueta y funciona correctamente, pero sólo se sabe que con seguridad para DrRacket.

Mi pregunta es si es garantizada que las expresiones de paso ((- x 1) y (cons x lst) en este caso) serán evaluadas en orden. Si no se garantiza, a continuación, mi procedimiento no es muy estable.

No he visto nada especificar esto en los estándares para uno u otro idioma, pero yo estoy pidiendo aquí porque cuando lo probé fue evaulated en orden.

¿Fue útil?

Solución

Están generalmente no garantiza que sea evaluado con el fin, pero el resultado seguirá siendo el mismo. Esto se debe a que no hay efectos secundarios aquí -. El bucle no cambia x o lst, sólo se les vuelve a vincular a nuevos valores, por lo que el orden en el que se evalúan las dos expresiones paso es irrelevante

Para ver esto, comenzar con una versión más limpia de aspecto de su código:

(define (make-nums n)
  (do ([x n (- x 1)] [lst null (cons x lst)])
      [(zero? x) lst]))

traducirá en una let llamado:

(define (make-nums n)
  (let loop ([x n] [lst null])
    (if (zero? x)
      lst
      (loop (- x 1) (cons x lst)))))

y, además, que se traduce a una función de ayuda (que es lo que realmente es un llamado let):

(define (make-nums n)
  (define (loop x lst)
    (if (zero? x)
      lst
      (loop (- x 1) (cons x lst))))
  (loop n null))

Debe quedar claro ahora que el fin de evaluar las dos expresiones de la llamada recursiva loop no lo hace hacer nada diferente.

Por último, cabe destacar que en la evaluación de la raqueta es garantiza que sea de izquierda a derecha. Esto es importante cuando hay efectos secundarios - Raqueta prefiere un comportamiento predecible, mientras que otros se oponen a ella, alegando que esto lleva a la gente a código que implícitamente se basa en esto. Un pequeño ejemplo común que muestra la diferencia es:

(list (read-line) (read-line))

en el que la raqueta está garantizado para devolver una lista de la primera línea de lectura, y luego el segundo. Otras implementaciones podrían volver las dos líneas en un orden diferente.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top