Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

The C++ DSL

jank has a domain specific language (DSL) for acessing arbitrary C++ types and values. This DSL is automatically enabled when the jank compiler is expecting a type, such as the first argument to cpp/new, cpp/unbox, or cpp/cast. The DSL can also be explicitly enabled using the #cpp tag.

DSL overview

The C++ DSL can be used to look up both types and values. The jank compiler will ensure that you use a type when you need a type and a value when you need a value.

  • (:* t) adds a pointer
  • (:& t) adds an lvalue reference
  • (:&& t) adds an rvalue reference
  • (:const t) and (:volatile t) add the corresponding C++ qualification
  • (:signed t) and (:unsigned t) add the corresponding C++ qualification
  • (:long t) and (:short t) add the corresponding C++ qualification
  • (:array t s?) turns a type into a sized (or unsized) array
  • (:fn ret [a1 a2...]) builds a function type
  • (t a1 a2...) builds a template instantiation
  • (:member t name) nests into a type
  • (:member* t mt) builds a pointer to member type
  • (:&member t mt) builds a pointer to member value

Let’s take a look at some examples, comparing the C++ representation and the jank representation.

Type examples

C++ jank

A normal C++ map template instantiation.

std::map<std::string, int*>
(std.map std.string (:* int))

A normal C++ array template instantiation.

std::array<char, 64>::value_type
(:member (std.array char 64) value_type)

A sized C-style array.

unsigned char[1024]
(:array (:unsigned char) 1024)

A reference to an unsized C-style array.

unsigned char(&)[]
(:& (:array (:unsigned char)))

A pointer to a C++ function.

int (*)(std::string const &)
(:* (:fn int [(:& (:const std.string))]))

A pointer to a C++ member function.

int (Foo::*)(std::string const &)
(:member* Foo (:fn int [(:& (:const std.string))]))

A pointer to a C++ member which is itself a pointer to a function.

void (*Foo::*)()
(:member* Foo (:* (:fn void [])))

Value examples

jank will never implicitly analyze the C++ DSL for values, like it does for types. You must always tag your DSL form with #cpp to separate it from normal jank code.

C++ jank
std::basic_string<char>::npos
#cpp (:member (std.basic_string char) npos)
std::numeric_limits<long long>::max()
(#cpp (:member (std.numeric_limits (:long (:long int))) max))
&std::pair<int, bool>::first
#cpp (:&member (std.pair int bool) first)