Freitag, 31. Mai 2013

Calling Idris from Javascript and vice-versa.

Until now the JavaScript backend for Idris has been a nice little gimmick to play around with, but when it comes to writing real applications it's pretty limited.
The limitations originates from the way how the FFI interacts with JavaScript. Until now it was not possible to call Idris code from within JavaScript which is essential when you want to register callbacks. In this blogpost I present my current work on the Idris FFI and JavaScript backend which enables this functionality. (Until these features have been merged into master you can track the development here)

Let's write a very simple piece of code that just changes a text label when it gets
clicked.

To do this we will need to define our onclick function. It'll look like this:


setOnClick : HTMLElement -> (() -> IO ()) -> IO ()
setOnClick (Elem p) f =
  mkForeign (FFun ".onclick=" [FPtr, FFunction FUnit (FAny (IO ()))] FUnit) p f

Let's break down what happens here. We are defining a function that takes an HTMLElement and a function that performs a side effect that should get executed whenever we click on the element. I'm using the FPtr type to represent a element. The name of the function tells the FFI that "onclick" is a field of an element. Whenever a name starts with a dot the FFI concludes that the first argument has to be an object and the name of the function is one of its fields. When the name ends with an equals sign it concludes that we are dealing with an assignment. In my previous blogposts I'm explaning how these mechanisms are used.
The second argument of our onclick function is of type "FFunction" takes an FUnit and returns a FAny (IO ()). mkForeign translates this into a function of type () -> IO (). For more information about the Idris FFI take a look at the tutorial. I've got a little bit of code on my gist that shows the FFI in action.

Have fun with calling functions back and forth :3