Skip to content

API Development

Jule aims to be interoperable with C/C++. But this must go both ways in some cases. So, while you can use C++ codes with Jule, in some cases you may need to use your Jule codes in the C++ backend.

Jule provides the export directive to achieve this. Jule does not provide a standard for how to pass any definitions to the backend. In other words, it is often not possible to know which identifier your Jule codes will be reflected in the backend. To make this consistent and expose your Jule codes to the backend you need to use the export directive.

Jule makes the export directive available only for global variables and functions. It always takes an absolute parameter. This parameter is the identifier that will be used to export.

Here's an example to develop API for your Jule code for the backend:

jule
cpp use "magicheader.hpp"

cpp fn printMagic()

#export "magic_calculation"
fn magicCalculation(x: int, y: int): int {
	ret ((x * y) ^ 1) / 3
}

fn main() {
	cpp.printMagic()
}

The magicheader.hpp:

cpp
#ifndef MAGICHEADER_HPP
#define MAGICHEADER_HPP

#include <iostream>
#include "api/jule.hpp"

jule::Int magic_calculation(jule::Int, jule::Int);

void printMagic() {
	jule::Int x = 42;
	jule::Int y = 89;
	std::cout << magic_calculation(x, y) << std::endl;
}

#endif

In the code example above, the Jule function with identifier magicCalculation is passed to the backend with identifier magic_calculation. It is called by a function in the backend with C++ interoperability. In this way, a bidirectional use can be achieved.

INFO

You cannot use exported functions as anonymous functions.

WARNING

Jule does not check export identifiers. So you're doing low-level work and you must know what you're doing. Any incorrect export identifier may cause compilation errors.

Additionally, Jule does not check whether export definitions collide with a different function. Therefore, it is recommended to set a custom prefix, especially if you are creating a backend API for your public libraries. For example, for the barbaz function in your foo package, this identifier might be more safe: __foo_barbaz