OCamlScript – a JavaScript back end for OCaml
github.com
github.com
We have multiple standard libraries, two concurrency library. It has damaged and divided the community significantly. And now two compilers to js ? :/
Before Babel for JS came out, there were tons of different solutions to compiling ES6 features into ES5, and the decision about which toolchain to use would fatigue newcomers to the community. But it was the fact that the community was relatively accepting of new spinoffs that Babel was able to gain momentum, and increase its quality to the point where it is the de factor tool that everyone uses - and it's really good.
As a consumer of the compiler, I don't necessarily consider multiple options a bad thing as long as something of really high quality emerges. (Although I can see how for something like an Async library (that introduces incompatibilities between dependencies) that would be particularly frustrating to have too many options)
It looks like OCamlScript used some good ideas from js_of_ocaml. Maybe js_of_ocaml can end up sharing some of the good ideas from OCamlScript so that it can also have very readable/debugable code and ecosystem integration?
And I think you have valid points. I'm curious though, since both js_of_ocaml have seamless interop with JS (seamless in terms of memory model), couldn't the two have seamless interop between each other by going through JS bindings?
I'm curious, do you think it's possible or practical to create an OCaml to JS compiler that has the strengths of both approaches?
At least for the integration between the js world and the ocaml world, I do believe it is possible. yes. For readability of the js produced, I really can't tell. It's probably pretty easy to improve js_of_ocaml on that though, given the current state. :)
Also, if it wasn't abundantly clear (to you or others) - I believe js_of_ocaml to be perhaps the best systems language compile-to-js toolchain that I've ever discovered (and I've looked extensively for others) - so I hope you can fully appreciate just how valuable it continues to be, to me personally and many others.
I have a question about your comment: "It's probably pretty easy to improve js_of_ocaml on that though, given the current state."
Would this also require patching the compiler to preserve record field names and avoid name mangling in general?
And I have a question about your comment on reddit which implies that maintaining a backend would be difficult to sustain: Do you believe that a seamlessly debuggable JavaScript backend, could generate the necessary amount of attention required to sustain such a backend, given how much more widely accessible end-end OCaml development would become as a result of its existence?
It seems like the primary difference is that the goals of js_of_ocaml gravitate more towards taking an app/library that had already been fully tested/debugged in OCaml and then running that thing in the browser with some nice debugging facilities that let you see the source code and kind of step through in the more rare event that something goes wrong.
I can't speak for this new approach here, but it seems to be more focused on using the JS target as the core development workflow for rapid iteration. I can see why that's appealing. Everyone knows how to use the browser debugger, and JS is one of most ubiquitous byte code formats ever. Running your OCaml app in the browser also gives you all kinds of really great timing and memory profiling tools that help you detect leaks (that even tells you something about the nature of your program when compiling OCaml to machine code).
Obviously, I wish there was a single toolchain that could actually do both though - a toolchain that you could use to get very JS-friendly code generation so the debugging/value printing/console inspection works just like it does in JS, but then would also let you do a js_of_ocaml style compilation based purely on an OCaml byte code object file (edit: or some kind of representation of the whole program) which would be free to remove and obscure record field names if it so chose.
(BTW: The difference in object representation (record field names are not obscured) seems to be the very thing that makes the values inspectable in the browser. Maybe there are some of OCamlScript's compiler patches that could be accepted in upstream ocaml so that the same can be achieved with js_of_ocaml?).
My issue here is that both are strictly incompatible and that you can't write FFI to a library for both.
Design goals here: http://bloomberg.github.io/ocamlscript/
Edit: I am a practical programmer, I am in favor of both for loop and recursion as long as it is readable
But my remark still stand: we now have two compilers to js, their API/FFI is not the same, so you can't factorize work, and the integration work could be made on js_of_ocaml too (see alain frisch's project).
I'd be curious to hear about the work that Alain is doing. Do you have a link?
This project has been released to exchange some ideas and collect feedback from the OCaml and JavaScript communities. It is still in an very early stage and more like research projects though we already had some good results.
Note that ocamlscript is inspired from typescript and js_of_ocaml, we like the readability of typescript generated js code, while don't want to loose the expressivity of a powerful langauge, ocaml, here in particular.
The main difference from js_of_ocaml is that js_of_ocaml maps the whole bytecode program into a js file while ocamlscript maps an ocaml module to es6 module.
Indeed, there is some difference in the runtime representation between js_of_ocaml and ocaml, for example, ocamlscript uses js string and array for ocaml string and arrray(we do this since we want an optimal js output at the price of a bit runtime incompability), this may make interaction between js_of_ocaml and ocaml a bit harder, but that's exactly why we made an early release to hear what other people may think. js_of_ocaml is an excellent project and we learned a lot from it and will seek some collaborations to share some workload.
OCamlScript does some cross-module optimization it seems. That's really cool, and js_of_ocaml does several optimizations as well, but for both approaches, it seems we'll not be able to take advantage of all really great f-lambda optimizations to come because they happen at a compiler stage after OCamlScript and js_of_ocaml have already intercepted their intermediate representations. Do you (or Drup) have thoughts on that?
The good news is that if you can achieve perfect compatibility with this approach, then I believe that runtime performance becomes less of a concern and OCamlScript's job gets a lot easier. This is because, if you've achieved perfect compatibility, you can easily compile your project with another toolchain such as js_of_ocaml, that has equal compatibility, but (in this hypothetical scenario) had chosen to focus more on performance instead of debugability - without changing anything in your program.
This would free you up to not have to worry about applying any optimizations in this readable/debuggable mode - you get to focus entirely on whatever makes the development flow faster/easier. (You'd probably still want tail call optimization because order of memory usage could be considered a key part of compatibility).
Similarly, I wonder if the existence of a fully compatible, (hypothetically) slow runtime performance, but perfectly debugable compiler backend, would then free up js_of_ocaml from some of the constraints/work that is required to make their code output reasonably simple/debuggable. Does the existence of a fully compatible OCamlScript mean that js_of_ocaml's job gets easier?
I'm excited to discuss how the two projects could potentially become an asset to each other.
edit: I started a discussion on Github here: https://github.com/bloomberg/ocamlscript/issues/12
SMLtoJS (whose site at http://www.smlserver.org/smltojs/ perhaps ironically seems to be down at the moment), which compiles the full Standard ML language (though not the full Basis library)
Yetiscript (https://www.npmjs.com/package/yetiscript) which compiles (a very close approximation of) the Yeti language (http://mth.github.io/yeti/)
Looks like there are some F# options as well, though I haven't tried any and I don't know what the relationship between e.g. Websharper and Funscript is.
Any others?