2012-06-15 25 views
5
(define get-first 
    (lambda (l) 
    (call-with-current-continuation 
     (lambda (here) 
     (set! leave here) 
     (waddle l) 
     (leave (quote())))))) 

(define get-first 
    (lambda (l) 
    (call-with-current-continuation 
     (lambda (here) 
     (set! leave here) 
     (leave (waddle l)))))) 

Para alguien no familiarizado con el libro "El sazonado Schemer", get-first, get-next y waddle (últimos dos no se definen aquí) Los procedimientos son a parecer modelo corutinas para iterar a través de un árbol pasado a waddle que cede hojas solamente. Justo antes de rendimiento waddle 's en su segunda a la última re-entrada, que establece el punto de reingreso a donde se va solamente siempre devolver el valor puro '() es decir, en lugar de ceder '(), la valor real de waddlees'(), como si fuera una función pura desde el principio.sazonado Schemer, conseguir-siguiente, y funciones waddle

Con esto en mente, podemos ver lo que get-first conjuntos de hasta ... cuando waddle retornos "de verdad", que será dentro de la call/cc en get-first y luego (leave (quote())) es el valor de get-first (y, a su vez, esta leave está destinado a volver a get-next en la última iteración, por lo tanto, es get-next que realiza el retorno "real" de '()).

¿Por qué es la segunda versión no es equivalente, donde el valor de '()waddle 's sería el argumento para leave?

+0

No importa ... la confusión se debe a que "dejar" no es la función que * quiero * que sea, sino la función a la que evalúa cuando se evalúa, que parece ser de izquierda a derecha y por lo tanto antes de "andar ". Eso significa que evalúa a lo que se acaba de establecer en la declaración anterior. Moral: ¡tenga cuidado al usar funciones que están sujetas a redefinir DENTRO de la llamada a la función! Si se tratara de un intérprete de derecha a izquierda, el waddle se evaluaría antes de buscar el permiso del símbolo como la función que se deja en cualquier lugar, durante ese tiempo se establecería en una función DIFERENTE. Qué desorden ... – user1457584

+2

Me alegra saber que está resuelto, pero publique la resolución como una respuesta (en lugar de un comentario aquí) y acéptelo. De esa forma la gente puede ver que la pregunta se resuelve sin entrar aquí. – Bridge

+0

@ user1457584 Ambas versiones no compilarán: 'set !: unbound identifier in module in: leave' – alfasin

Respuesta

3

La confusión se debe a que "leave" no es la función que queremos que sea, pero la función se evalúa como cuando Es evaluados, que parece ser de izquierda a derecha y de esta manera antes "waddle". Eso significa que evalúa a lo que se acaba de configurar, en la declaración anterior.

Moral: tenga cuidado al usar las funciones que están sujetas a redefinir DENTRO de la llamada a la función! Si se tratara de un intérprete de derecha a izquierda, se evaluaría waddle antes de buscar el símbolo leave como la función que "deja" en cualquier lugar, durante ese tiempo se establecería en una función DIFERENTE.

+2

Debe marcar su pregunta respondida, aunque haya escrito la respuesta. De lo contrario, aparece en la lista sin respuesta. –