UHC-like JavaScript backend in GHC

Jurriën Stutterheim j.stutterheim at me.com
Mon Nov 12 09:16:22 CET 2012


Hi all,


Last year, I worked on improving the Utrecht Haskell Compiler (UHC) JavaScript backend[1] up to the point where it is now possible to write complete JavaScript applications with it. Alessandro Vermeulen then ported one of my web applications to the UHC JS backend, and we've started using the result of that in production afterwards. The result of these efforts were presented at IFL 2012 and HIW 2012 by Alessandro and Atze Dijkstra respectively. One of the most powerful new features of this backend, in addition to the customised RTS, is the small subset of JS we can use when importing JavaScript functions with the "js" calling convention. For example, we can import the push() method for arrays using (roughly) the following import declaration:

  foreign import js "%1.push(%2)"
    push :: JSArray a -> a -> IO (JSArray a)

Here, we write a small expression in the import declaration, in which the object and arguments are numbered. The object argument, %1, corresponds to the `JSArray a` in the type signature of `push`, while the method argument %2 corresponds with the `a` in the type signature. Chris Done drew inspiration from this calling convention in designing the FFI for his Fay programming language[2].

One of UHC's nice features is that it is very easy to extend it, due to its heavy use of attribute grammars and its sophisticated variability management. Working on, and extending the UHC JavaScript backend was relatively easy because of this. One of UHC's downsides, however, is that it lags behind on supporting advanced language features, such as GADTs, functional dependencies, type families, etc. As a result, only a limited number of packages from Hackage can be compiled with UHC. In addition, some code requires additional workarounds and explicit type signatures, which would be redundant if, e.g., fundeps would be available.

In an ideal situation, we can have both the js calling convention from UHC's JavaScript backend, and GHC's more advanced language support. Combined, we can use most libraries on Hackage, we don't have to worry about the lack of language support while designing our JS applications, and we don't have to use explicit type annotations in scenarios where, e.g. fundeps, would un-ambiguate the situation quite easily. In the near future (i.e. after I have finished my MSc thesis), I would like to get started with getting more familiar with GHC's internals. In particular, I would like to see if it is possible to implement the js calling convention in GHC and have GHC spit out JavaScript, much like UHC is currently doing. Before I get started: does the GHC architecture currently allow for adding a new calling convention which departs from the conventional C FFIs and introduces a custom RTS? If not, where are the current major bottlenecks? And would it be possible to remove these bottlenecks, without significantly affecting the compilation times, and without affecting the performance of generated native code (when the JS backend is not used)?

Any input on this is appreciated :)

Cheers,


Jurriën


[1] http://uu-computerscience.github.com/uhc-js/
[2] http://fay-lang.org


More information about the Glasgow-haskell-users mailing list