Skip to content

Instantly share code, notes, and snippets.

@vietlq
Last active November 10, 2018 14:17
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vietlq/7e80f4d37cbf51d200a3c5d6b5bcc4f3 to your computer and use it in GitHub Desktop.
Save vietlq/7e80f4d37cbf51d200a3c5d6b5bcc4f3 to your computer and use it in GitHub Desktop.
Playing with js_of_ocaml

Playing with js_of_ocaml

A few years ago, while picking up basic OCaml, I found this site by Andrew Ray: https://andrewray.github.io/iocamljs/full402.html . This page has in-browser OCaml notebook. I was trying to modernise it and compile with OCaml 4.06.1. The vital part of the page is an ability to evaluate OCaml at run time in Javascript inside your browser. This is done by Js_of_ocaml. Learn basics of Js_of_ocaml in this post.

Hello World

Let’s do tradition “hello world” exercise, create a new file hello.ml:

let () =  
    let oneArgument (a: int) = a + 100 in
    Js.Unsafe.global##.jsOneArgument := Js.wrap_callback oneArgument;
    (* This will go to console.log *)
    print_string "Hello from Js_of_ocaml!\n";

This file does 2 things: 1) Update the global scope and inject a new function jsOneArgument which returns input + 100 ; 2) print the string Hello from Js_of_ocaml!

Now compile it into byte-code file (one line):

ocamlfind ocamlc -g -o hello.byte -linkpkg -package js_of_ocaml,js_of_ocaml-ppx hello.ml

Notice the usage of PPX for syntax enrichment here. The byte-code file hello.byte won’t give you much fun. Here we compiled it with debug flag -g which gives large output size of 1,313,781 bytes . Let’s try running it and see what happens:

$ ./hello.byte
Unimplemented Javascript primitive caml_pure_js_expr!

Nothing to see here, move on to compilation of the byte-code file into a Javascript target:

js_of_ocaml -o hello.js hello.byte

Now you need to create an HTML file to witness the miracle:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
          "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>Js_of_ocaml - Hello</title>
    <script type="text/javascript" src="hello.js"></script>
  </head>
  <body>
  </body>
</html>

Open in your browser and then JS console (F12 for Chrome), you will see the expected string in console.log:

Hello from Js_of_ocaml!

Now you can type in console to see if the function jsOneArgument was injected:

jsOneArgument(1)
> 101

Voila! So we have successfully compiled a OCaml file into Javascript! Learn more from https://ocsigen.org/js_of_ocaml/3.1.0/manual/overview and https://github.com/ocsigen/js_of_ocaml/tree/master/examples .

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment