With multicore landing soon, and algebraic effects coming as the next step the question arises - how is this going to work with js_of_ocaml backend? Gopherjs (Golang to JavaScript transpiler) boasts support of Goroutines and it really works in practice. Are there any plans to introduce similar transformations for green threads in OCaml with effects?
@avsm is there some game plan for JS compilation in OCaml 5+? js_of_ocaml multicore support issue references some relevant work by OCaml multicore project participants, but itâs unclear if that work succeeded or where it can be tracked. JS target is important for significant part of OCaml community and I thing some visibility on whatâs happening or whatâs going to happen with this would be much appreciated.
Iâm not aware of any formalised game plan. Originally to get effects in jsoo there was the approach @Armael implemented using CPS which I then tried to port to js_of_ocaml.3.9.0
and 4.12+domains+effects
(see here). The major downside is that the CPS code is slow (and adds some time to jsoo compilation). I remember reading/being told that this can be improved by doing a selective CPS. Just to clear this wasnât a planned bit of work, more just me experimenting in my own time :))
EDIT: Iâll add this to that tracking issue
I wonder how critical it is to get multicore working for JSOO, given that JS runtime itself is single-threaded? Doesnât Lwtâs concurrency model make much more sense for targeting JS? Also considering the fact that JS platformâs ânativeâ concurrency model is JS Promise, so shipping custom concurrency or multicore runtimes on top of that will only add layers of abstraction with no real benefitâŚ
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).
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.
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.
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
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.