Note

Some of the information here is outdated. Follow the installation instructions in the README. Using a virtual machine is no longer recommended and the ghcjs-build repository is no longer maintained.

Updated examples can be found in the ghcjs-examples repository, or click the source link. The safety specifications in the JavaScript foreign function interface have been changed slightly, see GHCJS.Foreign for more information. In particular, you need "interruptible" instead of "safe" for asynchronous imports.

introduction

After many months of hard work, we are finally ready to show you the new version of GHCJS. Our goal is to provide a full-featured Haskell runtime in the browser, with features like threading, exceptions, weak references and STM, allowing you to run existing libraries with minimal modification. In addition we have some JavaScript-specific features to make communication with the JS world more convenient. GHCJS uses its own package database and comes with Cabal and Template Haskell support.

The new version (gen2) is almost a ground-up rewrite of the older (trampoline/plain) versions. We built on our experience with the trampoline code generator, by Victor Nazarov and Hamish Mackenzie. The most important changes are that we now use regular JavaScript objects to store Haskell heap objects (instead of JS closures), and that we have switched to explicit stacks in a JavaScript array. This helps reduce the amount of memory allocation considerably, making the resulting code run much faster. GHCJS now uses Gershom Bazerman’s JMacro library for generating JavaScript and for the Foreign Function Interface.

This post is a practical introduction to get started with GHCJS. Even though the compiler mostly works now, it’s far from finished. We’d love to hear some feedback from users and get some help preparing libraries for GHCJS before we make our first official release (planned to coincide with the GHC 7.8 release). I have listed some fun projects that you can help us with at the end of this post. Join #ghcjs on freenode for discussion with the developers and other users.

Some highlights of the new version:

Easier installation, the compiler is now standalone, with its own package database. Install the compiler with cabal install ghcjs , install packages with cabal install --ghcjs myPackage ,

, install packages with , Everything works on 64 bit machines, generated JavaScript is the same as on 32 bit,

New JavaScript FFI calling convention, with convenient import patterns and asynchronous FFI,

Much improved performance compared to the older trampoline version, while still doing full tail-call optimization,

version, while still doing full tail-call optimization, Improved threading with black holes, asynchronous exceptions and STM,

The scheduler yields during long computations, to keep the browser responsive and able to handle events, even during long calculations,

Better and faster Integer/big number support through JSBN,

Easier command line testing with Node.js and jsshell,

An extensive testsuite with benchmarks (includes much of the GHC testsuite and nofib).

Some work still remains:

Cabal support is incomplete, in particular bundling JS files with cabal packages is not yet supported,

Our dataflow analyzer needs some more tweaks to make the generated code smaller, also some metadata is currently encoded inefficiently,

The front end ( ghcjs executable) needs some work, for example to only recompile changed files,

executable) needs some work, for example to only recompile changed files, The linker is too simple, it only supports linking everything referenced by main to one big file, some improvements, including incremental loading, are planned,

to one big file, some improvements, including incremental loading, are planned, Some debug tracing code cannot be fully disabled, making some parts of the RTS run slower than necessary.

More optimization is required to increase compilation speed and reduce memory consumption when compiling very heavy packages like haskell-src-exts .

. Unboxed arrays are implemented with DataView, using big endian byte ordering. Since most clients are little endian, and JavaScript libraries tend to expect native byte order, we are going to switch to typed array views and little endian.

installation

GHCJS depends on a patched GHC HEAD (7.8) to support some of the new improvements, like the javascript calling convention. In addition to that, you need a patched Cabal library and cabal-install which adds the GHCJS compiler flavour. We hope to have these patches merged before the first release in September, but unfortunately that means that it’s not yet possible to just cabal install the compiler.

The easiest way to install GHCJS is with the vagrant setup script from the ghcjs-build repository. This builds a virtual machine with a fully working installation, and includes some examples.

Building is very easy, just run the following commands after installing vagrant:

