Continuation Passing Style

14473 단어 JavaScriptJavaScript

Continuation-Passing Style

Intro

잠시 옆길로 새서 Continuation-passing style이라는 스타일을 살펴보려고 한다.

살펴보면서 중첩된 함수들을 읽기 편했던 개인적인 방법을 소개하려고 하는데, 궁금하지 않다면 다음 포스트로 넘어가도 무방할 것 같다.

Continuation-passing style은 간단히 말하면 모든 함수들을 콜백을 받도록 만드는 것이다. Javascript를 이용하여 direct style과 continuation-passing style을 서로 비교해보려고 한다.

예시

먼저 변수 선언은 다음과 같이 나타낼 수 있다.

// Direct style
const a = 1;
console.log(a); // 1

// Continuation-passing style
function lazyA(next) {
  return next(1);
}

lazyA((a) => console.log(a)); // 1

한 변수가 다른 변수의 결과를 참조할 때는 다음과 같이 사용한다.

// Direct style
const a = 1;
const b = a + 1;
console.log(b);

// Continuation-passing style
function lazyA(next) {
  return next(1);
}
function lazyB(next) {
  return lazyA((a) => {
    return next(a + 1);
  });
}
lazyB((b) => console.log(b)); // 2

개인적으로는 이렇게 읽는 것이 편했다.

function lazyB(next) { // lazyB는
  return lazyA((a) => { // lazyA의 결과를 a에 꺼내서
    return next(a + 1); // a + 1을 계산하여 반환한다.
  });
}
lazyB((b) => { // lazyB의 결과를 b에 꺼내서
  console.log(b); // console.log을 계산한다.
})

실행 순서를 보면

lazyB((b) => console.log(b))
=== lazyA((a) => { return console.log(a + 1); })
=== ((a) => { return console.log(a + 1); })(1) // lazyA 본문 수행
=== (console.log(1 + 1)) // lazyA의 결과 a = 1이 꺼내짐
=== (console.log(2)) // lazyB 본문 (a + 1) 수행, 결과 b = 2가 꺼내짐
=== undefined // console.log 수행, 2가 console에 출력

으로 읽었던 순서와 동일함을 알 수 있다.

함수도 변형시켜보자.

가장 간단한 상수함수의 경우 다음과 같다.

// Direct style
function constOne() { return 1; }

// Continuation-passing style
function lazyOne(next) {
  return next(1);
}

lazyOne((i) => console.log(i)); // 1

읽기 전용 변수 선언과 상수함수가 구분되지 않음을 알 수 있다.

더 복잡한 예시를 보자.

// Direct style
function add(a, b) { return a + b; }
const sum = add(1, 2);
console.log(sum); // 3

// Continuation-passing style
function lazyAdd(a, b, next) {
  return next(a + b);
}
lazyAdd(1, 2, (sum) => { // 1, 2를 더해 sum에 저장하고
  console.log(sum); // console.log을 수행한다.
}); // 3

좋은 웹페이지 즐겨찾기