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

È stato utile?

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)) ) ))
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top