Foreign Function Interface (FFI) Syntax
Alternate Backends
Besides compiling to Javascript, Purescript can also compile to other languages. See this link for a full list (may be outdated)
Syntax
This folder provides examples of FFI for simple cases regarding the JavaScript backend. However, see Wrapping JavaScript for PureScript for more detailed examples as to how to do FFI properly.
You should also look at the Purescript and Javascript source code for Effect.Uncurried:
Lastly, there may be some cases where you need to write FFI with Effect
, but Effect
isn't the best type to use. In such cases, take a look at Aff's FFI:
Using PureScript code within a JavaScript context
Imagine you defined a function in PureScript like gcd2
below that you wish to use in JavaScript code. What's a good practice to follow when calling that PureScript code from JavaScript?
$ cat src/GCD.purs
module GCD where
import Prelude
gcd2 :: Int -> Int -> Int
gcd2 n m | n == 0 = m
gcd2 n m | m == 0 = n
gcd2 n m | n > m = gcd (n - m) m
gcd2 n m = gcd (m - n) n
A good practice is to define a separate Interop
module that looks like this:
module GCD.Interop where
import Prelude
import GCD as GCD
import Data.Function.Uncurried (mkFn2)
gcd2 :: Fn2 Int Int Int
gcd2 = mkFn2 GCD.gcd2
The above code will get compiled to ./output/GCD.Interop/index.js
. So, in a JavaScript file, I would do the following:
import { gcd2 } from "./output/GCD.Interop/index.js";
gcd2(4, 5);
Defining an Interop
module comes with two benefits that occur if gcd2
needs to do some breaking change (e.g. changing its number/order/type of args and return value):
- If we have an
Interop
module, JavaScript consumers of the module don't have to account for breakage. Rather, theInterop
version can change how this breakage propagates to the JavaScript consumer. In many cases, such breakage can be hidden entirely. - If we have an
Interop
module, theInterop
module will produce a compiler error. This will remind us of every place where theInterop
code is used by JavaScript and force us to verify that the JavaScript usage of the PureScript code is still correct.