OCaml multicore, effects and js_of_ocaml

Effects are designated as the unifying force of Lwt/Async dichotomy (if I get it right), and if effects are not going to be supported on JSOO, a bunch of libraries will stay on Lwt because that still works there, continuing the ecosystem split.

Multicore itself seems orthogonal to effects, but imagine a library that wants to be thread safe and uses a bunch of mutexes internally. Nothing actually stops it from working on JSOO if JS runtime supports mutexes (actually this is what Gopherjs is doing - it runs multithreaded code in single threaded scheduler, and libraries designed for multiple threads can work on JS without extra effort in most cases).

1 Like

From what I understood, having effects would not really change anything w.r.t. Lwt/Async, they might just be ported over to work using effects going forward, but there would be no real change to their APIs.

Maybe I’m misunderstanding?

imagine a library that wants to be thread safe and uses a bunch of mutexes internally.

OCaml and Lwt both ship with a Mutex module (Mutex, Lwt_mutex). Do these not work on JSOO?

As I understand it, any code that uses effects at all won’t be compatible with jsoo, regardless of if it exposes or consumes those effects through a monad like LWT or Async.

Right now I think that even the multicore stdlib isn’t compatible.


There’s no really clean answer for jsoo compilation, with the best mechanism currently being a CPS translation which can “thread” the effect handling through the control flow of the program. As @patricoferris observes and has kindly forward ported, there is a prototype version of this that @Armael built while interning at OCaml Labs a few years ago. If someone wants to have a go at building a selective CPS version of this that is more efficient, then that’d be great.

Ultimately, our great hope is that wasm will take over from JavaScript as the compilation target of choice, and the effect handling story is much more rosy there. @kayceesrk has recently been active in the WebAssembly stacks working group, and there is an extension proposal in wasm that has the right primitives for efficient compilation of effect-handler-using OCaml to that.

Will wasm adopt the stack switching extension before OCaml 5.0 is out and we have a significant body of code using effect handlers? Only time will tell, as indeed will the number of motivated hackers who can work on either the jsoo or wasm compilation side to help advance the state-of-the-art here.


It would be useful to state the obvious first. If you don’t care about parallel domains and effect handlers, it should be fairly straight-forward to support jsoo complication for OCaml 5.0.

For effect handlers, CPS is one way to compile them. But there are also other strategies that @dhil, Sam Lindley, Bob Atkey, Jeremy Yallop and I explored a few years ago: https://www.dhil.net/research/papers/handlers_js-proweb2018.pdf. The gopherjs strategy for compiling go routines looks like trampolining, which is one of the strategies that we’d explored. Most of these compilation strategies tend to affect the performance of code that doesn’t use effect handlers since the transformations required to support suspending and resuming computations are program-wide. That said, it would be useful to replicate the experiments for OCaml 5.0 on jsoo as our experiments were not on jsoo (which can optimise whole programs) and JS engines get better all the time.

Wasm effect handlers make it almost trivial to compile OCaml effect handlers to them, but that is not something that can replace targeting JS in the short term. For one, there is no OCaml to Wasm compiler yet. :expressionless:


Right but unless I miss something it will break the current js_of_ocaml model which basically takes any OCaml bytecode to the browser (modulo C primitives/libraries).

This is a very good user experience as library authors do not need to care about JavaScript compilation. If you need to start tracking which libraries do use effects and does who don’t and live in the fear a library author might start to use them in the next version this is no longer nice :–)

Another thing is that according to what was answered to me here, accessing what you are actually interested in accessing when you compile for the browser – that is the browser APIs – doesn’t seem obvious/streamlined yet. I gather WASM is new and thus cool and all that, but without a good FFI to the browsers API it’s just a useless gimmick to me.


Fragmenting the already small OCaml ecosystem even further with the warning “don’t use effects for anything if any transitive user might want to use it in a web browser” feels like a last ditch resort. If we are forced down this road, we should make sure that the stdlib never uses effects, and that “uses effects” is tracked at the library level (via dune?) and enforced at build time so that people don’t accidentally pick up dependencies that use effects.

1 Like

There are already things in the ocaml library that you can’t use when compiling to javascript, including most relevantly the Thread module (at present non-parallel). When I last looked at it, also not available were most of the Sys module and all of Unix except time functions. I doubt adding effect handlers is going to surprise many people.


At Jane Street at least, the Unix and Sys modules are banned in libraries that claim to be jsoo compatible, and this is enforced at compile time (by shadowing those modules with empty modules).

I don’t think that Dune has this yet, but I think it would be valuable.

Edit: ok, not all of sys; lots of those functions are platform independent

1 Like

I don’t know what the Jane Street libraries do, but from my experience JSOO appears to give you a compile error if you call up functions in Sys or Unix which it has not wrapped, and ditto the Thread module. I imagine JSOO could do the same with respect to effects without great difficulty. I doubt that dune has to do anything.

I imagine that what would make support for effects desirable in JSOO is a situation where Lwt moves from a monadic implementation to effects. At some point I suspect that will happen.

That’s not the point.