# git clone https://github.com/ghcjs/ghcjs-build.git # cd ghcjs-build # git checkout prebuilt # vagrant up

This downloads prebuilt binaries from our server. If you want to build everything from source, use this instead (warning, can take 3-4 hours):

# git clone https://github.com/ghcjs/ghcjs-build.git # cd ghcjs-build # vagrant up

After the build has finished, log into the newly created virtual machine:

# vagrant ssh

GHCJS should now be installed:

# which ghcjs /home/vagrant/.cabal/bin/ghcjs

All the examples in the rest of this post are available in /home/vagrant/ghcjs-examples/weblog in the vm, and on github. Exchanging files between the vm and the host is easy: The directory containing the vagrant setup script is mounted under /vagrant in the vm, so just copy files there.

first steps

You can now test the installation by compiling a simple Haskell file:

module Main where main = putStrLn "Hello, world"

Compile it and run the result with Node.js and jsshell (both preinstalled on vagrant):

# ghcjs -o hello hello.hs [ 1 of 1] Compiling Main ( hello.hs, hello.o ) [ 1 of 1] Compiling Main linking hello.jsexe: Main # node hello.jsexe/all.js Hello , world # js hello.jsexe/all.js Hello , world

The example also works in the browser. You need a web server to run it. The warp server from the warp-static package is very convenient for this. It comes preinstalled on the vagrant vm. Run the following on the host, from the ghcjs-build directory:

# vagrant ssh -c warp

Warp now listens on port 3000 and serves the home directory in the vm. Port 3030 on the host is remapped to this port on the virtal machine, so you should open http://localhost:3030/ on the host to see the examples. You can find the hello example at http://localhost:3030/ghcjs-examples/weblog/hello/hello.jsexe/ .

putStrLn will print to the JavaScript debug console in the default configuration (you can redirect the output, but that’s a topic for a later post), so you need to open that first to see the result. Here’s what it should look like in Chrome:

GHCJS produces several files when compiling an executable. The most important one is out.js which contains all the compiled Haskell code. The GHCJS linker starts with the main IO action and includes all its (function-level) dependencies in out.js . We have plans to add more options to the linker, including incremental loading. If you have specific needs or wishes, please let us know!

lib.js and lib1.js contain non-Haskell dependencies, including most of the RTS. The contents depend on the packages used by the program: All foreign dependencies of the program are included here. Currently this is done through the yaml descriptions in the shims repository, but we want to add support to Cabal to include the .js files directly in packages. File lists lib.js.files and lib1.js.files are included to support custom build systems, for example if you want to load some of the dependencies from a different location.

rts.js is a static file, generated by the compiler, which has lots of functions used by the Haskell runtime system. It’s the same for every program, but it might change depending on the debug options GHCJS is compiled with.

file description all.js combined lib.js , lib1.js , out.js , and rts.js , runnable with Node.js and jsshell. lib.js RTS and non-Haskell functions (this contains most of the RTS, including the scheduler) lib.js.files list of files in lib.js lib1.js RTS and non-Haskell functions that must be included after rts.js lib1.js.files list of files in lib1.js out.js compiled Haskell code rts.js JMacro generated part of the RTS index.html a sample HTML file that runs the main IO action

The HTML file below is the default HTML generated by GHCJS. It runs the main IO action h$mainZCMainzimain (z-encoded main:Main.main prefixed with h$ ) with h$main , which starts a new thread labeled “main” . The thread is started in the background, h$main returns immediately. The Haskell runtime scheduler is started if it’s not yet running.

You can customize the HTML file, GHCJS does not overwite the file if it already exists.

<!DOCTYPE html > <html> <head> <script language= "javascript" src= "lib.js" ></script> <script language= "javascript" src= "rts.js" ></script> <script language= "javascript" src= "lib1.js" ></script> <script language= "javascript" src= "out.js" ></script> </head> <body> </body> <script language= "javascript" > h$main(h$mainZCMainzimain); </script> </html>

