How to invoke a function generated by js_of_ocaml?

648 Views Asked by At

I am new to JavaScript, I am trying to use js_of_ocaml.

I first wrote a very simple cubes.ml:

let simple (a: int) =
  a + 1234

Then complied it:

ocamlfind ocamlc -package js_of_ocaml -package js_of_ocaml.syntax \
          -syntax camlp4o -linkpkg -o cubes.byte cubes.ml

then generated the JavaScript file:

js_of_ocaml cubes.byte

Here is the generated cubes.js. Note that we could not find 1234 or function name simple in that file.

I have another JavaScript file Home.js, where I want the function callSimple to call what was generated in cubes.js. But I don't know how to write it. Could anyone help?

(function () {
    ...
    function callSimple(a) {
        return ???;
    };
    ...
})();

Edit 1:

I tried the solution proposed by @EdgarAroutiounian :

(* cubes.ml *)
let () =
  Js.Unsafe.global##.jscode := (object%js
    val simple = Js.wrap_meth_callback
        (fun a -> a + 1234)
    val speak = Js.wrap_meth_callback
        (fun () -> print_endline "hello")
  end)

It did compile, but it did not return the right output: enter image description here

If I write in home.js:

confirm(jscode.simple(10)); // 1244 is expected
confirm(jscode.speak()); // "hello" as string is expected

the first line returns function (a){return p(c,aM(b,a))}, and the second line returns 0. They are not what I expect.

1

There are 1 best solutions below

4
On

Here's one possible way to do it.

In our OCaml code intended to be exposed to JavaScript:

let () =
  Js.Unsafe.global##.jscode := (object%js
    val simple = Js.wrap_meth_callback
        (fun a -> a + 1234)
    val speak = Js.wrap_meth_callback
        (fun () -> print_endline "hello")
  end)

Notice that I'm using the ppx extension, I recommend you do so as well: this means no more camlp4. You can compile that code with:

ocamlfind ocamlc -package js_of_ocaml.ppx -linkpkg cubes.ml -o T
js_of_ocaml T -o cubes.js

Then in your other file, home.js

console.log(jscode.simple(10));
console.log(jscode.speak());

and an index.html of:

<!DOCTYPE html>
<meta charset="utf-8">
<body>
  <script src="cubes.js"></script>
  <script src="home.js"></script>
</body>

And that should work.