2012-02-16 4 views
2

체계에서 루프가 작동하는 방식을 이해하는 데 어려움이 있습니다. 이 코드는 실행되지만 특히for 루프는 어떻게 작동합니까?

(define (bubblesort alist) 
    ;; this is straightforward 
    (define (swap-pass alist) 
    (if (eq? (length alist) 1) 
     alist 
     (let ((fst (car alist)) (scnd (cadr alist)) (rest (cddr alist))) 
      (if (> fst scnd) 
       (cons scnd (swap-pass (cons fst rest))) 
       (cons fst (swap-pass (cons scnd rest))))))) 
    ; this is mysterious--what does the 'for' in the next line do? 
    (let for ((times (length alist)) 
      (val alist)) 
    (if (> times 1) 
     (for (- times 1) (swap-pass val)) 
     (swap-pass val)))) 

내가 (let for ((가 여기서 할 예정이다 알아낼 수없는 이유를 모르겠어요, 그리고 마지막 줄에 두 번째의 for 표현도 넣어 조금 떨어져있다 - 저는 통역사가 for이 단 하나의 논점만을 취하고 있다고 불평했지만, 여기에는 두 가지가 있습니다.

여기에 무슨 일이 일어나고 있는지에 대한 의견이 있으십니까?

답변

11

그건 for 루프가 아니에요. 그 이름은 let입니다. 함수는 for이라는 함수를 만든 다음 호출합니다. "루핑"동작은 함수의 재귀에 의해 발생합니다. loop 함수를 호출하는 것이 더 관용적이며, btw입니다. 예 :

(let loop ((times 10)) 
    (if (= times 0) 
    (display "stopped") 
    (begin (display "still looping...") 
      (loop (- times 1))))) 

이 실제로 for 언어 기능을 사용하지만, 당신이 쉽게 재귀 함수를 작성 할 수 있습니다 let의 변형을 사용하지 않는

(letrec ((loop (lambda (times) 
       (if (= times 0) 
        (display "stopped") 
        (begin (display "still looping...") 
          (loop (- times 1))))))) 
    (loop 10)) 
+0

많은 감사의 말로 설명 된대로 let이라는 이름이 확장되었습니다. 지금은 나에게 훨씬 더 의미가 있습니다. –

5

같은 것을 확대됩니다. let에 관한 this 문서를 참조하십시오 (두 번째 형식입니다).

무슨 일인지는이 let 형태가, 지정된 인수 목록 (timesval)과 절차 (이 경우 for에서)이 전달되는 이름을 결합하여 초기 값을 호출하는 것입니다. 본문에서 바운드 이름을 사용하는 것은 재귀 호출입니다.

결론 : for은 여기에 중요하지 않습니다. 그것은 단지 이름입니다. 이름을 foo으로 바꿀 수 있으며 여전히 작동합니다. Racket은 대략 here에 대한 실제 루프를 가지고 있습니다.

관련 문제