Progress update January 19, minimal web server success

Exciting tiny milestone alert! I can now compile a minimal-but-functional example web server from Braid to Go.

The following is the aforementioned Braid code:

module Main

extern type ResponseWriter = "net/http.ResponseWriter"
extern type Request = "*net/http.Request"

extern func fprintf = "fmt.Fprintf" (writer: ResponseWriter, str: string) -> ()
extern func handleFunc = "net/http.HandleFunc" (path: string, handler: func(ResponseWriter, Request)->()) -> ()
extern func listenAndServe = "net/http.ListenAndServe" (address: string, handler: ()) -> ()

let hello = (w: ResponseWriter, request: Request) -> (){
    fprintf(w, "Hello world!")

let main = {
    handleFunc("/", hello)
    listenAndServe(":8000", ())

And here’s its resulting Go code:

package main

import __go_fmt "fmt"
import __go_http "net/http"

type ResponseWriter = __go_http.ResponseWriter
type Request = *__go_http.Request

func hello (w ResponseWriter, request Request) () {
        __go_fmt.Fprintf(w, "Hello world!")


func main () {
        __go_http.HandleFunc("/", hello)
        __go_http.ListenAndServe(":8000", nil)


We can handle external types and use type annotations to make sure functions using external types are inferred and compiled correctly. We can also handle pointer types by appending an asterisk to the start of the external type’s import path.

Go 1.9’s type aliases made it easy to use our Braid-defined types everywhere internally, rather than rewriting all annotations from our internal type to the original Go type (which would’ve meant rewriting allĀ  request Request instances to request *__go_http.Request, for example). Thanks Go!

Although I didn’t realise it, Go doesn’t allow import statements after other statements, e.g. type declarations, so I had to add some very hacky sorting to make sure these are always at the top.

Finally, because Go functions can return nothing (rather than that being handled as a nil value), Braid can understand that it shouldn’t generate return statements for functions with a return type of unit, or where the last expression evaluates to unit.

With these changes, we can turn a single module of Braid into valid Go that compiles and runs a simple web server example. It’s small, but it’s a nice milestone.