jank 개발자임. jank는 완전한 Clojure 방언으로, 폭넓은 C++ 상호운용성을 제공함. 기존 Lisp/C++ 조합인 Clasp와 달리 함수·타입·값을 등록하는 연결용 API가 필요 없고, 헤더만 포함하면 C++ 코드를 바로 사용할 수 있음. 템플릿 인스턴스화, 암시적 변환과 ADL을 포함한 오버로드 해석, 예외 던지기와 잡기, 가상 함수 호출까지 지원함.
jank는 C++로 컴파일되고 C++ 타입 시스템을 사용한다는 의미에서 C++ 그 자체임. REPL 기능을 위해 Clang 기반 C++ JIT 컴파일러를 내장하며, Cargo 같은 도구로 C++ 빌드 환경도 개선함.
C++ 네이티브 애플리케이션을 만들거나 기존 C++ 애플리케이션에 jank를 내장할 수 있고, 다른 Clojure 방언에서도 사용할 수 있는 이식 가능한 Clojure 라이브러리를 작성할 수도 있음.
아직 알파라 다소 불안정하며, 1월에 더 안정적인 베타 출시를 목표로 함. 직접 사용하고 불편한 부분을 Slack, Discord, GitHub에 알려주는 것이 가장 큰 도움이 됨. 여러 해 동안 개발해 왔으며, 바이브 코딩으로 만든 프로젝트가 아님.
네이티브 코드에 접근할 수 있는 REPL 중심 개발은 에이전트 기반 개발에 절묘한 조합이 될 수 있다고 봄. 재시작이나 재컴파일이 필요 없고, 영속적 불변 자료구조를 쓰면 여러 스레드에서 병렬로 시도하면서도 복잡성을 감당할 수 있음.
실제로 에이전트가 내 Clojure 코드베이스를 다루고 실험하는 속도에 놀라고 있음. REPL을 아주 잘 활용함.
재시작과 재컴파일이 없다는 말을 들으면, Jupyter에서 시제품을 만들다가 어떤 셀을 실행했는지 잊어 변수 상태가 뒤엉키는 상황이 먼저 떠오름. 에이전트도 분명 이 문제를 겪을 수 있을 것 같아서, 가능하다면 차라리 컴파일을 빠르게 만들겠음.
컴파일 시간이 에이전트 기반 프로그래밍에서 정말 병목인가? 꽤 복잡한 작업을 해봤지만 컴파일만 빨랐다면 훨씬 빨리 끝났겠다고 느낀 적은 없음. Claude가 처리하는 시간이 빌드 시간보다 훨씬 길어 보임.
다만 100만 줄 이상의 코드베이스를 다루지는 않으므로, 그런 규모에서는 느린 컴파일이 문제가 될 수 있겠음. 그때는 에이전트의 처리도 함께 느려질 것 같음.
Lisp와 Prolog 환경이 있던 지난 AI 전성기로 돌아온 셈임. 이번 전성기는 대신 네이티브 라이브러리에 바인딩을 붙인 인터프리터 언어를 택했다는 점이 아쉬움.
C++과 연동되는 Lisp가 필요하다면, Common Lisp에는 몇 년 전부터 CLASP 구현을 통한 매끄러운 C++ 연동 기능이 있음. 본격적인 프로젝트에 쓰려고 탄생한 것으로 알고 있어, 지금쯤이면 꽤 성숙했을 것으로 봄.
Clasp가 원조 Lisp/C++ 조합이기는 하지만, 매끄러운 연동과는 거리가 멂. 마지막으로 확인했을 때는 Lisp에서 접근하려면 함수·타입·값을 C++ 쪽에서 먼저 등록해야 했음. 두 세계를 잇는 연결 코드를 C++로 작성해야 하니, 상당한 경계가 존재함.
jank에서는 C++을 쓸 때처럼 헤더만 불러오면 그 안의 요소에 접근할 수 있음. C++ 타입 시스템을 쓰고 C++로 컴파일되며, 이를 가능하게 하는 Clang 기반 C++ JIT 컴파일러도 내장함.
Clojure와 Common Lisp는 상당히 다른 언어임.
C++로 변환해 컴파일한다는 점을 더 앞에서 밝혀주면 좋겠음. 작동 방식 중 이 부분에 관심을 가질 사람이 많을 것 같음. “C++ 위의 Clojure”라는 표현은 여러 의미로 해석될 수 있으니, C++로 소스 변환한다고 명확히 쓰면 장단점도 자연스럽게 이해됨.
LLVM 기반 JIT 런타임으로 C++ 코드를 즉석에서 컴파일하고 기존 nREPL 편집기 플러그인을 쓸 수 있다는 설명은 jank로 작성한 코드에는 해당하겠지만, C++ 의존성에도 해당하는가? 예를 들어 다른 C++ 라이브러리가 관리하는 데이터에 jank 코드가 의존한다면 어떻게 되는지 궁금함. 동시성과 병렬성에 미치는 영향도 구체적으로 밝혀주면 좋겠음.
“기존 Clojure 코드를 유지하면서 네이티브 세계를 활용한다”는 설명에도 제약이 있는가? 명시하지 않으면 항상 작동하지는 않을 것이라 가정하게 되고, 그러면 매력이 크게 줄어듦. 정말 항상 작동한다면 몇 마디 더 보태서라도 강조할 만함.
Janet과 비슷한 것인가?
jank는 불변성 등을 갖춘 완전한 Clojure에 전면적인 C++ 연동과 네이티브 컴파일을 더한 언어임. Janet은 Clojure의 영향을 크게 받았지만, 내장용 스크립트 언어에 더 가까움. 둘 다 꽤 좋아함.
jank는 Clojure이지만 JVM 대신 Clang과 LLVM을 내장하므로, C++ 헤더를 직접 이해하고 별도 바인딩 없이 C++을 호출할 수 있음. Rust, Swift, Zig 등 다른 LLVM 언어에는 일반적인 방식인 C ABI를 통해 접근 가능함.
본문에 따르면 템플릿, 가상 함수, 예외, 오버로드 해석, RAII가 모두 별도 상용구 코드 없이 작동함. 헤더만 포함하면 되고, 어떤 C++ 소스든 포함하거나 C/C++ 라이브러리에 링크할 수 있음. C++ 타입 시스템을 사용하며 C++로 컴파일되기도 함.