Content is user-generated and unverified.

conal 라이브러리 소개 대담

Q: conal이라는 라이브러리를 만드셨네요. 이 라이브러리를 만들게 된 계기가 뭔가요?

A: 프론트엔드 개발에 쓸 상태 관리 라이브러리가 필요했어요. 기존에 쓰던 jotai는 incremental한 업데이트이 불가능하고 동적 네트워크 구성에 제약이 있었어요.

Q: incremental 업데이트가 불가능하다는 게 구체적으로 어떤 의미인가요?

A: 가령 number 배열을 값으로 갖는 상태를 생각해보죠. 그리고 그 배열의 값을 전부 더한 sum이라는 computed된 상태도요. 이때 배열에 새로운 원소를 추가했을때, jotai의 경우 sum을 구하기 위해 배열의 합을 처음부터 다 더하게 되죠. 이건 jotai의 인터페이스상 이럴수 밖에 없죠.

하지만 우리가 생각하는 이상적인 동작은, 추가된 원소 만큼만 sum에다가 더하는 거에요.

Q: 아, 그러니까 배열이 [1, 2, 3]에서 [1, 2, 3, 4]로 바뀌었을 때, sum을 1+2+3+4=10으로 다시 계산하는 게 아니라 기존 sum 6에다가 4만 더해서 10을 만드는 방식을 말하는 거군요. 그럼 conal에서는 이런 incremental 업데이트가 어떻게 가능한가요?

A: 일단 jotai와 달리 conal에선 상태 뿐만 아니라 이벤트 전파를 명시적으로 관리할 수 있어요. 그래서 배열의 변경 이벤트로부터 sum의 변경 이벤트를 구하는 로직을 짜면 됩니다. 물론, 이런 코드를 짜는게 좀 까다롭긴 하지만, jotai에선 이런걸 할 기회조차 없죠. 그리고 그런 까다로운 코드를 한번 짜놓고, 일종의 combinator 함수로 만들어서 재사용할 수 있어요.

Q: 이벤트 전파를 명시적으로 관리한다는 게 흥미롭네요. 그럼 jotai 같은 라이브러리들은 이벤트 전파를 어떻게 처리하는 건가요?

A: jotai에선 이벤트란게 명시적으로 존재하지 않고, 그냥 어떤 상태를 변경할 수 있고, 그럼 그 변경이 전파되고, 필요한 이펙트가 실행될 수 있죠. 이벤트를 명시적으로 다룰수 있냐가 핵심입니다.

Q: 그럼 conal에서 이벤트를 명시적으로 다룬다는 건 구체적으로 어떤 모습인가요? README를 보니 Event<T> 타입이 있던데, 이게 어떻게 작동하는 건지 간단한 예시로 설명해주실 수 있나요?

A: 그 부분은, 이 스크립트를 읽으시는 분들이 예제 코드를 가지고 놀면서 쉽게 익힐수 있을거라고 생각해요.

Q: 알겠습니다. 그럼 다른 질문을 해볼게요. README에서 "글리치 없음"을 강조하셨는데, 이게 왜 중요한 문제인가요?

A: 우선 글리치가 어떤건지 설명드리죠. 어떤 상태 A가 있고 거기서 파생된 상태 B, C가 있고, 또 B, C로 부터 파생된 D가 있다고 합시다.

   A
 /   \
B     C   
 \   /
   D

다이아몬드 모양이죠?

Q: 네, 다이아몬드 의존성 구조네요. 그럼 이 구조에서 글리치가 어떻게 발생하는 건가요?

A: 여기서 A에 변경이 일어났을때, D에도 변경이 한번만 일어나는게 맞겠죠? 그런데 처리에 따라 D에 변경이 두번 일어날 수있어요. A의 변경에 따른 B의 변경에 따른 변경과, 또 A의 변경에 따른 C의 변경에 따른 변경 이렇게요.

Q: 아, 그러니까 A가 바뀔 때 B가 먼저 업데이트되면서 D가 한 번 계산되고, 그 다음에 C가 업데이트되면서 D가 또 한 번 계산되는 상황이 생길 수 있다는 거군요. 이런 글리치가 실제로 UI에서는 어떤 문제를 일으키나요?

A: 네. UI에서는 중간에 invalid한 상태를 가지는 화면이 잠깐 표시되었다가 돌아오는 flickering이 발생하죠. 또, UI가 아닌 다른 용도로 쓸때도, D가 이펙트를 두번 실행시키는 문제가 있어요. 그 이펙트가 운좋게 idempotent하지 않을 경우에 문제가 되겠죠.

사실 이 문제는 jotai에선 없어요. 대신 RxJS 같은 이벤트 라이브러리를 UI에서 쓰려고할때 마주치게 돼요.

Q: 그럼 conal에서는 이 글리치 문제를 어떻게 해결하셨나요?

