함수형 언어 하스켈은 컴파일러, 데이터 처리, 백엔드 영역에서는 익숙하지만 데스크톱 GUI 애플리케이션 개발 사례로는 자주 거론되지 않는다. Floréal Technologies가 공개한 튜토리얼 시리즈는 바로 이 공백을 겨냥한다. 시리즈의 1부는 하스켈과 GTK 4, 그리고 GNOME 프로젝트의 디자인 라이브러리인 Adwaita(libadwaita)를 이용해 간단한 할 일 목록(todo-list) 애플리케이션을 만드는 과정을 다룬다. 글은 하스켈 개발 경험이 있는 중급 이상 개발자를 독자로 상정하고 있어, 언어 자체보다 GUI 구조를 어떻게 함수형 스타일로 길들이는지에 초점을 맞춘다.
GTK와 Adwaita, 그리고 하스켈 바인딩
Adwaita는 단순한 위젯 모음이 아니라 GNOME이 접근성과 스타일 측면에서 축적한 결정, 즉 휴먼 인터페이스 가이드라인(HIG)을 코드로 응축한 라이브러리다. 저자의 설명에 따르면 Adwaita를 쓰면 반응형 레이아웃을 구성할 수 있고, 데스크톱이 라이트/다크 테마를 전환할 때 애플리케이션이 런타임에 자동으로 다시 채색되는 기능도 얻을 수 있다. 디자인 언어를 직접 구현할 필요 없이 플랫폼의 관례를 그대로 따라갈 수 있다는 점이 핵심 이점이다.
하스켈에서 이 C 기반 라이브러리를 다루기 위해 시리즈는 haskell-gi 툴킷을 사용한다. haskell-gi는 GTK 계열 라이브러리로부터 하스켈 바인딩을 자동 생성하는 도구로, C API와 대응 관계를 유지한 채 하스켈 인터페이스를 제공한다. 덕분에 기존 GTK 문서나 C 예제를 참고하면서도 하스켈 코드로 옮겨 쓸 수 있다는 점이 실무적으로 중요하다. 글의 시작 예제는 리소스 관리를 대신 처리해 주는 Adwaita의 'Application' 객체를 만들고, 그 결과로 'Todos'라는 제목에 480×640 크기를 가진 빈 창을 띄우는 것으로 구성된다.
명령형 GTK를 함수형으로 길들이는 법
이 튜토리얼의 설계 중심에는 엘름 아키텍처(The Elm Architecture, TEA)가 있다. TEA는 모델(상태), 뷰(상태로부터 그려지는 화면), 업데이트(상태 변경)라는 세 가지 개념을 축으로 하는 대화형 프로그램 구조화 패턴이다. 저자는 이 접근이 GTK 툴킷의 명령형 성격을 다스리는 데 잘 들어맞는다고 본다. 사용자 상호작용은 모두 '메시지(Message)'라는 알려진 동작 집합으로 모델링되고, 각 메시지에는 모델을 어떻게 바꿀지에 대한 명확한 처리가 대응된다. 상태와 동작을 모두 데이터 구조로 표현하기 때문에, 어떤 액션이 발생했고 그것이 무엇을 의미하는지 완전히 들여다볼 수 있다는 것이다. 메시지는 합(sum) 타입으로, 상태 변경은 update 함수로 인코딩된 도메인 로직이 된다.
여기에 이 구현만의 연결 고리로 dispatch와 step이라는 두 함수가 등장한다. dispatch는 메시지를 받아 GTK 실행 루프의 우선순위를 처리한 뒤 step을 호출한다. step은 모델을 읽어 Model 모듈의 update를 적용해 새 모델을 얻고, 이를 저장한 다음 새 모델과 dispatch 함수를 뷰에 넘긴다. 뷰는 그 결과로 새 GTK 위젯을 돌려주고, 이것이 창의 새로운 내용으로 설정된다. 즉 모델-뷰-업데이트의 순환이 GTK 창에 실제로 반영되는 지점이 바로 이 두 함수다.
실무적 의미와 한계
이 시리즈가 한국 개발자에게 주는 시사점은 두 가지다. 첫째, 하스켈 같은 순수 함수형 언어로도 네이티브 리눅스 데스크톱 앱을 만들 수 있으며, 그 과정에서 상태 관리를 데이터와 순수 함수로 환원하는 TEA가 자연스러운 선택지가 된다는 점이다. 이는 프론트엔드에서 Elm이나 Redux류 단방향 데이터 흐름에 익숙한 개발자라면 곧바로 직관을 가져올 수 있는 구조다. 둘째, 자동 생성 바인딩을 통해 기존 GTK 생태계의 방대한 위젯과 문서 자산을 그대로 활용할 수 있다는 점은, 생태계가 상대적으로 작은 하스켈 GUI 개발의 진입 장벽을 낮춘다.
다만 저자 스스로 밝혔듯 이 글의 코드는 개념을 부각하기 위해 완전하지 않은 발췌이며, 전체 프로젝트는 GitHub 저장소(Floreal-Technologies/adwaita-todo)에서 확인해야 한다. 또한 흥미로운 대목으로, 저자는 디자인이 데이터 형태에서 곧바로 도출되지 않는다는 경험을 언급하며 사용자 인터페이스를 만들기 전에 기대하는 바를 먼저 적어 두라고 조언한다. 데이터 모델이 좋은 UI를 보장하지 않는다는 것이다. 실제 위젯이 어떻게 연결되는지, 그리고 더 많은 기능은 2부로 넘겨졌으므로, 이번 글은 전체 그림의 골격을 잡는 단계로 읽는 것이 적절하다.