Skip to content

Golang interop

tim-hardcastle edited this page Sep 7, 2023 · 15 revisions

Charm is implemented in Go, and so has features for interoperating with Go that are different from the more generic ways in which you can interoperate with other languages.

The basic idea is that you can write the signature of a function in Charm, and then use the gocode keyword to write the body of the function/command in Go. The same keyword allows you to import a Go library. An example is given in examples/go.ch; the rest of this page will consist mainly of talking through it a bit at a time.

A basic function with a Golang body.

Let's ignore the part about imports for now and look at the first function in the def section:

def

fancy (s string) : gocode {
    return "**" + s + "**"
}

This has its signature written in Charm, but its body written in Go.

Such a function needs to have the types of its parameters specified. If string was left out of the example above, it wouldn't work. Go is a static language: it needs to know what type it's getting.

There is no need to specify return types. What the function returns is a Charm value, and Charm is a dynamic language.

Importing from Go

Now let's look at the import section at the top of the example script. We need the strings and errors libraries from Go for the examples coming up next:

import

gocode "errors"
gocode "strings"

Importing strings allows us to write the second example function in examples/go.ch:

contains(haystack, needle string) : gocode {
    return strings.Contains(haystack, needle)
}

raw

Because Charm is implemented in Go, you can use the raw suffix to pass to the Go routine Charm's internal representation of the value in question. The Go code has access to Charm's object module and so you can write things like this:

head (L list raw) : gocode {
    if len(L.Elements) == 0 {
        return errors.New("list has no members")
    } else {
        return L.Elements[0]
    }
}

Note that you should not use this feature until Charm's object module has a stable API. This is not yet the case.

Clone this wiki locally