I'm on the Facebook Reason team, and we're using BuckleScript to compile OCaml into the best compiler output I've ever seen. People didn't recognize that my React components were generated, not hand-written.
BuckleScript's author (hongbo_zhang here) has been incredibly responsive and welcoming.
We'll be publishing the React.js binding on HN in a few days. Stay tuned! We (including Hongbo) are all sitting in irc #reasonml and https://gitter.im/facebook/reason
Reason describes itself as "a meta language toolchain to build systems rapidly", which seems a little vague to me. Am I understanding correctly that Reason is both a (kind of) alternative compiler for OCaml's build toolchain, and a dialect of OCaml in its own right?
To tie this back to Bucklescript, does this loosely describe the process of using Reason syntax to author Javascript? Reason file -> (Reason) -> OCaml executable code -> (Bucklescript) -> Javascript
Basically, just a new syntax and a blessed-stack approach that really, really emphasizes developer experience. Which is to say, ReasonML is merely a cosmetic and DX change, it remains compatible and is not a fork of OCaml at all.
There's a crucial distinction! OCaml's compilation command takes in a `-pp` flag (preprocessor), which accepts a command that takes in a file and outputs an OCaml AST tree. We're basically using that. In that sense, the official OCaml syntax is really just that: another syntax like Reason, but official, and goes back two decades.
I just wanted to say thanks to the authors of Bucklescript. Not sure if I'll ever get to use it in a production system, but definitely awesome tech. I played with it a little bit and I think an OCaml React app might actually compile faster than the same thing written in ES6 and compiled/built through the normal babel+webpack toolchain.
you should checkout reason, they are working on bindings using bucklescript. So it is not a dream, people probably can write react app using ocaml very soon
Hey, so when Ocaml comes out with modular implicits (hopefully soon!), will they be supported? If I recall correctly, Bucklescript is compiling Ocaml source, as opposed to Ocaml bytecode like js_of_ocaml does [this is incorrect, see below]. Assuming this is the case, I'd guess the downside is you have to specifically work to support potentially complex new features like modular implicits.
I think between modular implicits[0], multicore support (both coming soon), along with BuckleScript and js_of_ocaml, Ocaml will be the functional language to beat in the coming years.
0. For those unfamiliar with modular implicits (Scala has them), they are kind of like type classes, so we won't have to write things like "print_string" or "print_int" anymore; we can just write "print".
Edit: NEvermind, I see you're compiling the lambda IR. So hopefully support for modular implicits will be automatic!
> I think between modular implicits[0], multicore support (both coming soon), along with BuckleScript and js_of_ocaml, Ocaml will be the functional language to beat in the coming years.
Since you mentioned Scala ... you realize Scala has had those properties for years, don't you?
Yes, true. I'm probably overstating things. Just excited about the prospect of having these things in Ocaml. Scala is an impressive language but it's a big language. I prefer the relative simplicity of Ocaml and (even more) SML.
Also, performance-wise, with multicore and the new optimizations with flambda, Ocaml will be particularly interesting.
One question here: how tight the compiler is binded to OCaml semantics? Besides Reason, do you think it's possible to build a frontend for other languages and integrate the backend of BuckleScript to generate beautiful JS as well? Or in other words, what property do you think a language should have so we can generate this level of beautiful JS outputs?
BTW: Please understand I'm not objecting OCaml, I do believe OCaml is an awesome language, but my point is: if possible, we should make this beautiful backend for generating human-readable JS more accessible than restricting it to OCaml only, shouldn't we :)
OCaml compiler is designed in an extremely modular style. Actually you can design any syntax for OCaml (including lisp style) and produce the OCaml data structure, then it should work with BuckleScript, that's how Reason works
Are there internal projects inside Bloomberg that use this? It is really great and it is very impressive that it seems that you almost single-handedly did all this. I am curious what moved Bloomberg to start a project like this.
we have an intern this summer create bindings for our internal JS stack. we have some internal stuff running on server side in OCaml which we wish to move to client side.
I would say many thanks to my boss and employer's great support
How did you become so proficient with the OCaml compiler internals? When you started the project did you already know that you can compile to idiomatic js or was that discovered through experimentation?
Thanks! I have some experience in ocaml compiler internals, I reimplemented camlp4 called Fan. Yes, I made a prototype in 2 weekends and showed it to my boss and got very good feedback
It would have to be Core_kernel, the subset of Core that doesn't interact with the runtime or OS. I'm very curious about this and would like to know, too.
Indeed, js_of_ocaml is kind of shocking in its fidelity. It can compile even highly complex libraries that do lots of runtime tricks. Async_kernel and Incremental_kernel both compiled and worked without any issues whatsoever.
We've even built some support for making incrementally rendered web-apps in OCaml, using Async and Incremental. Here's a link:
It sounds like Bucklescript is doing something quite different, which is to aim for pretty JavaScript output, while compromising and maintaining semantic consistency with OCaml. I don't fully understand the use-case, but for us, js-of-ocaml is clearly the thing we want.
Uh, given that you don't respect ocaml's memory model and force -safe-string, that's just not true. Any Obj.magic that is correct in OCaml is probably not going to be correct in bucklescript.
`-safe-string` is the future. Any compiler can not guarantee its correctness if you write crazy code , `Obj.magic` here.
I am not interested in core personally, but I don't see any reason why it will not work if it is vanilla OCaml
This is really cool! I took some OCaml code I'd written a while ago and pasted it in and the output was shockingly legible even with the calls to functions in stuff like Caml_int32 and Pervasives. Very impressive!
much more readable transpiled output, really nice (and getting nicer) FFI to javascript.
but it doesn't interface with existing ocaml stuff as well (doesn't use `.cmo/.cma` so it needs to compile everything from source afaict)
People gave you the part in favor of bucklescript, so I'll give you the other side of the story:
bucklescript doesn't respect the OCaml memory model and runtime semantics, which makes it incompatible with some part of the ecosystem.
Js_of_ocaml already has various features that bucklescript doesn't have: dynlink, support for concurrency libraries such as lwt and async, etc. It's also much more stable and battle-tested.
to be precise, Js_of_ocaml does not respect OCaml memory model either, think about float. But I think Js_of_ocaml is really great, BuckleScript and Js_of_ocaml have different use cases.
I'm very optimistic about the future of these two projects. Both are working hard to build a soundly-typed platform on top of the JS ecosystem. While there are tons of existing languages that can be compiled to JS, the most successful ones are those (like Typescript) that embrace the npm ecosystem and the huge community investment it represents.
Both Bucklescript and Reason have a huge focus on seamless JS interop and DX, and stand a good chance of bringing soundly-typed functional programming to a much wider audience!
I was wondering about the practical differences between BuckleScript and js_of_ocaml. Found this brief explanation in the docs[0]:
> Js_of_ocaml takes lowlevel bytecode from OCaml compiler, BuckleScript takes the highlevel rawlambda representation from OCaml compiler
I presume that means different (higher-level) optimisations are available in BuckleScript?
> Js_of_ocaml focuses more on existing OCaml eco-system(opam) while BuckleScript’s major goal is to target npm
Now that is a good idea—npm is a fairly large ecosystem that people are already familiar with. If you haven’t already, you might look into using existing TypeScript interface files to get type information for npm libraries.
> Js_of_ocaml and BuckleScript have slightly different runtime encoding in several places, for example, BuckleScript encodes OCaml Array as JS Array while js_of_ocaml requires its index 0 to be of value 0.
Would it ever be feasible to support interop with js_of_ocaml?
This is one of the few JS compiled languages that interest me: Some of these languages add a very thin syntactic layer on Javascript and maybe a type system. If I wanted Javascript, I'd use Javascript, and if I wanted types, I'd use Flow, not a new programming language that's kinda-sorta-not-really JS.
That leaves this, Clojurescript, and SPOCK as the only really interesting projects. They all have runtimes that are unpleasantly large (well, Buckle may not), but that's the price of a new language.
However, Clojurescript leaves a bad taste in my mouth, and SPOCK stresses javascript implementations in interesting ways. I'm not really a fan of OCaml, but Buckle looks interesting, and more enjoyable/practical than the other two.
I've been using Elm for the last 2 weeks on a project and I love it. I still get slapped around all the time by the compiler, but at least I know my program won't have any run-time exceptions.
Well, first off, I don't really like Java or the JVM. That in itself is a pretty strong reason to not get into Clojure.
Secondly, I don't really like Clojure as a language: It's strongly opinionated, and made some unorthodox (for a lisp) design choices which I dislike.
Finally, Clojurescript is really heavyweight, dragging along not only its own runtime, but also the google closure library and compiler, making the entire system more complex than it needed to be (was there any reason we needed to have a closure dependancy?).
Don't get me wrong, Clojure isn't an objectively bad language, it's just a language I personally dislike. If you have similar tastes to me, you may not like it either. OTOH, You may thibk it's The Best Thing Since Sliced Bread (TM). That's fine, I just won't agree.
Not an expert, but having dabbled in cljs, I think this misrepresents it. The closure dependency makes things arguably heavier at dev time, but at compile time it allows for a lot of dead code elimination and other optimization that makes the actual output much more light weight. It doesn't slow down development, but allows for a much better product to be deployed.
I guess... but it's advertising to large teams, it seems java-oriented (so if I wanted that sort of thing, I could use Clojure), it's pushing an IDE, and it's from Red Hat, a company that has given us such marvellous technologies as networkmanager, rpm, dbus, systemtap, and systemd - so while not an awful track record, not exactly picking all winners either.
All in all, kind of neat, but that is just way too many red flags for me to say I'm bursting with anticipation to use it.
I suppose. But I'm not really the target audience: I'm more comfortable in Scheme than Haskell, and I'm willing to forgive JS most of its warts (especially since it's got proper HOF (better than Python and Ruby, anyways), and is getting TCO. It even has a macro system, courtesy of sweet.js (even if it is only a limited pattern-matching one, as opposed to the imperative systems of Lisp and most Schemes)).
do you have any uses in mind for F*? i went through the tutorial a while ago, and it looked very nice, but i couldn't think of anything i wanted/needed to use it for.
Why doesn't it actually curry? Impressive output, don't get me wrong. But given how native and idiomatic currying is in Javascript, and how much trouble I'd expect this to have taken to implement... is there a specific reason for this? Just curious.
Anyway, again: very impressive. Thanks.
EDIT clarification: I expected:
function f(param) {
return curry(32, param);
}
(or is this to highlight the difference between currying and partial function application?)
It looks like tail call optimization only works in simple situations.
let rec foo i = if i < 0 then "foo" else bar (i - 1)
and bar i = if i < 0 then "bar" else foo (i - 1)
function foo(i) {
if (i < 0) {
return "foo";
}
else {
return bar(i - 1 | 0);
}
}
function bar(i) {
if (i < 0) {
return "bar";
}
else {
return foo(i - 1 | 0);
}
}
It would be nice to get a warning when tail calls cannot be optimized.
yes, we will have this warning when upgraded into OCaml 4.04
Note that optimizing mutual recursive call is a very hard problem it needs VM level support
Seems like it should also be possible to have the compiler employ JavaScript generator functions (i.e. `yield`) and iteration as a substitute for growing the stack, which might be a bit more flexible than rewriting in terms of loops+thunks, though the concept is the same.
OCaml seems to be on an upswing in popularity/hype recently. As someone who's threading the waters in Clojure but not a fan of the JVM developer experience I'm curious why OCaml is a great choice.
I would love to hear some stories from people using it in production. I'm leaning towards wanting to use a LISP as it's just so elegant... but I feel that getting boggled down in "hard core" functional programming is a bit daunting and limiting.
I'm in the same mindset right now. Really like aspects of Clojurescript and its elegant syntax, but it's complicated machinery (JVM, Google Closure) make me wary. I'm sure they're well done, but because I'm mainly interested in the JS target, I'm open to something like Bucklescript, along with Elm, Purescript.
The website says BuckleScript can also be compiled into a unikernel, which links to MirageOS. I get the sense that integration between MirageOS unikernels and the javascript Bucklscript compiles down to is a likely usage-case scenario?
Definitely, almost half the time is spent in polishing the FFI. Check out the FFI section in the Manual.
OCaml's type system is so powerful, that it can model most js libraries without writing JS stubs code
BuckleScript's author (hongbo_zhang here) has been incredibly responsive and welcoming.
We'll be publishing the React.js binding on HN in a few days. Stay tuned! We (including Hongbo) are all sitting in irc #reasonml and https://gitter.im/facebook/reason