MCPcopy
hub / github.com/MadAppGang/dingo

github.com/MadAppGang/dingo @v0.14.0 sqlite

repository ↗ · DeepWiki ↗ · release v0.14.0 ↗
5,434 symbols 21,986 edges 503 files 3,467 documented · 64%
README

Dingo

Dingo mascot

Go that escaped.

Go Version License Development Status PRs Welcome

FeaturesQuick StartExamplesStatusRoadmapContributing


At a Glance

Sum Types: Working | Pattern Matching: Working | Error Propagation: Working | Tuples: Working | Safe Navigation: Working | Playground for Go's Future | v1.0 Target: Q1 2026


Look, I love Go. But...

You know that feeling when you're writing Go and you type if err != nil for the 47th time in a single file?

Or when you forget to check for nil and your production server learns what a panic feels like?

Or when you're explaining to a Rust developer why Go doesn't have sum types and they look at you like you just said "we don't believe in seatbelts"?

Yeah. That's why Dingo exists.

What's Dingo?

Think TypeScript, but for Go.

Dingo is a language that compiles to clean, idiomatic Go code. Not some franken-runtime or a whole new ecosystem. Just better syntax that becomes regular Go.

The pitch: Write code with Result types, pattern matching, and null safety. Get back perfect Go code that your team can read, your tools can process, and your production servers can run at exactly the same speed.

Zero runtime overhead. Zero new dependencies. Zero "what's this weird thing in my transpiled code?"

Is this proven to work? Yes. Borgo (4.5k stars) already proved you can transpile to Go successfully. Dingo builds on that foundation with better IDE integration, source maps, and a pure Go implementation.


Why "Dingo"?

Ever wonder what a dingo actually is?

Thousands of years ago, they were domesticated dogs. Well-behaved. Following commands. Controlled.

Then they escaped to the Australian wild and evolved into something science couldn't categorize. Not quite dog. Not quite wolf. Ungovernable.

The Go Gopher? Created at Google. Lives by the rules. Does what it's told.

Dingo broke free.

Here's the beautiful part: dingos are still canines. They didn't reject their DNA—they just refused to be controlled. Same with our language.

Every Go feature still works. Go 1.24 adds something? You get it in Dingo. Day one. Disable all plugins? You're running pure Go.

You're not losing anything. You're gaining freedom without asking permission.

Want pattern matching? Enable it. Want sum types? Already working. Think you can do it better? Fork the plugin and prove it.

Your language. Your rules. No committee required.

See MANIFESTO.md for why this terrifies the establishment.


Quick Start

Note: Dingo is in active development. Phase 10 Complete - Full LSP integration with gopls proxy, auto-rebuild on save, and comprehensive IDE support.

Latest (2025-12-09): ✅ Tuples & Documentation Update - Tuple type support (Phase 8) complete with destructuring, multi-return functions, and Option/Result integration. Golden tests updated to use current API patterns (.MustSome(), .MustOk() methods). See CHANGELOG.md for details.

Installation

# Clone the repository
git clone https://github.com/MadAppGang/dingo.git
cd dingo

# Build the compiler
go build -o dingo ./cmd/dingo

# Add to PATH (optional)
export PATH=$PATH:$(pwd)

Your First Dingo Program

Create hello.dingo:

package main

import "fmt"

func main() {
    message := "Hello from Dingo!"
    fmt.Println(message)
}

Build and run:

# Transpile to Go and compile to binary (like go build)
dingo build hello.dingo

# Transpile and run immediately (like go run)
dingo run hello.dingo

# Transpile to Go only (generates .go files without compiling)
dingo go hello.dingo

Try Working Features Now

Sum Types with Pattern Matching:

enum Result {
    Ok(value: int),
    Error(message: string)
}

func divide(a: int, b: int) Result {
    if b == 0 {
        return Error("division by zero")
    }
    return Ok(a / b)
}

