Effect handlers
Js_of_ocaml supports effect handlers with the --enable=effects flag. This is based on partially transforming the program to continuation-passing style. As a consequence, tail calls could be fully optimized (if CPS transformed). This is not the default for now since the generated code can be slower, larger and less readable. The transformation is based on an analysis to detect parts of the code that cannot involves effects and keep it in direct style. The analysis is especially effective on monomorphic code. It is not so effective when higher-order functions are heavily used (Lwt, Async, incremental). We hope to improve on this by trying alternative compilation strategies.
An alternative CPS transform is provided under the --effects=double-translation option. It keeps a direct-style version of the transformed functions in addition to the CPS version. The choice of running the CPS version is delayed to run time. Since CPS code is usually slower, this can avoid degradations. In addition, one can ensure that some code is run in direct style by using Jsoo_runtime.Effect.assume_no_perform.
Dune integration
Dune is aware of the --enable effects option. So, you can just add it to the Js_of_ocaml flags (js_of_ocaml (flags ...)) wherever you want to use it.
We're still working on dune support for the --effects option. For now, here are two possible setups.
Whole dune workspace setup
Put the following in a dune (or dune-workspace) file at the root of the workspace
(env (_ (js_of_ocaml (flags (:standard --effects=double-translation)) (build_runtime_flags (:standard --effects=double-translation)))))
With this setup, one can use both separate and whole program compilation.
Sub directory setup
If you want to enable effect handlers for some binaries only, you'll have to give-up separate compilation for now using:
(executable (name main) (js_of_ocaml (compilation_mode whole_program) (flags (:standard --effects=double-translation))) )
Trying to use separate compilation would result in a error while attempting to link the final js file.
js_of_ocaml: Error: Incompatible build info detected while linking. - test6.bc.runtime.js: effects=disabled - .cmphash.eobjs/byte/dune__exe.cmo.js: effects=double-translation