2012-10-03 5 views
1

표현식 (call/cc (lambda (k) (k 12)))에는 세 개의 연속이 있습니다. (k 12), (lambda (k) (k 12))(call/cc (lambda (k) (k 12)))입니다. 어느 것이 현재의 연속인가?다음 표현식에서 현재 계속되는 것은 어느 것입니까?

일부 책의 연속성은 값을 기다리는 절차로 간주되며 값에 적용되면 즉시 반환됩니다. 그게 맞습니까?

현재 진행중인 내용을 자세히 설명 할 수 있습니까?

답변

2

같은 내용은 (k 12)과 관련되지 않습니다. 더 큰 프로그램에는 각 하위 표현식과 관련된 계속이 있습니다. 예를 들어 x의 연속은 (* 3 (+ x 42))이고 (lambda (_) (* 3 (+ _ 42)))입니다.

예에서 "현재 연속"은 (call/cc (lambda (k) (k 12)))이며 그 표현을 둘러싼 모든 것이됩니다.당신이 방금 프롬프트에 입력 한 경우, 그것을 둘러싸고 아무것도 없다, 그래서 "현재의 연속"은 단순히 (lambda (_) _)입니다. (* 3 (+ (call/cc (lambda (k) (k 12))) 42))과 같이 입력하면 계속은 (lambda (_) (* 3 (+ _ 42)))입니다.

"현재 연속"을 나타내는 데 사용 된 람다가 call/cc이 전달하는 이름 (예 : k)과 다릅니다. k에는 현재 연속을 평가 한 후 나머지 계산을 중단하는 특별한 제어 효과가 있습니다.

1

이 경우 계속은 call/cc 호출의 반환 값을받는 "것"입니다. 따라서 :

(display (call/cc (lambda (k) (k 12))) 

는 계획에

(display 12) 

Continuations를 같은 결과가 "모양과 느낌"절차처럼,하지만 그들은 실제로 절차처럼 행동하지 않습니다. 지속성을 더 잘 이해하는 데 도움이되는 한 가지 방법은 CPS 변환입니다.


CPS 변환에서 값을 반환하는 대신 대신 continuation 매개 변수를 사용하고 결과와 함께 연속을 호출합니다. 따라서 CPS로 변환 된 sqrt 함수는 (sqrt 64 k)으로 호출되고 8을 반환하는 대신 tail 위치에 (k 8)을 호출합니다.

연속 (CPS 변환 기능에서)이 꼬리로 호출되므로이 함수는 연속 반환에 대해 걱정할 필요가 없으며 사실 대부분의 경우 반환 할 것으로 예상되지 않습니다. 이것을 염두

여기 함수의 간단한 예이다 :

(define (hypot x y) 
    (sqrt (+ (* x x) (* y y)))) 

및 CPS-변형 버전 :

(define (hypot x y k) 
    (* x x (lambda (x2) 
      (* y y (lambda (y2) 
        (+ x2 y2 (lambda (sum) 
           (sqrt sum k)))))))) 

(*+, 그리고 sqrt 모든되었다고 가정 계속 논증을 수용하기 위해 CPS 변환 됨). 그래서 지금


, 흥미로운 부분 : call/cc 이해하기 쉽고 구현하기 쉽고, CPS 변환으로

(define (call/cc fn k) 
    (fn k k)) 

하십시오 call/cc CPS-변화는 다음과 같이 정의되어있다. CPS 변환이 없다면, call/cc은 (예를 들어, 스택 복사 등을 통해) 매우 마법적인 구현이 필요할 것입니다.