result := divide(10, 2)
match result {
    Ok(value) => fmt.Printf("Success: %d\n", value),
    Error(msg) => fmt.Printf("Error: %s\n", msg)
}

Safe Navigation and Null Coalescing (Phase 7 ✅):

// Property access with safe navigation
city := user?.address?.city?.name ?? "Unknown"

// Method calls with safe navigation
email := user?.getProfile()?.email ?? "noreply@example.com"

// Works with Go pointers too!
timeout := config?.database?.timeout ?? 30

// Chained defaults
theme := user?.theme ?? project?.theme ?? global?.theme ?? "light"

Functional Utilities:

numbers := []int{1, 2, 3, 4, 5}
doubled := numbers.map(func(x int) int { return x * 2 })
evens := numbers.filter(func(x int) bool { return x % 2 == 0 })
sum := numbers.reduce(0, func(acc int, x int) int { return acc + x })

See examples/ and docs/features/ for more working code.


Why Dingo?

### The Go Pain Points - **47 `if err != nil` blocks** per file - **Nil pointer panics** in production - **No sum types** after 15 years of requests - **Verbose error handling** drowning business logic - **No null safety** operators - **Boilerplate enums** requiring manual type guards ### The Dingo Solution - **`?` operator** propagates errors cleanly - **`Option`** makes nil checks compile-time safe - **`enum` keyword** with full sum type support - **Pattern matching** with exhaustiveness checking - **`?.` and `??`** for safe navigation and null coalescing - **Zero overhead** - transpiles to clean Go

Key Insight: Dingo doesn't change Go. It transpiles to it. Your team gets modern ergonomics, your production gets pure Go performance.


The Hidden Superpower: Use Dingo Selfishly, Help Go Evolve Naturally

Here's what makes Dingo special — you get two massive benefits simultaneously:

1. Revolutionize YOUR Codebase TODAY

This is why you'll actually use Dingo:

  • 67% less error handling boilerplate? operator instead of 47 if err != nil blocks
  • 78% code reduction with sum types — Rust-style enums that just work
  • Zero nil pointer panics — Option types that the compiler enforces
  • Pattern matching — Exhaustive, type-safe, impossible to mess up
  • Same performance — Transpiles to clean Go, zero runtime overhead

Your code becomes cleaner, safer, and more maintainable. Immediately.

This is the selfish reason to use Dingo. And it's a damn good reason.

2. Shape Go's Future (As a Natural Side Effect)

Here's the beautiful part you get for free:

While you're using Dingo to make YOUR code better, you're automatically contributing to Go's evolution:

  • 📊 Your metrics become data — "67% reduction in error handling code across 50 real projects"
  • 🐛 Your bugs find edge cases — Real problems that theoretical debates miss
  • Your usage validates ideas — Proof that features work in production
  • 📚 Your code becomes examples — Concrete demonstrations for Go proposals

You don't have to think about this. It just happens.

The TypeScript Parallel (This Is EXACTLY What Happened)

Developers didn't adopt TypeScript to "help JavaScript evolve."

They adopted it because it made their codebases better.

  • TypeScript added types → Developers used them → JavaScript saw it worked → JavaScript added types
  • TypeScript added async/await → Millions used it → JavaScript saw the value → JavaScript adopted it
  • TypeScript added optional chaining → Everyone loved it → JavaScript added it officially

Developers used TypeScript selfishly. JavaScript evolved as a natural consequence.

Same thing is happening with Dingo and Go:

  1. You use Dingo because it makes error handling less painful
  2. 50,000 other developers do the same thing
  3. Go team sees 2 years of production data showing it works
  4. Go proposal now has concrete evidence instead of theoretical debate
  5. Everyone wins

You're not doing charity work. You're writing better code. Helping Go evolve is just a happy side effect.

Why This Matters More Than You Think

For decades, programming language evolution has been broken:

The old way: Community → Proposal → Years of debate → Maybe no → Frustration

The Dingo way: Developers → Use features → Data emerges → Go team decides with evidence