Sniffing uses of system/C libraries is easy to do. Sniffing uses of effects, a language construct which could well be used only internally by a library is an entirely different thing.


As JSOO converts from ocaml bytecode to javascript, wouldn’t there be something in the bytecode to alert JSOO that there is something it can’t deal with (in this case, the use of effects), and error out? If you say no I believe you: I don’t know enough about ocaml’s bytecode to form a view.

Of course it will (and it likely already does).

But again that’s not the point. The point is that currently, the powerful promise of js_of_ocaml is: if you have pure OCaml code we guarantee you can compile it to JavaScript. If effects are not supported that’s no longer the case and makes js_of_ocaml a much less reliable tool.


Agreed. Throwing an exception when an unsupported API is called is one thing, but missing entire language features is another.

I am afraid I have lost the ability to understand the point. You seemed to suggest first that there as a difficult in “sniffing” uses of effects, which would be a problem for JSOO. You now seem to suggest above that there isn’t.

For what it is worth, I was referring to the fact that not all ocaml code can be compiled to Javascript at the moment anyway. Possibly by “pure” you mean “not including ocaml library modules wrapping system specific (that is, POSIX specific) functionality”. If so then I was suggesting that one could add “effects” to the list without surprising a user.

I understand that effects are a language construct and not something implemented in a module in the ocaml library. I also understand the desirability of supporting effects in JSOO. If that is all there is to be said then I am not sure there is anything left of substance so let’s leave it here.

Sorry, I defer to @TyOverby which said it in a much more concise and eloquent way than I did :–)

Not in a programming language that supports abstraction.


If this is a last-ditch resort, then why is the discussion here focussing on that rather than the rest of @kayceesrk’s message, which is a list of techniques to support js compilation for effects? And not just one technique like CPS – but five! It would be nice to see a spirit of adventure with this exciting new feature and the community pitching in with ideas and prototypes to explore how to get jsoo up to speed before effects land in a mainstream OCaml compiler.

The multicore and core OCaml dev teams are pretty busy in the short-term with the rather large amount of work required to get the native ecosystems ported over, so I’d very much welcome efforts in this direction from those interested in the web ecosystem.


Because as can be seen by the discussion in question. No everyone does seem to understand the implication on the user experience of js_of_ocaml which is not so well summarized by:

(P.S. this reply was intended to the general addition to the thread and not a specific reply to @avsm )

Look at Kotlin – it supports JVM/Javascript/Native. See kotlin-stdlib - Kotlin Programming Language (with the various color codes corresponding to the platform) you have this messy matrix of which features/APIs are supported for which platform. As you can imagine it requires a lot of engineering effort to maintain this and test this as each of the platforms that Kotlin runs on keeps evolving and getting more specialized and complex. Without the might of a organized effort (and funding) I doubt that JS/Wasm generation will be a first class citizen for OCaml in the long term.

Even if we can transpile effects from Ocaml bytecode to Javascript (and WASM in the future), its going to be full of edge cases and surprises and debugging problems. It is tough enough to debug JSOO in the browser, imagine throwing non-local control flows into the mix and debugging that.

JSOO came at a lucky time when the OCaml runtime was simple enough that ocaml bytecode could be translated to Javascript without many compatibility issues. That time is over, in my opinion.

OCaml should concentrate on being the best backend platform it needs to be. After having explored this space, I personally see a lot of issues for a JSOO approach going forward. Its too heavyweight. I think something like Rescript (Bucklescript) is more likely to succeed. It would have been great to have a Rescript (Bucklescript) as a first class citizen in the OCaml tree. But that again gives rise to the huge engineering complexity that Kotlin has had to take on and this messy matrix of what works and what does not on the platform you want to emit for, separate standard libraries etc.

So its a good thing in some way that OCaml can aspire to be excellent in a few domains instead of average in many. Javascript/WASM emission is always going to be full of problems – I don’t think OCaml is the answer in the future here, though there might be some cool developments along the way. Just my view…


its going to be full of edge cases and surprises and debugging problems. It is tough enough to debug JSOO in the browser, imagine throwing non-local control flows into the mix and debugging that.

I don’t know about the state of debugging jsoo in the browser, but non-local control flow and debugging doesn’t need to be hard. For one, Multicore OCaml produces sensible backtraces under non-local control-flow both within the runtime’s own mechanism (such as backtraces with exceptions) and using DWARF (backtraces in gdb and lldb). Yes, Multicore OCaml maintains its own stacks, which make the job easier. I believe C# and Kotlin (which is mentioned in the parent comment), which turn the function in “state machines” (essentially a form of CPS), are also able to recover backtraces for coroutines and async-await. It is a bit of work, but that’s work that is already being done in many other languages.

No everyone does seem to understand the implication on the user experience of js_of_ocaml which is not so well summarized by:

I don’t see why this is harder than what the state of jsoo is currently for the OCaml standard library. There is no syntactic addition for effect handlers in OCaml 5.0. There is just a new stdlib module Effect_handlers that adds effect handler functionality. Just like how Weak and Sys models are not supported, Effect_handlers would be unsupported until jsoo implements support for it. Am I missing something?