2017-09-11 15 views
-1

MIT의 SICP 강의를 따르고 있으며 알렉산드리아 방법의 헤론에 의해 수의 제곱근 근사값을 찾으려고했습니다. 이것은 처음으로 lisp을 시도한 것이고, noobie 실수를해서 죄송합니다.오류 : (/) 잘못된 인수 유형 : # <unspecified> 치킨 구성표 제곱근 근사값

(define guess 1) 

(define (avg a b) 
    (/ (+ a b) 2)) 

(define (try guess x) 
    (if (goodEnough guess x) 
     guess 
     (improve guess x))) 

(define (improve guess x) 
    (define guess (avg guess (/ x guess))) 
    (try guess x) 
) 

(define (goodEnough guess x) 
    (= guess (avg guess (/ x guess)))) 

(print (try 1 25)) 

저는 이것을 인쇄하기 위해 치킨 계획 컴파일러를 사용하고 있습니다. 업데이트

Error: (/) bad argument type: #<unspecified> 

    Call history: 

    1.a.SquareRootApproximation.scm:29: try 
    1.a.SquareRootApproximation.scm:17: goodEnough  
    1.a.SquareRootApproximation.scm:27: avg 
    1.a.SquareRootApproximation.scm:19: improve  <-- 

: 이것은 출력 좀 더 추상화 혀짤배기를 사용하여이 문제를 향해 내 방식을 변경, 그러나 나는이 새로운 오류가 의미하는 무엇을 원하는지 알아낼 수 없습니다. 모든 수정 사항? 감사!

답변

1

#<unspecified>은 기본적으로 다른 언어에서는 "무효"입니다. 어떤 프로시져가 반환하는데 아무 도움이 없을 때마다 리턴 값으로 사용됩니다 (예 : print이 리턴합니다). 또한 일부 상황에서 임시 자리 표시 자 값으로 사용됩니다 (예 : 내부를 처리 할 때 define).

일반적으로이 임시 자리 표시자는 언어 사용자에게 표시되어서는 안되지만 언어의 이상한 경우를 나타냅니다 (축하합니다! 거의 발생하지 않음). improve 절차의 (define guess (avg guess (/ x guess)))이 동시에 변수를 정의하고 해당 변수를 사용하기 때문에 오류가 발생합니다. 이를 수행하는 동작은 잘 정의되어 있지 않으며, 일부 스키마 구현은 CHICKEN이 수행하는 작업 (Guile, Gauche, Gambit)을 수행하지만 다른 것들은 다소 의미있는 오류 메시지 (MIT, Scheme48, Racket)를 제공합니다. 이것이 잘못 지정된 이유는 내부적으로 defineletrec으로 확장된다는 사실과 관련이 있습니다. 왜냐하면 상호 재귀 적 프로 시저를 정의 할 수 있기 때문입니다. 그러나 이는 약간의 문제를 만듭니다. 예를 들어 (define a b) (define b a)의 경우 어떻게해야합니까?

귀하의 의도는 절차의 입력으로 전달되는 오래된 추측 변수를 사용하는 것, 그래서 대신 define을 사용하는 당신은 (행동해야이 잘 지정 방법) guess에 대한 새 값을 바인딩 let을 사용할 수도 있고, new-guess과 같이 다른 이름을 사용하십시오.

+0

나는 아직 배우지 않았지만, 나는 아직 첫 번째 강의를하고있다. 어쩌면 새로운 추측이 올바른 방향입니다. 감사. 실제로 새로운 변수로 작업했습니다. –

+0

R5RS에서'람다 '(그리고 파생 된 형태)의'define'은'letrec'이 몸체 이전과 R6RS에서 평가되고 나중에'letrec *'인 것을 허용하지 않기 때문에 매우 잘 지정되어 있습니다 이미 초기화 된 변수를 평가할 수 있습니다. 물론 이들 중 어느 것도 동일한'lambda'에서 ** 어떤 ** 로컬'define'에 의해 그려진 변수를 평가할 수 없습니다. 'letrec'과'letrec * '는 재귀 함수를 만들 수 있도록 허용하는 것이므로 closure 생성시에 바인딩이 존재해야합니다. – Sylwester

+0

''형식에서 직접적으로 ''값을 참조하는 것은 "오류입니다"라는 의미에서 잘 지정되어 있습니다. 그러나 이것은 기본적으로 "구현은 원하는대로 자유롭게 수행 할 수 있습니다"라는 의미입니다. 본질적으로 C의 "정의되지 않은 동작"과 유사합니다. "오류입니다"라는 것이 사양을 벗어나면 이러한 오류를 일으키는 프로그램이 실행되거나 컴파일되지 않을 수 있습니다. 이 예제는 MIT, Racket 및 Scheme48이 CHICKEN, Guile, Gambit 및 Gauche와 매우 다른 방식으로 동작합니다. – sjamaan