foreign function interface

Note: The foreign function interface has been changed and the information below is out of date. You need "interruptible" now for asynchronous imports. See GHCJS.Foreign for more information

One of the improvements in the new GHCJS is support for the new foreign import javascript calling convention. This not only gives us more convenient import patterns, inspired by UHC-JS and Fay, but also asynchronous FFI. foreign import ccall is still supported, for compatibility with existing libraries, which can be used unchanged if you provide JavaScript implementations of the foreign imports.

Let’s look at the next example. If you open it in a browser ( http://localhost:3030/ghcjs-examples/weblog/ffi/ffi.jsexe/ if you use the vagrant build) it prints the numbers 1. . 1000 to the document, one number per second.

module Main where #ifdef __GHCJS__ foreign import javascript unsafe "document.write($1+'<br/>');" writeNumber :: Int -> IO () foreign import javascript safe "setTimeout($c, $1);" delay :: Int -> IO () #else writeNumber = error "writeNumber: only available from JavaScript" delay = error "delay: only available from JavaScript" #endif main :: IO () main = mapM_ ( \ x -> writeNumber x >> delay 1000 ) [ 1 .. 1000 ]

writeNumber is a regular, synchronous, import. Placeholder $1 is replaced with the first function argument, an Int . It writes this integer and an HTML linebreak to the document using document.write .

The second import, delay , is an asynchronous import, indicated by the safe specification. An asynchronous imports get a callback parameter $c . The calling Haskell thread is suspended until $c is called, but other Haskell threads and JavaScript code continue to run (and the suspended thread can still receive asynchronous exceptions). This fits nicely into the common JavaScript pattern of doing IO asynchronously, reporting the results with a callback.

In the example, delay uses the JavaScript function setTimeout to call $c after $1 milliseconds, so it works more or less like threadDelay (GHCJS supports threadDelay more efficiently through its own scheduler though). Another example of this pattern can be found in the ghcjs-jquery ajax function.

FFI argument and result types

GHCJS FFI supports the same types as native GHC does for ccall foreign imports, with one addition, the JSRef type, defined in ghcjs-prim. JSRef is used to store arbitrary JavaScript values. When you enable the JavaScriptFFI extension, you can pass JSRef values to both javascript and ccall imports. The ghcjs-base package has some tools to manipulate JSRef values.

The FFI does marshalling for arguments the same way as the native GHC FFI does: If your foreign import has an Int argument, it gets a JavaScript number and not some thunk object.

Most numeric types are represented as a JavaScript number. Since JS doesn’t support single precision floating point, double precision is used everywhere. This can lead to results that differ slightly from GHC’s. If you return an Int or Word value, make sure that it’s an integer that fits in 32 bits. An easy way to do that is to return x|0 instead of x . The bitwise or operator forces the result to be a 32 bit integer.

Some FFI types don’t fit in a single JavaScript variable. For example the JS number type has only 53 bits of precision, not enough for Word64# and Int64# . These types are passed in two arguments with the ccall convention. With the javascript calling convention they get two placeholders, see below for an example.

JavaScript only supports signed 32 bit operands for its bitwise operations. Therefore any Word# value greater than 232 − 1 is represented by a negative number. The same goes for the two words in a Word64# and the least significant word in an Int64# .

Since JavaScript has no pointers, support for Ptr / Addr# is limited: Comparing pointers only works properly for pointers referring to the same data object, only the offsets are compared.

types primitive size JavaScript type Int, Int32, Int16, Int8 Int# 1 number Word, Word32, Word16, Word8 Word# 1 number (signed) Char Char# 1 number Int64 Int64# 2 number × number Word64 Word64# 2 number × number Ptr Addr# 2 object × number StablePtr StablePtr 2 object × number Array Array#, MutableArray#, MutableArrayArray# 1 array UArray, Vector, Text ByteArray#, MutableByteArray# 1 object (DataView) other MVar#, MutVar#, TVar#, Weak#, ThreadId#, StableName# 1 object JSRef ByteArray# 1 anything

When using the ccall calling convention, size-two values get passed in two arguments. If you return such a value, store the second part in the special global variable h$ret1 .

Both safe and unsafe ccall imports can call back into the Haskell runtime, but ccall imports are always synchronous.

foreign import ccall unsafe "plus" plus :: Int -> Int -> Int foreign import ccall unsafe "complement" negate :: Int64 -> Int64 foreign import ccall unsafe "f" f :: Ptr a -> IO ( Ptr b )

To avoid clashing with existing JavaScript names, all ccall imported functions (like the rest of the GHCJS runtime) are prefixed with h$ , which leads to the following JS implementation for the above imports:

function h$plus (x,y) { return (x+y)| 0 ; } function h$complement (x_msw, x_lsw) { h$ret1 = ~x_lsw; return ~x_msw; } function h$f (x_data, x_offset) { ... h$ret1 = new_ptr_offset; return new_ptr_data; }

If you use size-two values with the javascript calling convention, you get multiple placeholders, for example $1 and $1_2 ( $1_1 also works for the first value). Results are assigned to $r and $r_2 .

If the result size is 1, and the foreign import is synchronous, you can import a JavaScript expression and the result will be assigned automatically, like in the sin example below.

Imports are not restricted to simple statements and expressions. You can use loops, local variables and other JavaScript constructs. Thanks to JMacro, local variable names in the import are converted to hygienic names, so you don’t need to worry about existing local variables in the code.

foreign import javascript unsafe "$r = f($1, $1_2); $r_2 = h$ret1;" g :: Ptr a -> IO ( Ptr b ) foreing import javascript unsafe "Math.sin($1)" sin :: Double -> Double foreign import javascript unsafe "for(var i=0;i<$3;i++) { $1[i] = $2[i]; }" copyArray :: JSArray -> JSArray -> Int -> IO ()

See the ghcjs-jquery and ghcjs-canvas packages for more examples of foreign imports.

text and JavaScript strings

It is not possible to pass a Haskell String directly to JavaScript. The best way to do it is to convert the text to a JSString (which is a JSRef ) using the classes in GHCJS.Foreign.

toJSString converts the value to Text first, and then converts the underlying UTF-16 ByteArray# buffer to a JavaScript UCS-2 string. This means that working with Text is much faster than working with String.

foreign functions and packages

If your program or library requires some foreign code, the code must be added to the lib.js or lib1.js files for everything that depends on the package (or included in the HTML file manually). Unfortunately it’s not yet possible to include the foreign code in a Cabal package yet (it’s a planned feature).

As a workaround, we have the shims repository. It contains a yaml description file for every package, which references the required JavaScript files. When a package is then used, the files are automatically included in lib.js or lib1.js (in the same order as they are listed in the yaml file). Files referenced by multiple packages are included only once.

Please send us a pull request if you have added GHCJS support for a library. Package-specific support should go into pkg , general functionality to src . lib contains third party JavaScript libraries.

concurrency and exception handling

Threading in GHCJS is implemented in a way similar to the single-threaded GHC runtime: There is one system thread on top of which multiple lightweight Haskell threads run. Long Haskell computations are interleaved by the preemptive scheduler in the runtime system, which also yields occassionally to let the browser run event handlers and other JavaScript code. Since JavaScript does not have shared-memory parallellism, operations like par are no-ops in GHCJS.

Keep in mind that long-running JavaScript computations (called through the FFI or directly outside of Haskell code) will block all Haskell threads, as well as event handling for the browser itself. It’s best to run these things in an incremental way, or to move the whole calculation to a Web Workers process.

Other than this, threading works exactly the same as it does for native code with GHC, including support for MVar , STM ( atomically , TVar ) and more advanced data structures like Chan and TChan based on those.

The example below ( /home/vagrant/ghcjs-examples/weblog/race ) starts 10 threads that each update the position of a red square on a “race track”. The call to threadDelay after each update makes the scheduler switch to a new thread immediately, creating a smooth animation. Other than the GUI, which is browser specific, this is exactly how you would write a native Haskell program.

module Main where import Control . Monad import Control . Concurrent import GHCJS . Foreign import GHCJS . Types #ifdef __GHCJS__ foreign import javascript unsafe "document.getElementById($1).style.left = '' + $2 + 'px'" setPos :: JSString -> Int -> IO () #else setPos = error "setPos: only available in JavaScript" #endif main :: IO () main = mapM_ runRacer [ 1 .. 10 ] runRacer :: Int -> IO () runRacer n = void $ forkIO $ do doRace ( toJSString $ "racer" ++ show n ) doRace :: JSString -> IO () doRace str = go ( 0 :: Int ) where go n | n > 800 = go 0 | otherwise = do setPos str n threadDelay 1 go ( n + 1 )

The HTML for this example contains the race track and some extra elements for the red squares:

<html> <head> <script language= "javascript" src= "lib.js" ></script> <script language= "javascript" src= "rts.js" ></script> <script language= "javascript" src= "lib1.js" ></script> <script language= "javascript" src= "out.js" ></script> <style> div .track { width: 800px ; height: 30px ; border: 1px solid black ; position: relative } div .racer { background-color: rgb(255 , 0 , 0) ; width: 20px ; height: 20px ; position: absolute ; top: 5px } </style> </head> <body> <div class= track ><div class= racer id= racer1 ></div></div> <div class= track ><div class= racer id= racer2 ></div></div> <div class= track ><div class= racer id= racer3 ></div></div> <div class= track ><div class= racer id= racer4 ></div></div> <div class= track ><div class= racer id= racer5 ></div></div> <div class= track ><div class= racer id= racer6 ></div></div> <div class= track ><div class= racer id= racer7 ></div></div> <div class= track ><div class= racer id= racer8 ></div></div> <div class= track ><div class= racer id= racer9 ></div></div> <div class= track ><div class= racer id= racer10 ></div></div> </body> <script language= "javascript" > h$main(h$mainZCMainzimain); </script> </html>

exception handling and blackholes

New additions in the latest GHCJS version are support for blackholing and asynchronous exceptions. Blackholes are important for avoiding some kinds of memory leaks, help detect infinite loops (the <<loop>> exception) and prevent duplicate work when multiple threads try to evaluate the same thunk. Asynchronous exceptions are used to interrupt threads during a computation or while waiting on a blocking operation (async foreign call or MVar operation for example).

The example below demonstrates these features. main runs a loop, starting a thread to compute fib38 and print the result. After one second, the main thread throws an asynchronous exception to the forked thread. If the thread hasn’t finished computing and printing fib38 by that time, the running computation is suspended and the exception handler prints “not finished”. The next iteration, the fib38 computation is resumed from where it was interrupted.

Therefore, the example should print “not finished” a few times (depending on the speed of your computer and JavaScript engine). Eventually, the fib38 thunk is updated with the result, so the forked thread will just print the value every time from then on.

module Main where import Control . Concurrent import qualified Control . Exception as E import Control . Monad fib :: Int -> Int fib 0 = 0 fib 1 = 1 fib n = fib ( n 1 ) + fib ( n 2 ) fib38 = fib 38 printFib = print fib38 ` E . catch ` \ ( _ :: E . SomeException ) -> putStrLn "not finished" main = forever $ do tid <- forkIO printFib threadDelay 1000000 throwTo tid E . Overflow

System.Timeout uses the same technique as the example, and also works with GHCJS. Interrupting computations not only works for pure code like fib38 , but also for IO operations like asychronous FFI calls and waiting for an MVar.

For more details on black holes, see Runtime Support for Multicore Haskell. GHCJS implements eager blackholing (the default setting for GHC is lazy blackholing), since it has no control over the JS garbage collector.

synchronous threads

The threads we have seen so far were all asynchronous: They are started with h$main or h$run , both of which take an IO action and start a new thread that runs the action in the background. This allows the Haskell runtime to provide asynchronous IO and keep the browser responsive by yielding during long calculations.

Usually this is what we want, but it does have one disadvantage: We cannot get any result back from the call, the Haskell thread might not even have started yet when h$run returns. In most cases this is no problem, since Haskell can call back into JavaScript and we can supply a callback function.

Sometimes we need results immediately though, for example if we want an event to stop propagating from an event handler, we must call event.stopPropagation() before returning from the handler. Clearly, h$run will be of no use if we need to call into Haskell to decide whether to stop propagation of the event.

The alternative is to start the thread with h$runSync , which tries to run the thread to completion before returning. If the thread is not finished before the h$runSync call returns, it throws an exception:

call result h$runSync(action,false) run action in a synchronous thread, abort the thread if it tries to do an unsupported operation h$runSync(action,true) run action in a synchronous thread, continue the thread asynchronously after it does an unsupported operation

Unfortunately, synchronous threads have a few limitations due to JavaScript’s single threaded execution model. The most important limitations are listed below:

operation result block on MVar synchronous thread is interrupted (If the MVar operation does not block, it works as expected). threadDelay , yield synchronous thread is interrupted. asynchronous FFI or IO synchronous thread is interrupted. enter a blackhole from another thread The other thread is continued temporarily to finish computing the blackhole (might switch to other threads if this thread is also waiting for other blackholes). Synchronous thread is interrupted if the other thread tries to do an unsupported operation or has pending async exceptions. async exception not supported in synchronous threads.

In general it should be predictable whether an action is safe to run in a synchronous thread. Be careful with lazy IO and unsafePerformIO though.

The example below takes a JavaScript object, wrapped in a JSRef , it reads the input from the input property, calculates the factorial, and stores the result in the output property of the same object.

module Main where import GHCJS . Types import GHCJS . Foreign import Data . Text ( Text ) import Control . Applicative import Text . Read ( readMaybe ) main = do o <- newObj setProp ( "input" :: Text ) ( "123" :: JSString ) o factorial o r <- getProp ( "output" :: Text ) o putStrLn ( fromJSString r ) factorial :: JSRef () -> IO () factorial ref = do x <- fromJSString <$> getProp ( "input" :: Text ) ref let r = case readMaybe x of Just n | n < 0 || n > 5000 -> "invalid input" Just n -> toJSString . show . fact $ n Nothing -> "parse error" setProp ( "output" :: Text ) r ref where fact :: Integer -> Integer fact n = product [ 1 .. n ]

Our HTML sets up an event listener for a text field. The event listener builds an IO action by applying the factorial function to a JSRef object, which it then executes in a synchronous thread.

See below for more information about calling Haskell from JavaScript.

<!DOCTYPE html > <html> <head> <script language= "javascript" src= "//ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js" ></script> <script language= "javascript" src= "lib.js" ></script> <script language= "javascript" src= "rts.js" ></script> <script language= "javascript" src= "lib1.js" ></script> <script language= "javascript" src= "out.js" ></script> </head> <body> <input type= "text" id= "factorial_input" /> <div id= "factorial_output" ></div> </body> <script language= "javascript" > $('#factorial_input').on('keyup change', function(e) { var o = { input : $ ( '#factorial_input' ). val () }; h$runSync( h$c2( h$ap1_e , h$mainZCMainzifactorial , h$c1(h$ghcjszmprimZCGHCJSziPrimziJSRef_con_e, o) ) , false ); $('#factorial_output').text(o.output); }); </script> </html>

event handling and the DOM

A straightforward way to handle events is by registering an event handler that runs an IO action. If we run the action in an asynchronous thread, we get no guarantees about the order in which the events are handled, each handler runs independently in its own thread. With a synchronous thread, we would have to be really careful with blocking operations.

That’s why we take a different approach in the ghcjs-jquery package: Instead of starting a new thread to handle each event, we let the (JavaScript) event handler post the event to an MVar. A Haskell thread keeps consuming the events by taking the values from the MVar. This way, all events are always processed in order, and the overhead for processing an event is kept low.

This approach cannot always be used, since no Haskell code can be run to decide whether to stop propagating the event.

Below is a simple example using ghcjs-jquery to handle events, using the MVar approach under the hood:

module Main where import JavaScript . JQuery import JavaScript . JQuery . Internal import Data . Default import qualified Data . Text as T main = do b <- select "body" append "<div class='mouse'></div>" b m <- select ".mouse" mousemove ( handler m ) def b handler :: JQuery -> Event -> IO () handler m e = do x <- pageX e y <- pageY e setText ( T . pack $ show ( x , y ) ) m return ()

And the HTML:

<!DOCTYPE html > <html> <head> <script language= "javascript" src= "//ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js" ></script> <script language= "javascript" src= "lib.js" ></script> <script language= "javascript" src= "rts.js" ></script> <script language= "javascript" src= "lib1.js" ></script> <script language= "javascript" src= "out.js" ></script> <style> html,body { height: 100% ; padding: 0px ; margin: 0px ; }</style> </head> <body> </body> <script language= "javascript" > h$main(h$mainZCMainzimain); </script> </html>

calling Haskell from JavaScript

The current API for calling Haskell from JavaScript is a bit primitive, this section will be updated when the API has been polished a bit more.

We have three functions that can run an IO action:

function result h$run run the IO action in a new asynchronous thread. h$main run the IO action in a new asynchronous thread labeled “main”. In Node.js and jsshell, the application exits when this thread finishes. h$runSync run a synchronous thread

If you don’t have an IO action, but a function that produces one, you can use the following method to apply the function:

x :: Int -> JSRef a -> IO ()

var x = 5 ; var y = h$c1 (h$ghcjszmprimZCGHCJSziPrimziJSRef_con_e, o) var action = h$c3 (h$ap2_e, h$MainZCMainzix, x, y); h$runSync (action, false );

The first argument, x is an Int , which can be passed directly to the Haskell function without additional wrapping. The second argument is a JSRef , which is constructed with the h$c1 function, producing a Haskell heap object with one field. The IO action is then created with h$c3 and h$ap2_e , creating a thunk that applies the h$MainZCMainzix function to the two arguments.

Since we work with Haskell data structures directly here, without going through the FFI, we often have to wrap arguments in a Haskell heap object. Some argument types can be passed directly though, like x in the example. Here is a list of types, and how they should be wrapped:

type wrapping Int, Int8, Int16, Int32, Word, Word8, Word16, Word32, Char, Double, Float Pass directly as a JavaScript number. Make sure that the number is a 32 bit signed integer for the integral types. All datatypes with one constructor and one Int# , Word# or Char# field should be passed this way, Bool Pass directly as false or true , Enumerations Enumeration ADTs: multiple constructors without fields. Use the constructors directly, or false , true for the first two constructors, respectively, primitive types No wrapping is needed, but make sure you use the right apply functions for size-2 values, everything else wrap in a Haskell heap object, using the h$c functions.

tasks and projects, help needed!

Here are some ideas for if you want to help us with the compiler and libraries. We also have some bigger projects going on. For example Dan Frumin is working on a pastebin site using diagrams and GHCJS to generate interactive widgets for Google Summer of Code. Hamish Mackenzie is working on JavaScriptCore and webkit binding to make building cross-platform applications that can run in the browser (with GHCJS) or in native code (with webkitgtk for the GUI) with minimal changes.

Contact us in #ghcjs on freenode for more project ideas, or if you want some pointers to work on the GHCJS core itself.