Bun
is a new Javascript runtime. It is fast, and it has a very fast bun:ffi
.
Based on bun:ffi
, I just wrote an experimental package jlbun
which enables using Julia from Javascript/Typescript.
The package has been published at NPM, so you can directly install it via npm install jlbun
. However, since a thin dynamic library needs to be built locally, cmake
is needed. Only Linux and macOS are supported right now, since Bun
does not support Windows yet.
To use the package, you need both Julia
and Bun
. There are a few examples in the repo’s README.
It is still at a very early stage. Feedbacks and suggestions are welcome, especially those related to the following topics:
- API design
- Memory management
- Performance
14 Likes
With the latest update, we can now do something interesting, e.g., combining Julia’s Task
with Javascript’s Promise
. Here is an example:
import { Julia, JuliaFunction, JuliaTask, JuliaValue } from "../jlbun";
Julia.init();
const promises: Promise<JuliaValue>[] = [];
const func = Julia.eval(`function ()
println(Threads.threadid());
ans = 0;
for i in 1:1000
ans += i
end
ans
end
`) as JuliaFunction;
for (let i = 0; i < Julia.nthreads; i++) {
promises.push(JuliaTask.from(func).schedule(i).value);
}
const results = (await Promise.all(promises)).map(promise => promise.value);
console.log(results);
Julia.close();
3 Likes
Very interesting. Since Julia can ccall
libjulia, we can do the following trick:
const interpolated = `
function ()
ptr = ccall(:jl_call,
Ptr{Nothing},
(Ptr{Nothing}, Ptr{Nothing}, Cint),
convert(Ptr{Nothing}, ${funcPtr}),
convert(Ptr{Nothing}, ${argsPtr}),
${argsLength},
)
unsafe_pointer_to_objref(ptr)
end
`;
Just eval()
the interpolated string above, and we will get a zero-argument version of the original function. The wrapped function can then be used to initiate a Task
.
1 Like
Using Bun’s JSCallback
, we can now use JS functions in the Julia scope:
import { Julia, JuliaArray, JuliaFunction, safeCString } from "jlbun";
Julia.init();
const jsFunc = (x: number) => {
return safeCString(x.toString());
};
const cb = JuliaFunction.from(jsFunc, {
returns: "cstring",
args: ["i32"],
});
const arr = JuliaArray.from(new Int32Array([1, 10, 20, 30, 100]));
Julia.Base["sort!"].callWithKwargs({ by: cb, rev: true }, arr);
Julia.println(arr); // Int32[30, 20, 100, 10, 1]
cb.close();
Julia.close();
2 Likes