
2026/10/23 8:56
Jank:C++ とシームレスに連携するネイティブ Clojure ドायレクト
RSS: https://news.ycombinator.com/rss
要約▶
Japanese Translation:
Jank は、ゲーム開発に特化して設計された Clojure の専用ダイアレクタであり、コードブリッジ、手動登録、マーシャリングを必要とすることなく、ネイティブ C++ とシームレスな相互運用性を提供します。従来のアプローチとは異なり、Jank は開発者が機能的な Clojure コードの横に、高パフォーマンスな C++ ロジックを直接記述することを可能にし、LLVM ベースのフロントエンドである Clang を活用して、REPL 駆動のワークフロー内でのオンザフライコンパイルをサポートするインタラクティブな JIT コンパイラを実現します。このアーキテクチャにより、標準およびサードパーティ製の C++ ヘッダーの無効化なく含めることが可能となり、RAII、テンプレート、仮想関数、例外、オーバーロード解決といった高度な機能を利用する際にゼロのボーilerplate で動作します。プロジェクトは Leiningen モデルを用いて依存関係を管理し、ソースからライブラリを解決またはビルドできる豊富なネイティブビルドシステムをサポートしており、特に ImGui や GLFW を使用した例で示されるように、要求の多いグラフィックスニーズに特に適しています。Clojure の高速な反復を可能にする強力なマクロ機能と、堅牢な C++ 型システムを組み合わせて、Jank はコールバックオーバーヘッドを排除し、プロトタイプから生産への移行を簡素化し、機能的なロジックがネイティブ速度と対峙する高パフォーマンスアプリケーションの構築をチームに可能にし、開発者の生産性やアーキテクチャ的な柔軟性を損なうことなく実現します。
本文
Jank:C++ との完全な相互運用性を備えた Clojure 方言
Jank は、C++ とシームレスに連携するネイティブの Clojure 方言です。Java へのブリッジではなく、C++ の力をそのまま Clojure で活用することを目的としています。
主要な特徴
- C++ 機能の完全なサポート: C++ のテンプレート、仮想関数、例外処理、オーバーロード解決、RAII がそのまま動作します。
- 即座の開発開始: 余計な設定なしにヘッダーファイルを読み込むだけで利用可能。
- 堅牢な設計: Clang ベースの C++ JIT コンパイラを搭載し、インタラクティブな REPL 駆動型の開発環境を提供。
コード例:C++ ライブラリの即座の使用
(ns my.app.filesystem (:include "boost/filesystem.hpp") (:refer-global :rename {boost.filesystem.file_size file-size})) (defn file-info [file-path] (try (let [bytes (file-size (cpp/cast std.string file-path))] {:path file-path :size bytes}) (catch boost.filesystem.filesystem_error e {:path file-path :error (.what e)}))) (file-info "/etc/passwd") ; {:path "/etc/passwd", :size 4025} (file-info "/root/.bash_history") ; {:path "/root/.bash_history" ; :error "boost::filesystem::file_size: Permission denied [system:13]: \"/root/.bash_history\""}
C++ ソースコードの直接実行とコンパイル
Jank は、必要に応じて
:jank リード条件付きを使用し、以下の機能を備えています:
- 任意の C++ ソースコードを直接含める
- 任意の C または C++ ライブラリへのリンカー適用
- C++ の型システムを活用
- C++ へそのままコンパイルが可能(Clojure として実行可能)
ツールチェーンとプロジェクト管理
Leiningen ベースの環境
Jank は Leiningen をベースに構築されており、豊富なネイティブビルドシステムを提供します。
- プロジェクトに C/C++ の依存関係を簡単に追加できる
- 自動検出またはソースからのビルドに対応
- 新しい依存関係の追加は一行の変更で可能
開発環境と最適化
Jank は LLVM ベースの JIT ランタイムを内蔵し、C++ コードを実際のニーズに応じて即時コンパイルします。
プロジェクト構成例(画像処理ライブラリ)
(defproject imgui+glfw "0.1-SNAPSHOT" :dependencies [[org.jank-lang.commons/imgui-glfw-sys "2026.06-6"] [org.jank-lang.commons/imgui-opengl2-sys "2026.06-6"] [org.jank-lang.commons/gl-sys "2026.06-1"]] :plugins [[org.jank-lang/lein-jank "2026.06-2"]] :middleware [leiningen.jank/middleware] :main imgui+glfw.main :profiles {:base {:jank {:target-dir "target/debug" :optimization-level 0}} :release {:jank {:target-dir "target/release" :optimization-level 3}}})
ゲーム開発への適合性
Jank はゲーム開発において特に優れています。
- 関数的アプローチ: 不変なデータ構造と REPL 駆動型開発を標準で提供
- ハイブリッドパフォーマンス: Clojure の機能性を保ちつつ、必要に応じて C++ にアクセスして追加のパフォーマンスを得る
- 煩雑な設定なし: ブリッジ、手動関数登録、型のマーシャリング、コールバックの記述は一切不要
コード例:ImGui と GLFW の連携
(ns imgui+glfw.main (:include "GLFW/glfw3.h" "imgui.h" "imgui_impl_glfw.h" "imgui_impl_opengl2.h")) (defn -main [] (cpp/glfwInit) (let [window* (cpp/glfwCreateWindow 400 300 "jank" cpp/nullptr cpp/nullptr)] (cpp/glfwMakeContextCurrent window*) (cpp/ImGui.CreateContext) (cpp/ImGui_ImplGlfw_InitForOpenGL window* true) (cpp/ImGui_ImplOpenGL2_Init) (while (cpp/! (cpp/glfwWindowShouldClose window*)) (cpp/glfwPollEvents) (cpp/ImGui_ImplOpenGL2_NewFrame) (cpp/ImGui_ImplGlfw_NewFrame) (cpp/ImGui.NewFrame) (when (cpp/ImGui.Begin "jank") (cpp/ImGui.Text "Hello, jank and imgui!")) (cpp/ImGui.End) (cpp/ImGui.Render) (cpp/ImGui_ImplOpenGL2_RenderDrawData (cpp/ImGui.GetDrawData)) (cpp/glfwSwapBuffers window*)) (cpp/glfwTerminate)))