diff --git a/.gitignore b/.gitignore index 06565d0..7e5ed80 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ cw.tar .DS_Store /result-* /result +.#* diff --git a/blog/pahi-hello-world-2020-02-22.markdown b/blog/pahi-hello-world-2020-02-22.markdown new file mode 100644 index 0000000..a8db828 --- /dev/null +++ b/blog/pahi-hello-world-2020-02-22.markdown @@ -0,0 +1,169 @@ +--- +title: "pa'i: hello world!" +date: 2020-02-22 +series: olin +tags: + - 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"](https://innative.dev), 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][wasmer] project for a while and thanks to +their recent [custom ABI sample][wasmercustomabisample], 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][lojban] [rafsi][rafsi] for the word prami which means love. + +[wasmer]: https://wasmer.io +[wasmercustomabisample]: https://github.com/wasmerio/wasmer-rust-customabi-example +[lojban]: https://mw.lojban.org/papri/Lojban +[rafsi]: http://lojban.org/publications/cll/cll_v1.1_xhtml-section-chunks/section-rafsi.html + +[pa'i][pahi] is written in [Rust][rust]. It is built with [Nix][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: + +[pahi]: https://github.com/Xe/pahi +[rust]: https://www.rust-lang.org +[nix]: https://nixos.org/nix/ + +```console +$ 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][dhall] files +- building a small test runner + +[dhall]: https://dhall-lang.org + +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][pahidefaultnix], +bash, coreutils and `dhall-to-json` (which is required by the test runner). + +[pahidefaultnix]: https://github.com/Xe/pahi/blob/master/default.nix + +I'm actually really proud of how the documentation generation works. The +[cwa-spec folder in Olin][cwaspecolin] 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][cwans] [in Dhall][nsdhall]: + +[cwaspecolin]: https://github.com/Xe/olin/tree/master/docs/cwa-spec +[cwans]: https://github.com/Xe/pahi/tree/master/olin-spec#namespaces +[nsdhall]: https://github.com/Xe/pahi/blob/5ea1184c09df4e657524f9d5e77941cda5560d9a/olin-spec/types/ns.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][markdown] using +[`renderNSToMD.dhall`][shownsasmd]: + +[markdown]: https://github.github.com/gfm/ +[shownsasmd]: https://github.com/Xe/pahi/blob/5ea1184c09df4e657524f9d5e77941cda5560d9a/olin-spec/types/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][logns] as [this markdown][lognsmd]. + +[logns]: https://github.com/Xe/pahi/blob/5ea1184c09df4e657524f9d5e77941cda5560d9a/olin-spec/ns/log.dhall +[lognsmd]: https://github.com/Xe/pahi/blob/5ea1184c09df4e657524f9d5e77941cda5560d9a/olin-spec/ns/log.md + +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][compattodo]. 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][goflags], I might actually be able to get it mostly flag-compatible. +We'll see though. + +[compattodo]: https://github.com/Xe/pahi/issues/1 +[goflags]: https://crates.io/crates/go-flag + +I have also designed a placeholder logo for pa'i. Here it is: + +
![the logo for pa'i](/static/blog/pahi-logo.png)
+ +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][wingmakers]). The text on top of the microprocessor reads pa'i +in [zbalermorna][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". + +[wingmakers]: https://www.wingmakers.us/wingmakersorig/wingmakers/ancient_arrow_project.shtml +[zbalermorna]: https://mw.lojban.org/images/b/b3/ZLM4_Writeup_v2.pdf + +pa'i is chugging along. When I have closed the [compatibility todo +list][compattodo] 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. diff --git a/deps.nix b/deps.nix index 057d259..3d4b10e 100644 --- a/deps.nix +++ b/deps.nix @@ -257,8 +257,8 @@ fetch = { type = "git"; url = "https://github.com/prometheus/client_golang"; - rev = "v1.4.0"; - sha256 = "102x5qvnja9y3qx9vyr85rp3y63imk0rk73r91xzyhpp6mrcqfbh"; + rev = "v1.4.1"; + sha256 = "1kx461i7kw6y8s98774d0aasagzjh60ijsg3ikzxrfcc6adjmhz2"; }; } { diff --git a/static/blog/pahi-logo.png b/static/blog/pahi-logo.png new file mode 100644 index 0000000..180cc1b Binary files /dev/null and b/static/blog/pahi-logo.png differ