skydeck

Already a member? Login.

Skydeck Blog

ocamljs, OCaml to Javascript compiler

It can be hard to go back to a conventional language once you’ve enjoyed the freedoms of typed functional programming. That’s why, when we needed to write some Javascript at Skydeck, our first inclination was to find some way around it. Javascript is not such a terrible language—it has higher-order functions at least—but we missed the safety of static type inference and OCaml’s expressive features like variant types and pattern matching. So instead of writing Javascript, we wrote ocamljs, a back end to the OCaml compiler that generates Javascript.

We are proud to release ocamljs version 0.1 as free software. We are building Skydeck’s products on a foundation of free software (part of what makes OCaml such a great choice for us is its extensive library support) and we are very grateful to the developers of that software for making their work available. So we are pleased to contribute back to the OCaml community, and intend to continue doing so.

You can download ocamljs 0.1 here. This release is very preliminary and without question contains bugs, but we are using it successfully for production software, and we intend to continue to improve it. For the moment we have no mailing list or developer site for ocamljs, but you can send questions, bug reports, and patches to Jake Donham, jake dot donham at skydeck dot com.

Update 10/13/2008 There is now a Google Code project for ocamljs, along with a mailing list.

  • Wow! I just downloaded it and this seems a top quality work.

    Did you have access to some documentation on the internals of the ocaml compiler or did you just read the source code?

    In case you had access to docs, could you please tell me what you had to do to obtain it?
    If you just read the source would you like to write some documents (a tutorial or a blog post or whatever you like) explaining a bit the internals of the compiler?

    I'm working on a snippet manager to ease the distribution and reuse of ocaml code and to reduce the size of the binary by linking only those pieces of libraries that are used in your application and not the whole module. We already have a working prototype implementation using ocamldoc but we need to access the internals of the compiler to get a better tool. Our snippet manager will be released as free software.
    If you are interested I can provide you further details.
  • Jake
    I just read the source code; it is very clean. However, there is some documentation on the internals in the OCaml-Java project; see

    http://cadmium.x9c.fr/downloads.html

    Your snippet manager would be useful in ocamljs since minimizing the resulting Javascript is important for web apps.
  • Issac Trotts
    Nice stuff, thanks very much for implementing it. In the interest of making it even nicer, here's a bug report. It looks like there is a bug with support for closures, that could be fixed using the JS 'with' construct. For details, search for "(with" in http://blogs.bl0rg.net/netzstaub/2005/03/09/jav...

    let foo() =
    let a = ref [] in
    for i = 1 to 5 do
    a := (fun x -> x + i) :: !a;
    done;
    Array.of_list !a;;

    let foo_test() =
    let a = foo() in
    assert ((a.(0) 3) == 4);
    assert ((a.(1) 3) == 5);;

    foo_test();;
  • Issac, thanks for the bug report. I will try to get a fix released soon.
  • "with" in javascript is absolutely evil. The code should compile to someting like

    for (var i$60 = 1; i$60
  • I made you a bug report but your submission form has eated it.
  • Another try:

    The code should compile to someting like

    for (var i$60 = 1; i$60 <= 5; i$60++) (function() { var i$60$ = i$60; a$59 = $(_f(function (x$61) { return x$61 + i$60$; }), a$59)})();

    instead of

    for (var i$60 = 1; i$60 <= 5; i$60++) a$59 = $(_f(function (x$61) { return x$61 + i$60; }), a$59);

    Only functions, not blocks, are scopes in javascript.
    The assers in Isaacs code should obviously be

    assert ((a.(0) 3) == 8);
    assert ((a.(1) 3) == 7);;

    And print_int in ocamljs adds a newline that ocaml proper doesn't add.
  • Thanks Florian. I am working on a new release of ocamljs (see the Google Code link above) and will make sure this is fixed.
blog comments powered by Disqus