점프 테이블을 실제로 연습해보기

수정일: 2025. 3. 16.

점프테이블을 실제로 연습해보면서 느낀점을 써보자

점프테이블을 연습해보자

두서

점프 테이블이라는 글에서 작성했듯이 점프 테이블에 대해 알아봤으니 연습을 해보는게 좋겠습니다.

아주 기본적인 형태부터, 조금 개량시킨 형태등을 알아보겠습니다.

state machine을 구현한다는 느낌으로 작성해보겠습니다.

첫번째 예시

```js const states = { add1: n => { n += 1; return ‘add2’; }, add2: n => { n += 2; return null; } }

const runner = (init, ctx) => { let state = init, passedCtx;

while(state) \{
    state = states[state]?.(ctx);
\}

} ```

위의 형태가 아마 가장 단순한 형태일 것입니다.

물론 이렇게 생각하실 수 있습니다.

```js const add1add2 = n => [1, 2].reduce((acc,cur) => acc + cur, n) ```

위에서 만든 상태 머신에 비해 훨씬 짧고 간단하며, 이미 검증 되었고 등등… 이렇게 만드는 것도 매우 훌륭합니다.

사실 이 점프머신과 함수형 프로그래밍은 저에게 매우 비슷하다는 느낌을 줍니다.

원하는 함수등을 지정해놓고, 순서에 따라 파이프에 물을 흘려 보내듯이 순서대로 흘려보내는 것이 닮아 있습니다.

여기서 점프 테이블의 강점은 명시적인 상태 관리라고 생각합니다. 각 상태를 각 함수가 관리하고, 상태에 따라 다른 상태로 넘기는 것이 명시적으로 드러나게 됩니다.

```js const state = { a: (ctx) => ctx > 5 ? null : ‘b’, b: (ctx) => ctx > 7 ? null : ‘c’, // … } ``` 이렇게 명시적으로 상태를 지정하는 것이 가능합니다. 만약 상태 a에서 `ctx > 5`라는 조건을 만족한다면 바로 상태머신은 종료됩니다.

이 글을 쓰면서도 단점이 보여지긴 합니다. 만약 위처럼 a, b, c 등으로 시퀀스를 갖는 이름으로 상태를 관리하는 경우 유지보수 기간 중 a와 b 사이의 어떤 상태가 추가될 때, 이름을 끼워넣기 난해할 수 있다는 점입니다.

함수형 코드가 반환값을 주니 점프 테이블도 반환값을 받을 수 있게 약간 손을 보겠습니다.

두번째 예시

```js

const states = { add1:(n)=>{ n += 1; return [‘add2’, n]; }, add2:(n) => { n += 2; return [‘done’, n]; }, done: (n) => [null, n] };

const runner = (init, ctx) => { let state = init, passedCtx;

while(state) \{
    [state, passedCtx] = states[state]?.(passedCtx || ctx);
\}
return [state, passedCtx];

}

const result = runner(‘add1’, 1);

```

각 상태는 이제 다음 이동 할 `state`와 해당 함수의 반환값을 튜플에 담아 반환합니다. `[state, return value]` 이런식으로 말입니다.

`while`문 내에서 `passedCtx`는 이전 상태에게 전달받은 값의 포인터 혹은 원시값이 저장되며 해당 값을 다음 state 함수에 전달합니다. 만약 값이 없다면 처음 받은 값을 전달합니다.

여기서 계속 발전시킬 수 있습니다. 예를 들어 처음 받은 `ctx`와 `passedCtx`를 항시 전달하게 한다거나, 받은 인자들을 `spread` 연산자를 사용하여 계속 전달 한다거나 등등… 다양한 방법이 있겠습니다.

단, 단순하게 if-else를 나열하는 것보다는 낫다고 생각합니다.

마치며

위에서 함수형과 점프 테이블에 대한 비교를 했습니다. 비교는 비교일 뿐 서로 더 나은 점이 있고 보완할 점이 있습니다.

전 이럴 때, 둘을 섞어 쓰는게 더 좋다고 생각합니다.

큰 흐름은 점프 테이블로 관리하고 점프 테이블의 각 함수는 함수형으로 관리를 하는 것입니다.

비슷한 느낌으로 객체지향에 함수형을 섞는 등의 방법도 있습니다.