I’ve been working on type inference this weekend, using a Hindley-Milner implementation I already had, but in Python. I did find some Go implementations on GitHub but, perhaps ironically, I find it easier to understand the Python version. I’m not fully comfortable with Go yet.
Inference is not at all complete, but basic literals and variables work, so after:
let a = 5
let b = a
a is correctly an int, and so is
b. List literals are also correctly unified, so while
let a = [5, 6] works and creates a
list int type,
let a = [5, "nope"] produces an error.
This is small progress but quite encouraging. Hindley-Milner feels magical! And having implemented it for these basic cases has made me excited to keep going and finish the whole thing. Must find more time.
Progress is slow so far as I haven’t found a reliable way to fit regular work on Braid into my schedule. Building the apps that make the money is taking priority for now.
This weekend I finished parsing support for Algebraic Data Types (ADTs), both for definitions and for creating new literal instances. Record types map directly to Go’s structs, which is nice and easy, but sum types will require a more complicated combination of structs and interfaces to implement. At the moment these cannot be compiled properly unless they only use concrete types. The typical Option/Maybe type is not yet supported, as the Braid compiler lacks the means to determine which concrete versions it needs to generate based on where the type is used.
As this is my first update, I’ll be a bit more explicit about where everything is up to, and later updates will probably be more brief.
Braid, an ML-like language that compiles to Go, is still in the very early stages. For simplicity’s sake, I’m also writing it in Go, so both the compiler and the final language will be built on it. I’ve started with the front-end of the compiler, which means lexing and parsing source code into an AST. For lexing and parsing, I’m using Pigeon, a library for building Parsing Expression Grammars. Previously I’ve only used EBNF libraries, a fairly different way of building up grammar rules, so PEGs are a big change in approach for me. I’m still working my way along the learning curve.
I’m working on a language I’m calling Braid, an ML-like language that compiles to Go. Braid’s syntax is heavily inspired by Reason, itself a more C-like syntax on top of OCaml. So really I’m writing a language that aims to be fairly similar to OCaml in what it can do, but visually a bit closer to Go. I’m not trying to reimplement OCaml or Reason 1:1 on top of Go, but build something sharing many of the same concepts.