文章摘要
jank语言在C++互操作性方面取得了显著进展,开发者通过手动内存管理实现了cpp/new和cpp/delete功能,并支持析构函数。此外,引入了cpp/true和cpp/false以避免隐式类型转换。这些改进得益于Clang和LLVM的技术支持,以及社区和赞助者的帮助。
文章总结
文章《jank is C++》详细介绍了jank语言在C++互操作性方面的最新进展,展示了作者在过去一个季度中如何通过Clang和LLVM技术实现jank与C++的无缝交互。以下是文章的主要内容总结:
1. 内存管理
作者实现了通过cpp/new和cpp/delete进行手动内存管理,使用了jank的GC分配器(目前是bdwgc)。虽然cpp/delete通常不需要,但它可以使内存回收更加确定。此外,jank支持完整的bdwgc析构函数调用,无论是手动删除还是自动回收都会触发非平凡的析构函数。
2. 布尔值
为了避免隐式的jank对象转换,作者引入了cpp/true和cpp/false,它们直接对应C++的布尔值。这有助于生成更精简的IR代码。
3. 复杂类型字符串
jank现在支持在符号中表示指针类型,例如cpp/int**对应C++的int **类型。对于需要空格或逗号的复杂类型(如模板),可以使用(cpp/type "std::map<std::string, int>")来表示。
4. 复杂类型构造函数
为了解决Clojure中构造函数调用语法与C++语法的冲突,jank现在允许在类型调用中省略.后缀,直接调用类型即可视为构造函数调用。
5. 不透明盒子(Opaque Boxes)
为了在原生环境中处理任意类型的指针,作者引入了“不透明盒子”机制。通过cpp/box可以将原生指针封装为jank对象,并在需要时通过cpp/unbox解封装并指定类型。
6. 预编译头文件(PCH)
为了减少启动时间,jank现在支持预编译C++头文件。安装jank后,首次运行时会自动生成PCH文件,并在更新时重新编译。
7. 稳定性
作者进行了大量测试,确保jank与C++的互操作性在各种情况下都能稳定运行。测试涵盖了数组、全局指针、静态引用、函数指针、可变参数C函数调用等多个方面。
8. 静态类型
jank的互操作性是静态类型的,完全基于C++。编译器会在找不到成员、函数或特定重载时直接报错,无需运行时反射。
9. 实际示例
文章展示了几个实际示例,包括通过std::cout输出“Hello, world”、使用第三方库nlohmann/json进行JSON格式化输出,以及使用ftxui库进行终端布局。这些示例展示了jank与C++的无缝交互能力。

10. 与Clasp的比较
作者提到了C++ Lisp领域的先驱Clasp,并指出尽管jank和Clasp在实现方式和语言选择上有所不同,但两者都是将Lisp与C++结合的尝试。
11. 未来计划
接下来的工作重点包括自动析构函数调用、解决Clang和LLVM中的问题、改进打包和分发机制,以及修复各种小问题和工具支持。最终目标是发布jank的alpha版本。
12. 如何参与
作者鼓励社区成员通过Slack、GitHub参与讨论和贡献代码,并呼吁大家成为GitHub赞助者,以支持jank的进一步发展。
文章展示了jank在C++互操作性方面的强大能力,并展望了未来的发展方向。
评论总结
对Jank的C++互操作方法的批评
- 主要观点:Jank的C++互操作方法(CppInterOp)被认为是不稳定的,因为它通过字符串拼接和解析来生成ABI兼容的调用,而不是直接使用libclang的AST。
- 关键引用:
- "the CppInterOp approach to cpp interop is completely janky"(CppInterOp的C++互操作方法完全不稳定)
- "there’s no reason to do this except that libclang currently doesn’t support any other way"(除了libclang目前不支持其他方法外,没有理由这样做)
对C++标准化的不满
- 主要观点:C++缺乏标准化的名称修饰(name-mangling)和编译时反射机制,这增加了动态FFI的复杂性。
- 关键引用:
- "the lack of standardization for name-mangling, or even a way mangle or de-mangle names at compile-time"(C++缺乏标准化的名称修饰,甚至没有在编译时修饰或解修饰名称的方法)
- "Will compilers ever actually implement one of the three (3) compile-time reflection standards?"(编译器会真正实现三种编译时反射标准中的一种吗?)
对其他语言的C++互操作的积极评价
- 主要观点:D语言在C++互操作方面表现良好,而Carbon和Swift的互操作尚未显现。
- 关键引用:
- "Recently I tried D lang and was surprise with the nice interop with C++"(最近我尝试了D语言,对其与C++的良好互操作感到惊讶)
- "Carbon is nowhere to be seen and havent tried Swift’s yet"(Carbon尚未出现,我还没有尝试Swift的互操作)
对Jank项目的技术实现的理解
- 主要观点:Jank通过嵌入LLVM并使用libclang/CppInterOp来生成LLVM类型并发出函数调用。
- 关键引用:
- "Basically it just uses libclang / CppInterOp to get the corresponding LLVM types and then emits a function call"(基本上,它只是使用libclang/CppInterOp来获取相应的LLVM类型,然后发出函数调用)
对Jank项目的赞赏与期望
- 主要观点:尽管Jank的C++互操作存在挑战,但项目本身令人印象深刻,并且希望未来能有更好的C++互操作支持。
- 关键引用:
- "Neat project, I can only marvel at your ability to deal with such madness"(很棒的项目,我只能对你处理这种疯狂的能力感到惊叹)
- "it would be nice to have better C++ interop in higher level languages"(在高级语言中拥有更好的C++互操作会很不错)