Skip to main content

dingo

Use when working with Dingo meta-language for Go, implementing optionals/results, using generics shortcuts, or transpiling .dingo files to .go while maintaining Go compatibility.

ソース情報

リポジトリ
MadAppGang/claude-code
ソースの最終更新活動
2026年1月20日 08:16
検出された SKILL.md の言語
英語
スター
284
フォーク
25

インストール方法

デフォルトでは、最初にソースを確認する Prompt が選択されています。直接コマンドに切り替えるか、ローカルコピーをダウンロードすることもできます。

ソースファイルを確認

インストールを決める前に、SKILL.md と SkillsMP に表示されている付属ファイルをお読みください。

SKILL.md を表示中

SKILL.md
ソースの指示 · 読み取り専用プレビュー
name
dingo
version
1.0.0
description
Use when working with Dingo meta-language for Go, implementing optionals/results, using generics shortcuts, or transpiling .dingo files to .go while maintaining Go compatibility.
keywords
["Dingo","Go","meta-language","transpiler","optionals","results","generics","Go tooling"]
plugin
dev
updated
2026-01-20T00:00:00.000Z
# Dingo Language Patterns ## Overview Dingo is a meta-language for Go that transpiles `.dingo` files to `.go` files, providing modern language features while maintaining 100% Go ecosystem compatibility. **Repository:** https://github.com/MadAppGang/dingo **When to use Dingo:** - You want concise error handling with the `?` operator - You need sum types (enums) and pattern matching - You prefer functional patterns with lambdas - You want `Option[T]` and `Result[T,E]` types - You need safe navigation (`?.`) and null coalescing (`??`) **Key Philosophy:** Dingo makes common Go patterns more concise and safer without departing from Go idioms. The transpiled Go code is clean and idiomatic. ## Project Structure ``` project/ ├── cmd/ │ └── api/ │ └── main.dingo # Entry point ├── internal/ │ ├── handlers/ # HTTP handlers (.dingo files) │ ├── services/ # Business logic │ ├── repositories/ # Data access │ └── models/ # Domain models ├── pkg/ # Public packages ├── configs/ # Configuration ├── go.mod # Go module file ├── go.sum # Go dependencies └── .dingo/ # Generated .go files (gitignored) ``` ## Build & Development Workflow ### Commands ```bash dingo build # Transpile to Go and build binary dingo run main.dingo # Transpile and run directly dingo go # Generate .go files only (for CI/CD) dingo fmt # Format Dingo files ``` ### Development Cycle 1. **Write**: Edit `.dingo` files 2. **Transpile**: Run `dingo go` to generate `.go` files in `.dingo/` 3. **Type Check**: gopls works on generated `.go` files for IDE support 4. **Build**: `dingo build` or `go build` on generated files ### IDE Integration gopls (Go language server) works on the generated `.go` files: ```bash # After dingo go, gopls sees: .dingo/ ├── cmd/api/main.go ├── internal/handlers/user.go └── internal/services/user.go ``` Configure your editor to watch `.dingo/` for Go analysis. ### CI/CD Pipeline ```yaml # GitHub Actions example steps: - name: Install Dingo run: go install github.com/MadAppGang/dingo/cmd/dingo@latest - name: Generate Go files run: dingo go - name: Build run: go build -o app ./.dingo/cmd/api - name: Test run: go test ./.dingo/... ``` ### Transpilation Errors Dingo reports errors with source locations in `.dingo` files: ``` error: mismatched types in match expression --> internal/handlers/user.dingo:42:5 | 42 | match status { | ^^^^^ expected Status, found string ``` Fix errors in `.dingo` source, then re-run `dingo go`. ## Built-in Types **Important:** `Option[T]`, `Result[T,E]`, `Some()`, `None()`, `Ok()`, `Err()` are **built-in Dingo syntax**, not Go imports. The transpiler generates all necessary type definitions. ```dingo // These are built-in - no import needed func findUser(id string) Option[User] { // ... return Some(user) // Built-in function return None() // Built-in function } func divide(a, b int) Result[int, string] { if b == 0 { return Err("division by zero") // Built-in } return Ok(a / b) // Built-in } ``` Only import `dgo` if writing **pure Go code** that interoperates with Dingo-generated types. ## Error Propagation (? Operator) The `?` operator provides concise error handling, similar to Rust. ### Basic Propagation ```dingo // Before: verbose Go pattern func loadUser(id string) (*User, error) { user, err := db.FindByID(id) if err != nil { return nil, err } return user, nil } // After: concise Dingo func loadUser(id string) (*User, error) { user := db.FindByID(id)? return user, nil } ``` ### Error Context Add context to propagated errors: ```dingo func processOrder(id string) (*Order, error) { // Wrap error with message order := db.FindOrder(id) ? "failed to find order" // Validates and wraps validated := validateOrder(order) ? "order validation failed" // Process with full context result := processPayment(validated) ? "payment processing failed" return result, nil } ``` ### Error Transform Transform errors with closures: ```dingo func createUser(input CreateUserInput) (*User, error) { // Rust-style closure user := db.Create(input) ? |e| fmt.Errorf("db error: %w", e) // TypeScript-style arrow profile := createProfile(user.ID) ? e => AppError.Wrap(e, "profile creation") return user, nil } ``` ### Error Propagation in Lambdas When using `?` inside lambda bodies, the error propagates to the enclosing function: ```dingo func processAllUsers(ids []string) (*Summary, error) { // Error in lambda propagates to processAllUsers results := map(ids, |id| { user := db.FindUser(id)? // Propagates to processAllUsers, not the lambda return transform(user) }) return summarize(results), nil } // For lambdas that should handle errors internally: func processAllUsersSafe(ids []string) []Result[User, error] { return map(ids, |id| { user, err := db.FindUser(id) if err != nil { return Err(err) } return Ok(user) }) } ``` **Important:** The `?` operator inside lambdas propagating to the enclosing function is **intentional Dingo design**. When the transpiler sees `?` inside a lambda body, it generates special code that propagates errors to the enclosing function rather than the lambda itself. This is the most common use case for error handling in functional chains. If you need the lambda to handle errors internally (e.g., to return `Result` types), use explicit Go-style error checking as shown in `processAllUsersSafe` above. ## Option[T] Type Use `Option[T]` for optional values instead of nullable pointers. ### Basic Usage ```dingo func findUser(id string) Option[User] { user, err := db.FindByID(id) if err != nil { return None() } return Some(user) } // Usage user := findUser("123") if user.IsSome() { fmt.Println(user.Unwrap().Name) } // With default name := findUser("123").Map(|u| u.Name).UnwrapOr("Anonymous") ``` ### Option Methods ```dingo opt := Some("hello") opt.IsSome() // true opt.IsNone() // false opt.Unwrap() // "hello" (panics if None) opt.UnwrapOr("default") // "hello" opt.UnwrapOrElse(|| "computed") // "hello" opt.Map(|s| len(s)) // Some(5) opt.FlatMap(|s| Some(s + "!")) // Some("hello!") ``` ## Result[T, E] Type Use `Result[T, E]` for explicit error modeling. **Type Parameter Inference:** Type parameters can be inferred when the context makes them clear (e.g., function return type), but explicit parameters are needed in standalone expressions like `Ok[int, string](42)`. ### Basic Usage ```dingo func divide(a, b int) Result[int, string] { if b == 0 { return Err("division by zero") } return Ok(a / b) } // Usage result := divide(10, 2) if result.IsOk() { fmt.Println(result.Unwrap()) // 5 } // With default value := divide(10, 0).UnwrapOr(0) // 0 ``` ### Result Methods ```dingo ok := Ok[int, string](42) err := Err[int, string]("failed") ok.IsOk() // true ok.IsErr() // false ok.Unwrap() // 42 ok.UnwrapErr() // panics ok.UnwrapOr(0) // 42 ok.Map(|n| n * 2) // Ok(84) err.UnwrapOr(0) // 0 err.UnwrapErr() // "failed" ``` ## Sum Types (Enums) Define algebraic data types with named variants. ### Basic Enum ```dingo enum Status { Pending Active Suspended { reason: string } Deleted { deletedAt: time.Time, deletedBy: string } } func (s Status) String() string { match s { Pending => "pending", Active => "active", Suspended(reason) => fmt.Sprintf("suspended: %s", reason), Deleted(at, by) => fmt.Sprintf("deleted at %v by %s", at, by), } } ``` ### Enum Instantiation Use constructor syntax to create enum variants: ```dingo // Simple variants (no fields) status := Status.Pending active := Status.Active // Variants with fields - constructor syntax suspended := Status.Suspended("policy violation") deleted := Status.Deleted(time.Now(), "admin@example.com") ``` ### Event Sourcing Example ```dingo enum UserEvent { Created { userID: int, email: string, createdAt: time.Time } EmailChanged { userID: int, oldEmail: string, newEmail: string } Deactivated { userID: int, reason: string } Reactivated { userID: int } } // Creating events - use constructor syntax func recordUserCreation(id int, email string) UserEvent { return UserEvent.Created(id, email, time.Now()) } func recordEmailChange(id int, old, new string) UserEvent { return UserEvent.EmailChanged(id, old, new) } func processEvent(event UserEvent) { match event { Created(id, email, _) => { fmt.Printf("User %d created with email %s\n", id, email) }, EmailChanged(id, old, new) => { fmt.Printf("User %d changed email from %s to %s\n", id, old, new) }, Deactivated(id, reason) => { fmt.Printf("User %d deactivated: %s\n", id, reason) }, Reactivated(id) => { fmt.Printf("User %d reactivated\n", id) }, } } ``` ## Pattern Matching (match) Exhaustive pattern matching with guards. ### Basic Matching ```dingo func describe(n int) string { match n { 0 => "zero", 1 => "one", _ if n < 0 => "negative", _ if n > 100 => "large", _ => "other", } } ``` ### With Enum Destructuring ```dingo enum Shape { Circle { radius: float64 } Rectangle { width: float64, height: float64 } Triangle { base: float64, height: float64 } } func area(shape Shape) float64 { match shape { Circle(r) => 3.14159 * r * r, Rectangle(w, h) => w * h, Triangle(b, h) => 0.5 * b * h, } } ``` ### Nested Match with Guards Complex matching scenarios with nested patterns: ```dingo enum Response { Success { data: Option[User], cached: bool } Error { code: int, message: string } } func handleResponse(resp Response) string { match resp { // Nested pattern: match on enum variant AND option state Success(Some(user), true) => { fmt.Sprintf("Cached user: %s", user.Name) }, Success(Some(user), false) => { fmt.Sprintf("Fresh user: %s", user.Name) }, Success(None(), _) => "No user data", // Guard on nested field Error(code, msg) if code >= 500 => { fmt.Sprintf("Server error %d: %s", code, msg) }, Error(code, msg) if code >= 400 => { fmt.Sprintf("Client error %d: %s", code, msg) }, Error(code, msg) => { fmt.Sprintf("Unknown error %d: %s", code, msg) }, } } ``` ### Wildcard Ignoring ```dingo func getOrderSummary(event OrderEvent) string { match event { OrderPlaced(id, _, amount) => fmt.Sprintf("Order %s: $%.2f", id, amount), OrderShipped(id, _, _) => fmt.Sprintf("Order %s shipped", id), _ => "Unknown event", }
GitHubで見る
この SKILL.md は非常に大きいため、SkillsMP では最初のセクションだけを表示しています。 GitHubで見る