A: 우선 RxJS에서 이 문제가 왜 있는지 설명할게요. RxJS에서 이벤트는, 그냥 콜백의 실행이에요. 그래서 이벤트가 전파된다고 하는건, 그 이벤트의 subscriber들(콜백)에 값을 넣어주는것 뿐이에요. 그래서 한 subscriber가 한번의 틱에 여러번 실행될 수도 있죠. 이게 명시적으로 '시간'이란 개념이 없어서 생기는 문제에요.

Conal에선 명시적으로 '시간'이란 개념이 있어요. 시간은 프레임으로 구성되죠. 그리고 이벤트는 한 프레임에 최대 한번 밖에 발생할수 없어요. 상태들은 하나의 값밖에 가지지 못하고요. 예시에서와 같이 다이아몬드 의존성이 생긴 경우에도, D가 한번만 업데이트 되고 그에 따라 이펙트도 한번만 실행되도록 해줍니다.

Q: 시간과 프레임 개념이 핵심이군요. 그럼 실제로 개발자가 conal을 사용할 때는 이 프레임을 어떻게 제어하나요? 자동으로 관리되는 건가요?

A: Timeline 객체를 만들때 onSourceEmission에서 넘겨주는 proceed 를 실행하면 됩니다. 그러면 한 프레임의 진행을 처리하게 되요. 그런데 보통은 onSourceEmission: proceedImmediately 로만 해놓으면, 어떤 Source 이벤트가 실행될때마다 진행되는데, 이러면 대부분의 상황에서 원하는대로 동작할거에요.

Q: 그럼 다음 질문으로 넘어가볼게요. README를 보니 "동적 네트워크"라는 특징도 있던데, 이게 무슨 의미인가요?

A: 결국 Conal이 하는건 이벤트/상태 네트워크를 다루는 건데요. 이벤트와 상태를 처음에 한번만 정의하고 거기서만 이벤트 전파와 상태변경이 이루어지면, 별로 재미가 없는 프로그램이겠죠?

흥미로운 프로그램을 만드려면 시간에 따라 네트워크의 형태 자체를 바꿔야합니다. 사실 React가 비슷한 걸 하는데요. 컴포넌트가 렌더링 되면 useState 훅으로 새로운 상태가 수명을 시작하게 되고, 또 새로 렌더링된 엘리먼트로 부터 새로운 이벤트를 받게 되죠. 이게 이벤트/상태 네트워크가 변하는 것과 같아요.

Q: 아, 그러니까 React의 컴포넌트가 마운트/언마운트되면서 상태와 이벤트 리스너들이 생겼다 없어졌다 하는 것처럼, conal에서도 런타임에 네트워크 구조 자체를 바꿀 수 있다는 말이군요. 그럼 기존 라이브러리들은 이런 동적 네트워크 구성이 어려운가요?

A: 네 그렇습니다. jotai의 경우에, 결국 React 컴포넌트의 생명주기를 이용해서 동적으로 상태를 추가할 수 있어요. 그런데 상태 관리 라이브러리가 프론트엔드 라이브러리에 의존해서 이런 동작을 하는건 좀 이상해보이죠.

Conal에서는 on 으로 어떤 이벤트가 실행됐을때 이펙트를 발생시키면서 네트워크를 변경시킬 수 있어요. 네트워크 변경 역시 이벤트로 부터 유발됩니다. 자세한 예시는 역시 example을 보면 될거 같아요.

Q: 그럼 conal이 React나 SolidJS 같은 프론트엔드 라이브러리와 함께 사용될 때는 어떤 식으로 통합되나요?

A: React와 통합하려면 useDynamic과 같은 훅을 만들어 사용하면 됩니다. 역시 example에 있어요.

그런데 Conal은 fine-grained reactivity를 다룰수 있는데, 그 장점을 못살리는 React랑 쓰면 먼가 좀 아쉽겠죠? 그래서 SolidJS와 함께 쓸수있는 방향을 기대하고 있어요.

Q: fine-grained reactivity라는 건 무슨 의미인가요?

A: 상태가 변경되었을때 그에 따른 변경의 전파와 이펙트의 실행을 딱 필요한 만큼만 하는거에요. 성능적인 이점이 있고, 더 큰 상태를 다루는 프로그램으로 스케일이 가능하죠. 아마 이 대화를 보시는 분들을 이미 fine-grained reactivity를 어느정도 알고 계실듯 해요.

Q: 마지막으로, conal을 실제로 사용해보고 싶은 개발자들에게 어떤 조언을 해주시겠어요? 어떤 프로젝트나 상황에서 conal이 특히 유용할까요?

A: 저처럼 incremental 변경을 하고 싶었던 분들은 바로 어떻게 써야할지 감을 잡으실것 같네요. 당장은 뭔가 기능이 더 많은 jotai 정도로 생각하셔도 괜찮을 듯해요. 많은 분들이 써주셨음 좋겠네요.


conal 라이브러리 정보:

Content is user-generated and unverified.
    conal 라이브러리 소개 대담 | Claude