2009-06-03 4 views
8

Desidero scrivere un programma per trovare le radici dell'equazione quadratica in Schema. Ho usato LET per determinati attacchi.Utilizzo dello schema Let in

(define roots-with-let 
    (λ (a b c) 
    (let ((4ac (* 4 a c)) 
      (2a (* 2 a)) 
      (discriminant (sqrt (- (* b b) (4ac))))) 
     (cons (/ (+ (- b) discriminant) 2a) 
      (/ (- (- b) discriminant) 2a))))) 

ho definito la discriminante con 4ac poiché non volevo (* 4 a c). Anche se ho definito (4ac (* 4 a c)), mi sta dando questo errore:

expand: unbound identifier in module in: 4ac .

mia domanda è come si lascia valutato (quale ordine)? E se voglio 4ac nel mio let dovrei scrivere un altro interno let? C'è un modo migliore per farlo?

+1

Questo è un esempio di SICP Lecture/Book! – Nishant

risposta

27

Utilizzare let* anziché let.

La differenza tra let e let* è la seguente:

let* lega le variabili da sinistra a destra. Le associazioni precedenti possono essere utilizzate in nuovi rilegature più a destra (o in basso).

let d'altra parte può essere pensato di zucchero come sintattico (o macro) per semplice astrazione lambda:

(let ((a exp1) 
     (b exp2)) 
    exp) 

è equivalente a

((lambda (a b) 
    exp) 
exp1 exp2) 
+1

Potresti commentare la differenza dell'ordine di valutazione tra i due? – unj2

+0

http://www.r6rs.org/final/html/r6rs/r6rs-Z-H-14.html#node_sec_11.4.6 – Javier

+2

non è (solo) sull'ordine di valutazione, è principalmente sull'ambito. in plain, l'ambito di ogni variabile è solo l'espressione, non i binding. in let *, l'ambito di ciascuna variabile è l'espressione e ogni legame dopo se stesso. – Javier

3

Avrete bisogno di un special let-construct (let*) qui poiché le variabili all'interno della let-definition si riferiscono l'una all'altra.

'piuttosto un problema di definire una portata che di valutazione di un'espressione (in usuale let -definizioni, l'ordine di valutazione non importa quanto i valori non possono utilizzare l'altro)

8
  • 4ac è una variabile con un valore numerico, quindi (4ac) non è significativa.

  • LET lega tutte le variabili, ma le variabili non possono essere utilizzate nei calcoli per i valori.

Questo non funziona:

(let ((a 1) (b 1) (c (* a b))) 
    c) 

Usa:

(let ((a 1) (b 1)) 
    (let ((c (* a b))) 
    c)) 

Sopra introduce A e B con il primo LET. Nel secondo LET sia A che B ora può essere utilizzato per calcolare C.

Oppure:

(let* ((a 1) (b 1) (c (* a b))) 
    c) 
2

Quando si utilizza lasciare, le associazioni non sono visibili in nessuno dei corpi. Usare let * invece e vedere i documenti RNRS per i dettagli.