2007년 12월 12일 수요일

Continuation

continuation이란 미래에 될 computation 과정을 얼려놓은 것을 말한다. 프로그램의 실행 도중에 이 지점 이후에 실행될 과정을 모조리 얼려놓은 객체랄까? 다음 예를 보자.

(+ 1 (call/cc
(lambda (k)
(+ 2 (k 3)))))

=> 4

call-with-current-continuation, 줄여서 call/cc라고 하는 오퍼레이터는 '인자가 하나인 함수'를 인자로 받는다. call/cc를 호출하게 되면 call/cc가 호출된 지점을 제외한 '나머지 부분'이 call/cc의 인자로 넘겨진다. 즉 lambda의 인자 k에는 프로그램에서 call/cc를 제외한 나머지 부분인 (+ 1 ~~) 라고 하는 계산 과정이 저장되게 된다(이 저장된 객체를 continuation이라고 한다). (k 3) 이 평가되면 3이 저 ~~ 자리에 들어가서 이 코드의 실행 결과는 4가 된다. (+ 2 부분이 무시되는 이유는 continuation이 저장된 시점의 스택 상태에서 계산이 되기 때문이다.

다른 예를 보자.

(define r #f)

(+ 1 (call/cc
(lambda (k)
(set! r k)
(+ 2 (k 3)))))

=> 4

(r 5)

=> 6

(+ 3 (r 5))

=> 6

여기서는 (+ 1 ~~) 라는 continuation 객체를 r 이라는 변수에 저장하였다. 따라서 (r 5) 가 평가될 때 r은 (+ 1 ~~) 이고 머시기 자리에 5가 들어가기 때문에 평가한 결과는 6이 된다.

continuation 은 scheme에서 처음으로 일급 객체(자료구조에 저장될 수 있고, 함수의 인자나 리턴 값이 될 수 있는 객체)로 제공하기 시작한 것 같다. 예에서 본 바와 같이, 제어 흐름을 특정 시점의 스택으로 돌려놓기 때문에 루프에서 탈출하는 오퍼레이터를 만들거나 할 때 쓰인다고 한다.

하지만 이 개념이 각광을 받는 부문은 웹 개발 쪽인 것 같다. 연산 과정 중 임의의 포인트를 저장할 수 있다는 특성을 이용해서 HTTP의 상태 없음을 극복해 보겠다는 것인데, session이나 cookie 같은 경우는 디자이너가 어떤 식으로 상태를 저장하고 관리해야 할지 설계해야하는 반면에 continuation은 완전히 arbitrary한 포인트들을 저장할 수 있고, 상태 저장을 단순한 문제로 바꾼다는 것 같다. 2001년도부터 2007년까지 ICFP(International Conference on Functional Programming - ACM 쪽이다)쪽에 continuation을 이용한 웹 개발의 장점들에 대해 논하는 논문들이 실려왔다.

continuation을 이용하는 시스템들은 다음과 같다.

Yahoo! Store, PLT Scheme Web Server, Uncommon Web framework and Weblocks Web framework(for Common Lisp), Seaside Web Server(for Smalltalk), Apache Cocoon Web application framework

주로, lisp을 사용하는 소프트웨어들이다. 커먼 리습에서 continuation을 일급 객체로 지원하진 않는 것 같지만 Paul Graham의 On Lisp 20장을 읽어보면 클로저와 매크로를 이용해서 continuation을 구현하는 것을 코드로 보이고 있다. 루비도 continuation을 지원하긴 하던데, 레일스는 continuation 기반 상태 저장을 지원하는지 잘 모르겠다.

References

Teach Yourself Scheme in Fixnum Days의 call-with-current-continuation
Wikipedia - continuation
Paul Graham의 On Lisp - chapter 20에 자세한 설명이 나와 있다

댓글 없음: