The Js_of_ocaml library
Base types
Base values are not represented the same way in OCaml and Javascript. In particular, OCaml strings are mutable arrays of bytes, while Javascript strings are constant arrays of UTF-16 code points. We list here the correspondence between base types. Conversion functions are provided.
OCaml values | Ocaml type of Javascript values | Actual Javascript type |
---|---|---|
int | int | Number |
float | float | Number |
bool | bool Js.t | Boolean |
string | Js.js_string Js.t | String |
array | Js.js_array Js.t | Array |
Integers and floats are implemented as Javascript numbers. They can thus be directly passed to and from Javascript.
Typing Javascript objects
Javascript objects are given types of the shape <m_1 : t_1; ...; m_n : t_n> Js.t, using a phantom object type. The methods m_i stands for the field of the Javascript object. For instance, a Javascript object of type:
< data : js_string t Js.prop; appendData : js_string t -> unit Js.meth> Js.t
has a property data containing a Javascript string, and a method appendData taking a Javascript string as argument and returning no value.
Method name and underscore
Some overloading is possible using a syntactic trick: names _foo, foo_abcd and foo are all mapped to a same Javascript field name foo: when accessing a field of an object, the name given in the OCaml code is transformed by removing a leading underscore and then removing all characters starting from the last underscore; this yields the corresponding Javascript name. For instance, these three types correspond to the same Javascript method drawImage:
drawImage : imageElement t -> float -> float -> unit meth drawImage_withSize : imageElement t -> float -> float -> float -> float -> unit meth drawImage_fromCanvas : canvasElement t -> float -> float -> unit meth
This trick can also be used to refer to Javascript fields type or Uppercase, for instance as _type and _Uppercase.
Example
class type .. = object
(* Refer to [meth] *)
method meth : ..
method meth_int : ..
method _meth_ : ..
method _meth_aa : ..
(* Refer to [meth_a] *)
method meth_a_int : ..
method _meth_a_ : ..
method _meth_a_b : ..
(* Refer to [Meth] *)
method _Meth : ..
(* Refer to [_meth] *)
method __meth : ..
(* Refer to [_] *)
method __ : ..
end
Syntax extension
Two syntax extensions are provided: the Ppx_js one and the Camlp4 one. This manual is written using the ppx extension, which we advise.
OCaml and Javascript functions
OCaml and Javascript do not follow the same calling convention. In OCaml, functions can be partially applied, returning a function closure. In Javascript, when only some of the parameters are passed, the others are set to the undefined value. As a consequence, it is not possible to call a Javascript function from OCaml as if it was an OCaml function, and conversely.
Calling Javascript functions
At the moment, there is no syntactic sugar for calling Javascript functions. You should use either Js.Unsafe.call or Js.Unsafe.fun_call, depending whether you want this to be bound to some particular object in the function body or not.
You can also refer to a Javascript function using an OCaml external declaration. Then, you need to write stub functions in C so that the OCaml compiler accept the external declaration:
Ocaml file: external foo : t1 -> t2 = "foo" C file: #include <stdlib.h> #define D(f) void f () { exit(1); } D(foo)
You can call this function as if it was an OCaml function, as the Javascript function is appropriately wrapped by the system.
Refer to the linker manual to link your program with javascript stubs.
IO
The Js_of_ocaml.Json module allows to marshal and unmarshal the javascript representation of OCaml values into the corresponding JSON string. The unmarshaling is unsafe in the same way the OCaml Marshal.from_string function is.
Type-safe unmarshaling may be achieved with the deriving library using either the optional Json class or the Pickle class.
- The Json class use a Json as external representation and do not preserve potential sharings in the data representation. See Deriving_Json for more information.
- The Pickle class use a binary format as external representation and preserve sharings in the data representation.