2009-06-03 4 views
8

Scheme에서 2 차 방정식의 근원을 찾기위한 프로그램을 작성하고 싶습니다. 특정 바인딩에 대해서는 LET을 사용했습니다. 내가 (* 4 a c)을하지 않았기 때문에 Scheme에서 Letter 사용하기

(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))))) 

나는 4ac으로 판별을 정의했다.

expand: unbound identifier in module in: 4ac .

내 질문 평가 (어떤 순서로)하게하는 방법이다 : 나는 (4ac (* 4 a c))을 정의하더라도, 그것은 나에게이 오류를주고있다? 그리고 만약 내가 내 let4ac을 원한다면 또 다른 내면 let을 작성해야합니까? 이 작업을 수행하는 더 좋은 방법이 있습니까?

+1

이것은 SICP Lecture/Book의 예입니다! – Nishant

답변

27

let 대신 let*을 사용하십시오.

let*는 왼쪽에서 오른쪽으로 변수를 바인드

letlet*과의 차이는 다음과 같다. 이전 바인딩은 새로운 바인딩에서 오른쪽으로 (또는 아래로) 더 사용될 수 있습니다. 반면에

let

간단한 람다 추상화와 같은 문법 설탕 (또는 매크로) 생각할 수 있습니다 :

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

당신은 special let-construct (let*이 필요합니다

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

둘 사이의 평가 순서 차이점에 대해 의견을주십시오. – unj2

+0

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

+2

평가 순서에 관한 것이 아니라 (대부분) 범위에 관한 것입니다. 일반 let에서 모든 변수의 범위는 바인딩이 아니라 표현식입니다. let *에서 각 변수의 범위는 표현식과 그 이후의 모든 바인딩입니다. – Javier

3

에 해당) 여기서 let-definition 안의 변수들은 서로를 참조하기 때문이다.

오히려 표현식 평가보다 범위를 정의하는 문제이다 (통상 let -definitions하여, 값이 서로를 사용할 수 있기 때문에 중요하지 않다 평가 순서는)

8
  • 4ac은 숫자 값을 가진 변수이므로 (4ac)는 의미가 없습니다.

  • LET는 모든 변수를 바인드하지만 변수 값을 계산할 때 사용할 수 없습니다.

이 작동하지 않습니다

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

사용 :

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

위는 소개하고 B 처음 LET와 함께. 두 번째에서 모두를하자 B는 이제

또는 C.

을 계산하는 데 사용할 수 있습니다

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

당신이 사용하는 경우하자, 바인딩은 몸의에 표시되지 않습니다. 대신 let *을 사용하고 자세한 내용은 RNRS 문서를 참조하십시오.