From the previous introductory post it might not be clear how to get started writing an actual program. Here I’ll describe how to quickly get started with a basic setup. This should be enough to bootstrap, without going so far as setting up an OTP application structure. The example can be found as a hello-world project.

We’re going to write a simple Hello World. Create a bower.json—you might run pulp init, but dependency versions will be wrong—and bower install.

  "name": "hello-world",
  "dependencies": {
    "purescript-console": "",
    "purescript-prelude": ""

Note that versions are not only based on URLs in the purerl organisation, but explicitly refer to #master—otherwise the latest tag will be used, which is merged from the main PureScript core repos.

We can just write a standard Hello World module:

module Main where

import Prelude
import Control.Monad.Eff (Eff)
import Control.Monad.Eff.Console (CONSOLE, log)

main :: forall e. Eff (console :: CONSOLE | e) Unit
main = do
  log "Hello Erlang!"

This will run just fine with the JS backend (eg pulp run) as the library forks referenced above still contain the JS FFI as well. To build with pserlc we use a command line as follows:

pserlc 'bower_components/**/*.purs' 'src/**/*.purs'

This will output .erl files in output/Main/main.erl etc. We can then compile those with erlc:

erlc -o ebin/ output/*/*.erl

We can then run the app itself. The main function is compiled as main in main.erl, which looks something like this:

main() -> ((control_monad_eff_console:log())("Hello Erlang!")).

We can run it from the command line:

erl -pa ebin -noshell -eval '(main:main())()' -eval 'init:stop()'

Notice the extra thunking, main/0 is a function which returns an Eff, which as usual is represented by a function itself.

I combine the above commands in a Makefile. See the hello-world project.

You may want to add tests. For now, purescript-assert, the low-level test library, is supported. See purescript-foldable-traversable for an example of this.