Add Result types and pattern matching to Go without breaking compatibility
GitHub RepoImpressions7.2k

Add Result types and pattern matching to Go without breaking compatibility

@githubprojectsPost Author

Project Description

View on GitHub

Bringing Rust-Style Results to Go with Dingo

If you've ever written Go, you've dealt with error handling. It's straightforward, but sometimes you find yourself wishing for something more expressive—like Rust's Result type or proper pattern matching. What if you could have that in Go without breaking backward compatibility or waiting for a new language version? That's exactly what Dingo aims to provide.

Dingo is a code generation tool that lets you add algebraic data types and pattern matching to your Go projects. It doesn't modify the language; it just generates the boilerplate code you'd otherwise write by hand. The result is cleaner, more expressive error handling and data flow, right in your existing codebase.

What It Does

Dingo takes type definitions from your Go code and generates corresponding Result and Option types, along with a pattern-matching system. You define what you want in regular Go, run the dingo CLI, and it creates the helper methods and types that let you work with these constructs in a more functional style.

Instead of the classic if err != nil pattern, you get methods like .Match(), .Unwrap(), or .Then() that let you handle success and error cases in a more declarative way. It feels familiar if you've used Rust or similar languages, but it's still just plain Go under the hood.

Why It's Cool

The clever part is how non-intrusive it is. Dingo doesn't require you to change how you write Go fundamentally. You don't need new language features or runtime changes. It's a tool that generates code based on your existing types, meaning you can adopt it incrementally. Start using Result in a new service or module without touching the rest of your application.

It also keeps things idiomatic where it counts. The generated code uses interfaces and structs that any Go developer can understand. You get the expressiveness of pattern matching without the complexity of a custom preprocessor or a fork of the Go compiler. It's a pragmatic take on bringing functional programming concepts into a language that wasn't built for them.

How to Try It

Getting started is straightforward. First, install the CLI:

go install github.com/MadAppGang/dingo@latest

In your project, define a type you'd like to use as a Result. For example:

//go:generate dingo
type DivideResult struct {
    Value float64
    Err   error
}

Then run the generator:

go generate ./...

Now you can use DivideResult with generated methods like .Match():

result := Divide(10, 2)
result.Match(
    func(value float64) {
        fmt.Println("Result:", value)
    },
    func(err error) {
        fmt.Println("Error:", err)
    },
)

Check out the GitHub repository for more examples and detailed documentation.

Final Thoughts

Dingo won't replace every if err != nil in your codebase, and it doesn't need to. It's a tool for specific cases where you want more expressive control flow or clearer intent. If you're building a module where errors are a core part of the domain, or if you're just curious about functional patterns in Go, Dingo is worth a look.

It shows how far you can push Go's type system with a bit of clever generation. Whether you adopt it fully or just borrow the ideas, it's a neat exploration of what's possible within Go's existing constraints.


Follow for more interesting projects: @githubprojects

Back to Projects
Project ID: 7ce89d97-3c73-487e-96c5-6e080954ffa5Last updated: March 14, 2026 at 01:45 PM