This is how TypeScript revolutionized JavaScript. Not through proposals, but through proving ideas in production.

The Win-Win-Win Scenario

🎯 You win: Better code today, zero waiting 🎯 Go team wins: Real data for decisions, reduced risk 🎯 Go ecosystem wins: Faster evolution, battle-tested features

Example: Sum Types

Imagine if before Go Proposal #19412 (sum types - 996+ 👍 but rejected), there was: - ✅ 50,000 developers using it for 2 years - ✅ Concrete metrics: 78% code reduction - ✅ Known edge cases documented - ✅ Production validation across 5,000+ projects

The proposal would have been impossible to reject with that evidence.

That's what Dingo enables. Every feature you use contributes data that could reshape Go's future.

This Is Not Hypothetical — TypeScript Proved It Works

Here's what actually happened with TypeScript and JavaScript:

Feature TypeScript Added Developers Used It JavaScript Adopted Timeline
Async/Await 2015 Millions of codebases ES2017 2 years
Optional Chaining 2019 Massive adoption ES2020 1 year
Nullish Coalescing 2019 Widespread use ES2020 1 year
Class Fields 2017 Standard in TS code ES2022 5 years
Decorators 2015 Widely used Stage 3 proposal Still evolving

Notice the pattern: 1. TypeScript adds feature 2. Developers use it (for selfish reasons - better code) 3. Real-world data proves it works 4. JavaScript adopts it with evidence-based confidence

Dingo enables the exact same cycle for Go.

You're not choosing between "make my code better" OR "help Go evolve."

You get both. Automatically. Simultaneously.


Why should you care?

Here's what the Go community has been begging for since 2009:

