site/blog/pahi-hello-world-2020-02-22...

6.4 KiB

title date series tags
pa'i: hello world! 2020-02-22 olin
rust
wasm
dhall

pa'i: hello world!

It's been a while since I gave an update on the Olin ecosystem (which now exists, apparently). Not much has really gone on with it for the last few months. However, recently I've decided to tackle one of the core problems of Olin's implementation in Go: execution speed.

Originally I was going to try and handle this with "hyperjit", but support for linking C++ programs into Go is always questionable at best. All of the WebAssembly compiling and running tooling has been written in Rust, and as far as I know I was the only holdout still using Go. This left me kinda stranded and on my own, seeing as the libraries that I was using were starting to die.

I have been following the wasmer project for a while and thanks to their recent custom ABI sample, I was able to start re-implementing the Olin API in it. Wasmer uses a JIT for handling WebAssembly, so I'm able to completely destroy the original Go implementation in terms of performance. I call this newer, faster runtime pa'i (/pa.hi/, paw-hee), which is a Lojban rafsi for the word prami which means love.

pa'i is written in Rust. It is built with Nix. It requires a nightly version of Rust because the WebAssembly code it compiles requires it. However, because it is built with Nix, this quickly becomes a non-issue. You can build pa'i by doing the following:

$ git clone git@github.com:Xe/pahi
$ cd pahi
$ nix-build

and then nix-build will take care of:

  • downloading the pinned nightly version of the rust compiler
  • building the reference Olin interpreter
  • building the pa'i runtime
  • building a small suite of sample programs
  • building the documentation from dhall files
  • building a small test runner

If you want to try this out in a more predictable environment, you can also nix-build docker.nix. This will create a Docker image as the result of the Nix build. This docker image includes the pa'i composite package, bash, coreutils and dhall-to-json (which is required by the test runner).

I'm actually really proud of how the documentation generation works. The cwa-spec folder in Olin was done very ad-hoc and was only consistent because there was a template. This time functions, types, errors, namespaces and the underlying WebAssembly types they boil down to are all implemented as Dhall records. For example, here's the definition of a namespace in Dhall:

let func = ./func.dhall

in  { Type = { name : Text, desc : Text, funcs : List func.Type }
    , default =
        { name = "unknown"
        , desc = "please fill in the desc field"
        , funcs = [] : List func.Type
        }
    }

which gets rendered to Markdown using renderNSToMD.dhall:

let ns = ./ns.dhall

let func = ./func.dhall

let type = ./type.dhall

let showFunc = ./renderFuncToMD.dhall

let Prelude = ../Prelude.dhall

let toList = Prelude.Text.concatMapSep "\n" func.Type showFunc

let show
    : ns.Type → Text
    =   λ(namespace : ns.Type)
      → ''
        # ${namespace.name}

        ${namespace.desc}

        ${toList namespace.funcs}
        ''

in  show

This would render the logging namespace as this markdown.

It seems like overkill to document things like this (and at some level it is), but I plan to take advantage of this later when I need to do things like generate C/Rust/Go/TinyGo bindings for the entire specification at once. I also have always wanted to document something so precisely like this, and now I get the chance.

pa'i is just over a week old at this point, and as such it is NOT feature-complete with the reference Olin interpreter. I'm working on it though. I'm kinda burnt out from work, and even though working on this project helps me relax (don't ask me how, I don't understand either) I have limits and will take this slowly and carefully to ensure that it stays compatible with all of the code I have already written in Olin's repo. Thanks to go-flag, I might actually be able to get it mostly flag-compatible. We'll see though.

I have also designed a placeholder logo for pa'i. Here it is:

the logo for pa'i

It might be changed in the future, but this is what I am going with for now. The circuit traces all spell out messages of love (inspired from the Senzar runes of the WingMakers). The text on top of the microprocessor reads pa'i in zbalermorna, a constructed writing script for Lojban. The text on the side probably needs to be revised, but it says something along the lines of "a future after programs".

pa'i is chugging along. When I have closed the compatibility todo list for all of the Olin API calls, I'll write more. For now, pa'i is a very complicated tool that lets you print "Hello, world" in new and exciting ways (this will change once I get resource calls into it), but it's getting there.

I hope this was interesting. Be well.