Java 8 has an inbuilt JavaScript engine called Nashorn so it is actually possible to run Haskell compiled to JavaScript on the JVM.
The following program works:
{-# LANGUAGE JavaScriptFFI #-}
module Main where
foreign import javascript unsafe "console={log: function(s) { java.lang.System.out.print(s); }}"
setupConsole :: IO ()
foreign import javascript unsafe "java.lang.System.exit($1)"
sysexit :: Int -> IO ()
main = do
setupConsole
putStrLn "Hello from Haskell!"
sysexit 0
We can run it with: (Side note: It is possible to run this as a normal Java program.jjs
is just a convenient way to run pure JavaScript code on the JVM)
$ ghcjs -o Main Main.hs
[1 of 1] Compiling Main ( Main.hs, Main.js_o )
Linking Main.jsexe (Main)
$ which jjs
~/bin/jdk/bin/jjs
$ jjs Main.jsexe/all.js
Hello from Haskell!
In the above code, console.log
needs to be defined using java.lang.System.print
as Nashorn doesn't provide the default global console
object and Haskell's putStrLn
otherwise doesn't seem to be printing anything.
The other thing is that the JVM needs to be exited with sysexit
FFI function implemented with java.lang.System.exit
.
I have 2 questions:
- Similar to
console.log
, what other host dependencies are assumed in ghcjs that have to be defined? - Is the JVM not shutting down normally because of ghcjs creating an event loop in the background or some other reason? Is there any way to avoid that and make the program exit normally?