Possible to mix jsoo and rescript (without json)?

Cross post of Possible to mix jsoo and rescript (without json)? - ReScript Forum

Besides using json, is it possible to mix jsoo and rescript in a single project ?

I’d like to use rescript for the React-ish stuff, and jsoo for the OCaml libraries not ported to rescript.

I’m wondering if there is a way to link the two, besides (directly) using json; i.e. if it’s OCaml/jsoo on oneside and OCaml/rescript on the other, is there a easier way to connect them ?

If you’re in the browser context, you can try assigning functions, variables, etc from within rescript and jsoo bundles to the windows/global object. Now they’ll be able to share that.

If you’re doing this server side with node or deno, the same would also work but you’d just have to make sure the generated JavaScript from both bundles are evaluated together.

Suppose we have a

type t = {
  x: int,
  y: string
}

do we have any guarantee that if we construct a t in Rescript, pass it to jsoo, it can be read as a jsoo t ?

Unfortunately even just strings cannot directly be passed between JSOO and Rescript, since JSOO boxes strings due to encoding differences, while Rescript uses JS strings directly. This is due to the different compilation models of JSOO and Rescript.

Shameless plug for ppx_expjs which makes interrop between JSOO and JS a bit easier, and could possibly help here as well.

1 Like

One limitation of JSOO ↔ JSON ↔ ReScript is that we can not send things like MessageChannel or SharedArrayBuffer. Does ppx_expjs handle this ?

Without having used those tools, from a cursory look at their APIs I’m not sure if ppx_expjs would be very helpful here. Right now the mental model of the PPX is “sometimes you write OCaml code that compiles to JS that you want to treat as a black-box in JS-land”, meaning you want to directly call OCaml code in JS without doing any of the standard “embellishing” usually required for that.*

In my non-expert opinion, I don’t think you’ll be able to communicate between JSOO and Rescript without doing some conversion/serialization. If I take this basic code block:

type t = {
  x : int
}

let f t = print_int t.x

This is what Bucklescript/Rescript produces:

function f(t) {
  return Pervasives.print_int(t.x);
}

exports.f = f;

Notice how a lot of the semantics of your code remain – t.x in OCaml directly translates to t.x in JS.

Conversely, here’s f in JSOO:

function _a_(t,cont) { return caml_cps_call2(Stdlib[44],t[1],cont) }

Because all of the OCaml types have been erased by the time JSOO compiles the bytecode into JS, we use the offset rather than the field name x.

Long story short, these differing representations are going to require some manipulation to send back and forth.

*Here’s a blog post that describes the PPX in a bit more detail if you’re interested

This is very convincing.

1 Like