Pregunta
estoy aprendiendo SICP ahora y hacer lo ex2.23 he wrirten el siguiente código:
(define (for-each proc items)
(if (null? items)
#t
((proc (car items))
(for-each proc (cdr items)))))
pero cuando se ejecuta, la causa del error: aplicación de procedimiento: procedimiento de esperar, dada: #; argumentos fueron: ()
Creo que sé la razón: me llamo para-cada función recursiva, cada llamada para-cada uno quería valor de retorno
pero cuando he modificado el código:
(define (for-each proc items)
(cond ((null? items) #t)
(else (proc (car items)) (for-each proc (cdr items)))))
funciona bien. No entiendo, ¿por qué? en cond , no todos los llamados fines de cada uno hay necesidad de valor de retorno?
i utilizado DrScheme, y elegir el lenguaje SICP
No soy un hablante nativo de Inglés, así que si hay algo que no se describe con claridad, los pls me dicen
Solución
pero cuando se ejecuta, la causa del error: aplicación de procedimiento: se espera> procedimiento, teniendo en cuenta: #; argumentos fueron: ()
Creo que sé la razón: me llamo para-cada función recursiva,> cada llamada para-cada uno quería volver valor
No, es porque en la cláusula alternativa de if
usted tiene la ((proc (car items)) (for-each proc (cdr items)))
combinación. Que la intención de evaluar la (proc (car items))
dos combinaciones y (for-each proc (cdr items))
secuencialmente, y con ese fin que pensó ponerlos en otro par de paréntesis trabajarían. Pero en realidad, lo que se ha especificado es que el resultado de (proc (car items))
es un procedimiento que se aplicará para el argumento de que es el valor de retorno de (for-each proc (cdr items))
. Este no es el caso, y se obtiene un error. El punto clave es que los paréntesis en Lisp no son para agrupar, pero tiene un significado definido.
El problema es que if
sólo puede tener una sola combinación en esa posición, mientras que usted quiere tener dos seguidas. Por otro lado, cond
no sufre tal restricción; usted puede poner siempre una secuencia de combinaciones individuales de la parte consecuente de una cláusula cond
como su corazón desea. Este estado de cosas es simplemente cómo el lenguaje se define al trabajo.
Sólo así puede usar cond
en estas situaciones, pero si aún desea utilizar if
hay algunas opciones para el relleno de múltiples combinaciones en una sola. P.ej. puede crear un procedimiento lambda cuyo cuerpo es las dos combinaciones e inmediatamente disparar si fuera poco:
(define (for-each proc items) (if (null? items) #t ((lambda () (proc (car items)) (for-each proc (cdr items)) )) ))
o puede utilizar begin
que en realidad está destinado a ser utilizado para tal propósito:
(define (for-each proc items) (if (null? items) #t (begin (proc (car items)) (for-each proc (cdr items)) ) ))