Hacker News 中文摘要

RSS订阅

Jank – The native Clojure dialect with seamless C++ interop

jank 语言(jank)是一门把 Clojure 语言(Clojure)构建在 C++ 语言(C++)之上的原生方言,拥有与其他语言不同的 C++ 互操作能力:模板、虚函数、异常、重载解析和 RAII 都能使用,无需样板代码,包含头文件就能开始。它也是稳健的 Clojure 方言,提供由基于 Clang 编译器(Clang)的 C++ JIT 编译器驱动的交互式 REPL 开发;jank 用 C++ 互操作取代 Java 语言(Java)互操作,可包含任意 C++ 源码、链接任意 C 语言(C)或 C++ 库,并使用 C++ 类型系统,甚至编译到 C++,项目管理基于 Leiningen 工具(Leiningen)。

正文

具备无缝 C++ 互操作能力的原生 Clojure 方言

jank 是构建于 C++ 之上的 Clojure。它拥有其他任何语言都不具备的 C++ 互操作能力。模板、虚函数、异常、重载解析和 RAII 在 jank 中都能顺畅工作,无需样板代码,只需引入头文件就能直接开工!

jank 是一个健壮的 Clojure 方言。它通过基于 Clang 的 C++ JIT 编译器,提供交互式的 REPL 驱动开发体验。

(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/.bashhistory") ; {:path "/root/.bashhistory" ; :error "boost::filesystem::filesize: Permission denied [system:13]: \"/root/.bashhistory\""}

jank 是一个不折不扣的 Clojure 方言,只是用 C++ 互操作取代了 Java 互操作。需要时,你还可以使用 :jank 读取器条件。它可以包含任意 C++ 源码、链接任意 C 或 C++ 库,并直接使用 C++ 类型系统;它甚至能直接编译成 C++!

jank 采用基于 Leiningen 的项目管理,并拥有丰富的原生构建系统,可以轻松地为项目添加 C 和 C++ 依赖。你可以使用自己喜欢的 nREPL 编辑器插件;jank 内置的基于 LLVM 的 JIT 运行时能够即时编译 C++ 代码。

轻松的项目管理

jank 的原生构建系统能够找到已安装的原生依赖,或从源码构建它们。添加新依赖只需改动一行配置。

(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 非常适合游戏开发

jank 将函数式、不可变数据以及 REPL 驱动的开发带入游戏开发流程。在 jank 中,每当需要额外性能时,你都可以随时调用 C++,无需桥接,无需函数/类型注册,无需数据编组,也无需回调。

(ns imgui+glfw.main (:include "GLFW/glfw3.h" "imgui.h" "imguiimplglfw.h" "imguiimplopengl2.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/ImGuiImplOpenGL2Init)

(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)))

图 1

评论

讨论篇幅很短,高赞评论间却出现明显分歧。一方认为 REPL 驱动开发结合原生代码与不可变数据结构是智能体工程的理想组合,另一方则反问这是否只是 Janet 的翻版,并质疑其新颖性。

认为 REPL 驱动开发结合原生代码与不可变数据结构是智能体工程的理想组合

  • 该观点主张,REPL 让迭代无需重启和重新编译;在此基础上还能调用原生代码,不必放弃底层能力;持久化不可变数据结构则让开发者在多线程并行迭代时仍能保持清醒、状态可控。(高赞) > REPL 驱动开发若能调用原生代码,可能是智能体工程的理想配方。(@goldenshale)

质疑它是否只是 Janet 的翻版

  • 该观点看到 REPL、原生代码和不可变数据结构等特性后,直接联想到 Janet,等于在问它是否和 Janet 这类已有语言没有本质区别,从而质疑其新颖性。(高赞) > 这听起来很像 Janet?(@alper)