What developers want How badly What Dingo gives you
Stop typing if err != nil every 3 lines ⭐⭐⭐⭐⭐ Result<T, E> + the ? operator
Stop shipping nil pointer panics ⭐⭐⭐⭐⭐ Option<T> type that the compiler actually checks
Sum types (seriously, it's been 15 years) ⭐⭐⭐⭐⭐ 996+ 👍 enum with pattern matching
Enums that can't be invalid ⭐⭐⭐⭐⭐ 900+ 👍 Type-safe enums with exhaustiveness
Lambda functions that don't take 4 lines ⭐⭐⭐⭐ 750+ 👍 \|x\| x * 2 like a normal language

The Go team has valid reasons for rejecting these features. They're not wrong about simplicity.

But here's the thing: Dingo doesn't change Go. We just compile to it.

Want sum types? Great. They become tagged structs in Go. Want the ? operator? Cool. It becomes if err != nil checks. Want pattern matching? Done. It's a switch statement underneath.

Your Go code stays pure. Your Dingo code stays sane.


Show Me Code or I'm Leaving

Fair enough.

Code Reduction in Action

Metric Traditional Go With Dingo Savings
Sum Type Definition 33 lines 7 lines 79% less code
Enum with Data 46 lines 10 lines 78% less code
Error Handling Pipeline 85 lines 28 lines 67% less code
API Handler 42 lines 15 lines 64% less code

All numbers from real examples in our test suite

The "if err != nil" problem

What you write in Go today:

func processOrder(orderID string) (*Order, error) {
    order, err := fetchOrder(orderID)
    if err != nil {
        return nil, fmt.Errorf("fetch failed: %w", err)
    }

    validated, err := validateOrder(order)
    if err != nil {
        return nil, fmt.Errorf("validation failed: %w", err)
    }

    payment, err := processPayment(validated)
    if err != nil {
        return nil, fmt.Errorf("payment failed: %w", err)
    }

    return payment, nil
}

75% of this function is error handling ceremony. The actual logic is hiding somewhere in there.

What you write in Dingo:

func processOrder(orderID: string) -> Result<Order, Error> {
    order := fetchOrder(orderID)?
    validated := validateOrder(order)?
    payment := processPayment(validated)?
    return Ok(payment)
}

Same safety. Same error handling. 60% less code.

The ? just means "if this is an error, return it. Otherwise, unwrap the value and keep going." That's it. That's the entire feature.

Rust developers have been using this for 8 years. They love it so much they put it on t-shirts.


Real Working Examples (From Our Test Suite)

These are actual examples from Dingo's test suite that transpile and run today.

Example 1: Simple Sum Type

**What You Write (Dingo)**
package main

enum Status {
    Pending,
    Active,
    Complete,
}
**What You Get (Generated Go)** ```go pa

Extension points exported contracts — how you extend this code

ErrorFormatter (Interface)
ErrorFormatter formats transpile errors for specific editor types. Each editor has different capabilities for rendering [8 …
pkg/lsp/error_formatter.go
ContextAware (Interface)
ContextAware plugins can receive context information [11 implementers]
pkg/plugin/plugin.go
Analyzer (Interface)
Analyzer is the interface for all Dingo analyzers. Implementations include correctness rules (D0xx), style rules (D1xx) [8 …
pkg/lint/analyzer/analyzer.go
Pattern (Interface)
Pattern is the interface for all pattern types [10 implementers]
pkg/ast/match.go
Generator (Interface)
Generator interface for all codegens [13 implementers]
pkg/codegen/codegen.go
Status (Interface)
Test: Enum variant - bare variant name should work This file should compile without errors line /Users/jack/mag/dingo/te [11 …
tests/lsp/06_enum_variant_typo/main.go
Status (Interface)
Enum definition [11 implementers]
examples/05_sum_types/match_contexts/match_contexts.go
Event (Interface)
Event sum type - all possible events in the system line examples/04_pattern_matching//event_handler.dingo:17:1 [6 implementers]
examples/04_pattern_matching/event_handler.go

Core symbols most depended-on inside this repo

Errorf
called by 2262
pkg/lsp/semantic/document.go
Fatalf
called by 954
pkg/lsp/logger.go
Contains
called by 567
pkg/parser/errors.go
Pos
called by 450
pkg/ast/ast.go
Error
called by 381
pkg/plugin/plugin.go
Printf
called by 338
pkg/ui/simple_build_ui.go
Debugf
called by 337
pkg/plugin/plugin.go
Write
called by 327
pkg/codegen/codegen.go

Shape

Function 2,603
Method 2,132
Struct 570
TypeAlias 52
Interface 50
Class 18
FuncType 9

Languages

Go92%
TypeScript8%
Python1%

Modules by API surface

pkg/feature/builtin/plugins.go91 symbols
pkg/ast/match.go59 symbols
pkg/codegen/match.go56 symbols
pkg/parser/pratt.go49 symbols
cmd/dingo/watch.go49 symbols
pkg/plugin/plugin.go46 symbols
pkg/plugin/builtin/type_inference.go45 symbols
pkg/registry/registry.go44 symbols
pkg/ast/enum.go43 symbols
pkg/typechecker/lambda_inference.go42 symbols
pkg/plugin/builtin/pattern_match.go42 symbols
pkg/plugin/builtin/safe_nav_types.go41 symbols

Dependencies from manifests, versioned

github.com/BurntSushi/tomlv1.3.2 · 1×
github.com/Masterminds/semver/v3v3.4.0 · 1×
github.com/aymanbagabas/go-osc52/v2v2.0.1 · 1×
github.com/charmbracelet/colorprofilev0.2.3-0.20250311203 · 1×
github.com/charmbracelet/lipglossv1.1.0 · 1×
github.com/charmbracelet/x/ansiv0.10.1 · 1×
github.com/charmbracelet/x/cellbufv0.0.13-0.2025031120 · 1×
github.com/charmbracelet/x/termv0.2.1 · 1×
github.com/davecgh/go-spewv1.1.1 · 1×
github.com/dustin/go-humanizev1.0.1 · 1×
github.com/fsnotify/fsnotifyv1.7.0 · 1×

Datastores touched

appDatabase · 1 repos

For agents

$ claude mcp add dingo \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact