Tech News
← Back to articles

jank Is C++

read original related products more articles

jank is C++

If you've wondered how much a solo dev can build for seamless C++ interop on a quarter, you're about to find out. In April, jank was unable to reach into C++ at all. Toward the end of this post, I'll show some real world examples of what works today. Before that, though, I want to say thank you for the sponsorship this quarter, not only by all of my individual Github sponsors, but also by Clojurists Together. I also want to say thank you to Vassil Vassilev and Lang Hames for building the necessary tech in Clang and LLVM for jank to actually do all of this magic. Let's get into it!

Memory management

In the past month, I have implemented manual memory management via cpp/new and cpp/delete . This uses jank's GC allocator (currently bdwgc), rather than malloc , so using cpp/delete isn't generally needed. However, if cpp/delete is used then memory collection can be eager and more deterministic.

The implementation has full bdwgc support for destructors as well, so both manual deletion and automatic collection will trigger non-trivial destructors.

( let [ i ( cpp/int. 500 ) p ( cpp/new cpp/int i )] ( assert ( = i ( cpp/* p ))))

True and false

To avoid any implicit jank object casting, we can now use cpp/true and cpp/false , which are straight up C++ bools. These come in handy when trying to keep the generated IR as lean as possible, compared to using true or false and having jank do automatic conversions from Clojure land into C++ land. Going forward, jank will add support for #cpp reader macros, as an easy way to get C++ literals, similar to #js in ClojureScript and #dart in ClojureDart.

Complex type strings

It's possible to represent a lot of possible types using normal Clojure syntax. This month, I also extended that to include pointer types within symbols. For example, cpp/int** will give you a C++ int ** type. However, when spaces or commas are required, such as with templates, Clojure's symbols become too limiting. In those cases, we can now use (cpp/type "std::map") . This will evaluate to a type which can be used in type position for cpp/cast , cpp/new , and so on.

... continue reading