JVM 생태계에서 태어난 Clojure는 불변 데이터 구조와 REPL 기반 개발, 함수형 프로그래밍을 하나의 실용적인 묶음으로 제공해 꾸준한 팬층을 확보해 왔다. 그러나 JVM에 얹혀 있다는 사실은 강점인 동시에 제약이기도 하다. 기동 시간, 메모리 사용량, 그리고 네이티브 라이브러리와의 연동에서 오는 번거로움은 게임이나 그래픽, 시스템 프로그래밍처럼 성능과 저수준 제어가 중요한 영역에서 Clojure를 선택하기 어렵게 만드는 이유였다. Jank(jank)는 바로 이 지점을 겨냥한다. Clojure 방언이되 기반을 JVM이 아니라 C++로 옮긴 언어다.
자바 대신 C++를 품은 Clojure
Jank는 스스로를 '네이티브 Clojure 방언'으로 규정하며, 자바 상호운용(interop) 대신 C++ 상호운용을 제공한다. 공식 설명에 따르면 템플릿, 가상 함수, 예외, 오버로드 해석, RAII 같은 C++의 핵심 기능이 별도의 보일러플레이트 없이 그대로 동작한다. 헤더를 포함하기만 하면 바로 쓸 수 있다는 것이다. 또한 어떤 C++ 소스도 포함할 수 있고, C나 C++ 라이브러리에 링크할 수 있으며, C++의 타입 시스템을 그대로 사용한다. 더 나아가 Jank 자체가 C++로 컴파일된다고 밝히고 있다. Clojure 사용자에게 익숙한 리더 조건부(reader conditional) 문법도 :jank 키워드 형태로 제공돼, 플랫폼별 코드를 분기할 수 있다.
이 구조에서 핵심은 상호운용이 '다리'가 아니라는 점이다. 많은 언어가 외부 네이티브 코드를 쓰려면 함수와 타입을 등록하고, 데이터를 변환(marshalling)하고, 콜백을 거는 별도의 바인딩 계층을 요구한다. Jank는 이런 중간 단계 없이 C++ 타입 시스템 위에서 직접 동작하도록 설계됐다고 설명한다. 함수형이고 불변인 데이터를 다루다가 성능이 필요한 순간 곧장 C++로 내려갈 수 있다는 것이 내세우는 그림이다.
Clang 기반 JIT와 REPL 개발
Jank가 이런 연동을 가능하게 하는 기반은 Clang 기반의 C++ JIT 컴파일러다. LLVM 기반 JIT 런타임을 내장해 C++ 코드를 실행 시점에 즉석에서 컴파일한다. 덕분에 Clojure 개발자들이 당연하게 여기는 상호작용형 REPL 개발 경험이 네이티브 환경에서도 유지된다. 에디터 연동 측면에서도 기존 nREPL 플러그인을 그대로 쓸 수 있다고 안내한다. 즉 새로운 툴체인을 처음부터 배우기보다, 익숙한 Clojure 작업 흐름을 거의 그대로 가져오면서 대상만 네이티브로 바꾸는 접근이다.
프로젝트 관리와 빌드도 기존 생태계에 기댄다. Jank는 Leiningen 기반 프로젝트 관리를 채택했고, 여기에 풍부한 네이티브 빌드 시스템을 더했다. 이 빌드 시스템은 설치된 네이티브 의존성을 찾아내거나 소스에서 직접 빌드할 수 있으며, 새 의존성 추가는 한 줄 변경으로 끝난다고 강조한다. C/C++ 의존성을 프로젝트에 끌어오는 일이 Clojure의 의존성 선언만큼 가볍다는 점을 전면에 내세운 셈이다.
실무자가 따져볼 지점
용도로는 게임 개발이 구체적인 예시로 언급된다. 함수형·불변 데이터와 REPL 중심 개발을 게임 개발 워크플로에 가져오되, 추가 성능이 필요할 때 언제든 C++로 손을 뻗을 수 있다는 점을 장점으로 든다. 실시간 성능과 네이티브 엔진 연동이 필수인 게임 분야는 Clojure가 전통적으로 약했던 영역이라는 점에서, Jank가 왜 이 사례를 앞세우는지 이해할 만하다.
다만 한국의 실무자가 도입을 검토한다면 공식 소개가 말하지 않는 부분도 함께 봐야 한다. 제공된 자료에는 안정화 단계나 버전, 지원 플랫폼, 기존 Clojure 라이브러리와의 호환 범위, 실제 성능 수치가 담겨 있지 않다. Clang/LLVM 기반 JIT로 C++를 실시간 컴파일한다는 설계는 강력하지만, 그만큼 빌드 환경 구성과 디버깅의 복잡성, 컴파일 지연 같은 현실적 비용이 따를 수 있다. 또한 Clojure 생태계의 많은 라이브러리가 JVM과 자바 상호운용을 전제로 만들어졌다는 점에서, C++ 기반으로 옮겨올 때 그대로 재사용하기 어려운 코드가 적지 않을 것이다.
결국 Jank의 의미는 'Clojure를 네이티브로'라는 오래된 바람에 C++ 상호운용이라는 구체적인 답을 제시했다는 데 있다. 자바 연동을 C++ 연동으로 치환하고, REPL과 nREPL, Leiningen이라는 익숙한 도구를 유지한 설계는 Clojure 사용자가 네이티브 영역으로 발을 들이는 진입 장벽을 낮춘다. 성능이 중요한 작업에 함수형 사고와 불변 데이터를 적용하고 싶었던 개발자라면, 현재의 성숙도와 생태계 한계를 직접 검증한다는 전제 아래 주시할 만한 프로젝트다.