Go-CoNLLU - Some Much Needed Machine Learning Support in Go
Python is commonly seen as the AI/ML language, but is often a dull blade due to unsafe typing and being slow, like really slow. Many popular natural language processing toolkits only have Python APIs, and we want to see that change. At Nuvi, a social media marketing tool, we use Go for the majority of our data processing tasks because we can write simple and fast code. Today we are open-sourcing a tool that has helped make our ML lives easier in Go. Say hello to go-conllu.
What is CoNLL-U?
The Conference on Natural Language Learning (CoNNL) has created multiple file-formats for storing natural language annotations. CoNLL-U is one such format and is used by the Universal Dependency Project, which hosts many annotations of textual data. To use these corpora, we need a parser that makes it simple for developers to utilize the data.

Universal Dependencies
How Does Go-Conllu Help?
Go-conllu parses conllu data. It is a simple and reliable way to import conllu data into your application as Go structs.
The GoDoc can be found here with the specifics
Let’s take a look at the example quick-start code from the Readme. First, download the package.
go get github.com/nuvi/go-conllu
Then in a new project:
package main
import (
"fmt"
"log"
conllu "github.com/nuvi/go-conllu"
)
func main() {
sentences, err := conllu.ParseFile("path/to/model.conllu")
if err != nil {
log.Fatal(err)
}
for _, sentence := range sentences {
for _, token := range sentence.Tokens {
fmt.Println(token)
}
fmt.Println()
}
}
All the sentences and tokens in the corpus will be printed to the console.
If you need a .conllu corpus file you can download the Universal Dependencies English training model here: en_ewt-ud-train.conllu
Related Articles
Go's WaitGroup vs JavaScript's PromiseAll
Jun 04, 2020 by Lane Wagner - Boot.dev co-founder and backend engineer
In applications that are i/o heavy, it can get clunky to synchronously execute high-latency functions one after the other. For example, if I have a web page that needs to request seven files from the server before it can show the page, I need to asynchronously fetch all those files at the same time. The alternative of making each request one at a time will take much too long. This is where JavaScript’s PromiseAll and Go’s WaitGroup come in.
How to Sort a Slice in Go
May 27, 2020 by Lane Wagner - Boot.dev co-founder and backend engineer
Sorting is a common task in programming, and for that reason, most languages have a default sorting algorithm in their standard library. Go is one such language. Go has gone about providing sorting functionality in one of the most elegant ways possible, via an interface.
Don't Go To Casting Hell - Use Default Native Types in Go
May 21, 2020 by Lane Wagner - Boot.dev co-founder and backend engineer
Go is strongly typed, and with that, we get many options for simple variable types like integers and floats. The problem arises when we have a uint16, and the function we are trying to pass it into takes an int. We find code riddled with int(myUint16) that can become slow and annoying to read. In other words, when Go developers stray from the “default” type for any given type family, the code can get messy quickly.
Rust vs Go - Which Is More Popular?
May 06, 2020 by Lane Wagner - Boot.dev co-founder and backend engineer
Go and Rust are two of the hottest compiled programming languages, but which is more popular, Go or Rust?. I develop in Go full-time and love it, and I’m learning more about Rust recently - it’s an exciting language. Let’s explore some differences between the two and look at which is growing faster in the popularity polls.