Not only is this extremely cool all by itself, it looks to be a perfect demonstration/example of extending codemirror to support a custom language, with a lot of the bells and whistles one would expect, and all via OCaml and jsoo. Outstanding!
Thank you, glad you like it! We’ve ended up where we are thanks to various bits of hacking from @tmattio, @jonludlam, @voodoos (and I’m sure others!) and of course the jsoo contributors. This is how the OCaml.org playground works (although I think it lost merlin.js in the switch to OCaml 5).
Another nice feature (thanks to @jonludlam!) that might not be immediately apparent is that all of the OCaml evaluation is happening in a browser worker meaning it never blocks the UI (the adventurous can try while true do () done ^^), which has nice story if we compiled notebook style exercises to the browser or something like that.
Yes, not being able to interact with the DOM is definitely a downside to this approach. There are some other upsides though, like dynamic loading of cmis/cmas - you can do synchronous fetches of remote files that you can’t do if the toplevel is running in the main page. This can cut the file size down by a surprising amount. I’ve got some patches almost ready that’ll do this for the playground on ocaml.org.
I’m curious how the current Try Eio evaluation works. Is it:
(1) we have an OCaml interpreter compiled to js, and it interprets the *.ml in the codemirror editor or
(2) the OCaml interpreter compiles the *.ml in the codemirror editor to js, then evaluates it ?
From @jonludlam 's comment above, it seems to imply (2), i.e. the ability to take the js, postmessage it to another iframe, and evaluate there. However, my current (possibly incorrect) mental model is (1), where since it’s an interpreter, there isn’t generated js code to ship – unless we move the interpreter itself.
I wonder if there is an example showing the complier running in the browser. What I mean is that an example where multiple .ml files (thus modules) in the virtual file system are compiled (by js_of_ocaml compiled OCaml compiler) and
allow merlin to type check module A that depends on module B while using signature information contained in the compiled b.cmi file.
Not exactly what you are asking for, but learn-ocaml does that kind of stuff, taking user-supplied ml code, applying some custom validations to its AST, then compiling and running it against a pre-defined solution. This and its sibling try-ocaml have had evaluation in a worker for a long time too — you can’t really ask students to reload the page after an accidental infinite recursion.
@patricoferris : I hope this does not come off as entitled / asking someone to do work for free. With the Try EIO example you have shared, can you provide a minimal example of *.ml code for doing self.postMessage ?
I know that the “OCaml interpreter” is being evaluated in a webworker.
I know that in regular JS, a webworker can send a message to parent via self.postMessage
I’m not familiar with the OCaml FFI; especially not in the case of jsoo.
I’m wondering if you could show minimal ocaml code (running in the jsoo / repl) which does the equiv of self.postMessage(…) [from webworker to parent]
The XY problem here is I’m planning on having the parent register a onmessage handler, then have the webworker (running jsso / ocaml repl) send it msgs via postMessage.