Can I use js_of_ocaml as a compiler in the browser?

I am working on a programming environment/new language that is meant to be used in the browser. Initially I thought I’ll implement a compiler by myself, but now I think this might be unnecessary (since my language is not innovative in this area).

Instead a new plan is emerging. Roughly looking like this:

  1. I’ll compile js_of_ocaml by itself and will get access to a compiler which can run in the browser. I hope this will give me access to OCaml’s type system, and to various optimizations. The bytecode is typed, right?
  2. I’ll create a minimal compiler/transpiler for my language that targets OCaml bytecode. It will be a curried, typed functional language (written in s-expressions for various reasons) and will probably use an effect system for side-effects (inspired by Eff).

Then I hope to be able to come up with a language that can be bootstrapped (and hopefully it will catch the attention of a couple of additional developers/dreamers who want to contribute, but that’s another topic) and continue its journey on its own.

Does this sound like a good plan?

1 Like

I don’t think Js_of_ocaml implements OCaml’s type system: it “only” compiles OCaml bytecode to JavaScript (types have already been checked at this point)… However, you could re-use parts of the OCaml compiler (and Js_of_ocaml to emit JavaScript) within your own.

Regarding the question in the title, check out https://try.ocamlpro.com/ (https://github.com/OCamlPro/tryocaml).

BuckleScript provides self-hosted OCaml compiler in browser, if you consider alternatives to js_of_ocaml. You could look how Klipses uses it: http://blog.klipse.tech/ocaml/2017/10/05/blog-ocaml.html

Thanks for the answers!

I have no previous experience with OCaml, but I have realized it has a lot of interesting qualities from my perspective. The modular compiler being one of them. But my understanding of how the compiler works is still really shallow. So right now I am trying to educate myself, with the help of the answers in this topic. I’ll probably be back with further questions.

BuckleScript seems interesting, though I am not sure it fits my needs. It definitely seems like the simplest option to use from the browser, but I also feel it’s a bit like a black box. Remember, I am not trying to compile OCaml (or Reason) and I don’t think I want to transpile to OCaml.

But lets say I’ll go for BuckleScript, is there a way to get access to the typed tree?

I’m not sure targeting the OCaml bytecode directly is the best idea for you. It might be better to use something like malfunction. You can then obtain the bytecode and pipe it to js_of_ocaml. With that process, you can bypass OCaml’s typing, which should be a good thing for you. Also, js_of_ocaml should be fairly robust to the tortuous bytecode that you might emit. :slight_smile:

If you value your sanity, don’t try to emit OCaml typedtree. That road lead only to madness and depression.

In any case, this plan is valuable only if you want your language to also be executable natively. If you only care about js execution … this is a bit roundabout. Just target js/wasm directly.

1 Like

My initial idea was to try to piggy-back OCaml’s type system, proper tail calls, maybe the pattern matching and various optimizations. But you think I should side-step the type system, right?

To be able to run the programs natively would only be a bonus, so this alone is not a valid reason to target the bytecode instead of JavaScript/WebAssembly.

Hmmm, food for thought. Thanks!

Those are disconnected problems.

If you want your own typesystem, which looks like you do, if you want something Eff-like, then trying to emit OCaml code mean you will have to encode things in order to please the OCaml typesystem. This is usually painful.

Hence the proposition to use malfunction, which uses the OCaml compiler after the types have been checked and remove. It still performs all OCaml’s optimization. The representation is “simply typed” (think C without implicit casts).

Ok, thanks! Yeah, I guess the problems are disconnected, but I was hoping to solve a bunch of problems in a single move.

I’ll take a closer look at how Eff is implemented. I was hoping Eff extended OCaml and that I could use a subset of the functionality for a first version of my language meant to be bootstrapped. But more of wishful thinking than deep analysis from my side …

You wrote I would loose my sanity if I tried to emit a typed parse tree, but what about an untyped one?
It seems possible. What problems will I face if I go this way and then try to extend the type system with effects? I feel you are trying to warn me for something I don’t see.

edit: I just realized there are effects for multicore OCaml, that are untyped. I guess they are untyped for a reason.