Domanda
sto imparando SICP ora e fare l'ex2.23 Ho wrirten il seguente codice:
(define (for-each proc items)
(if (null? items)
#t
((proc (car items))
(for-each proc (cdr items)))))
, ma durante l'esecuzione, errore causa: applicazione procedura: procedura prevista, data: #; argomenti erano: ()
Credo di sapere il motivo: io chiamo per-ogni funzione in modo ricorsivo, ogni chiamato for-each voluto valore di ritorno
ma quando ho modificato il codice:
(define (for-each proc items)
(cond ((null? items) #t)
(else (proc (car items)) (for-each proc (cdr items)))))
funziona bene. Non capisco, perché? in cond , fa ogni chiamata for-each alcuna necessità di valore di ritorno?
ho usato DrScheme, e scegliere la lingua SICP
Io non sono un madrelingua inglese, quindi se c'è qlc che non viene descritta in modo chiaro, Pls mi dice
Soluzione
, ma durante l'esecuzione, la causa di errore: applicazione procedura: atteso> Procedura, data: #; argomenti erano: ()
Credo di sapere il motivo: io chiamo per-ogni funzione in modo ricorsivo,> ogni chiamata for-each voluto valore di ritorno
No, è perché nella clausola alternativa di if
avete la ((proc (car items)) (for-each proc (cdr items)))
combinazione. Si destinati a valutare la due combinazioni (proc (car items))
e (for-each proc (cdr items))
in sequenza, ea tal fine si pensava mettendoli in un altro paio di parentesi avrebbe funzionato. Ma in realtà, ciò che hai specificato è che il risultato di (proc (car items))
è una procedura da applicare alla tesi che è il valore di ritorno di (for-each proc (cdr items))
. Questo non è il caso, e si ottiene un errore. L'essere punto chiave che le parentesi in Lisp non sono per il raggruppamento, ma hanno un significato preciso.
Il problema è che if
può avere solo una singola combinazione in quella posizione, mentre si desidera avere due di fila. D'altra parte, cond
non soffre di una tale restrizione; si può mettere il più a lungo una sequenza di singole combinazioni nella conseguente parte di una clausola cond
come il tuo cuore desidera. Questo stato di cose è semplicemente come il linguaggio viene definito a lavorare.
Si può altrettanto bene usare cond
in queste situazioni, ma se si vuole ancora utilizzare if
ci sono alcune opzioni per l'imbottitura combinazioni multiple in una sola. Per esempio. è possibile creare una procedura di lambda il cui corpo è le due combinazioni e sparare via immediatamente:
(define (for-each proc items) (if (null? items) #t ((lambda () (proc (car items)) (for-each proc (cdr items)) )) ))
In alternativa è possibile utilizzare begin
che in realtà è destinato a essere utilizzato a tale scopo:
(define (for-each proc items) (if (null? items) #t (begin (proc (car items)) (for-each proc (cdr items)) ) ))