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.
What this skill does
# 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, Related in General
modeling-omnistudio-epc-catalog
IncludedSalesforce Industries CME EPC product-modeling skill for Product2-based catalog creation. Use when creating EPC products, configuring product attributes, building offer bundles with Product Child Items, or reviewing EPC DataPack JSON metadata for product catalog changes. TRIGGER when: user creates or updates Product2 EPC records, AttributeAssignment payloads, AttributeMetadata/AttributeDefaultValues, Offer bundles, or ProductChildItem relationships. DO NOT TRIGGER when: designing OmniScripts/FlexCards/Integration Procedures (use building-omnistudio-omniscript, building-omnistudio-flexcard, or building-omnistudio-integration-procedure), implementing Apex business logic (use generating-apex), or troubleshooting deployment pipelines (use deploying-metadata).
relationship-science-coach
IncludedUse this skill for direct, practical adult relationship coaching: couples conflict, repair, trust, marriage, dating, flirting, attachment patterns, emotional connection, sex, desire differences, eroticism, kink negotiation, affection, love languages, breakups, and long-term passion. Draw on Gottman, EFT and Hold Me Tight, attachment science, modern sex research, Perel, Nagoski, Kerner, Schnarch, Love and Stosny, and flexible love-language tools. Be concrete and low-hedge. Redirect only for imminent danger, abuse, coercive control, minors, non-consent, self-harm, stalking, or medical/legal/psychiatric decisions.
building-sf-integrations
IncludedSalesforce integration architecture and runtime plumbing with 120-point scoring. Use this skill to set up Named Credentials, External Credentials, External Services, REST/SOAP callout patterns, Platform Events, and Change Data Capture. TRIGGER when: user sets up Named Credentials, External Services, REST/SOAP callouts, Platform Events, CDC, or touches .namedCredential-meta.xml files. DO NOT TRIGGER when: Connected App/OAuth config (use configuring-connected-apps), Apex-only logic (use generating-apex), or data import/export (use handling-sf-data).
venue-templates
IncludedAccess comprehensive LaTeX templates, formatting requirements, and submission guidelines for major scientific publication venues (Nature, Science, PLOS, IEEE, ACM), academic conferences (NeurIPS, ICML, CVPR, CHI), research posters, and grant proposals (NSF, NIH, DOE, DARPA). This skill should be used when preparing manuscripts for journal submission, conference papers, research posters, or grant proposals and need venue-specific formatting requirements and templates.
let-fate-decide
IncludedDraws the 12 Houses of the Zodiac Tarot spread to inject entropy into planning when prompts are vague, ambiguous, or casually delegated. Interprets the spread to guide next steps. Use when the user says 'let fate decide', 'YOLO', 'whatever', 'idk', or other nonchalant phrases, makes Yu-Gi-Oh references, or when you are about to arbitrarily pick between multiple reasonable approaches. Prefer over ask-questions-if-underspecified when the user's tone is casual or playful rather than precision-seeking.
net-ops
IncludedCross-platform network troubleshooting (Windows, macOS, Linux) via local or remote shell. Use for: DNS broken, can't resolve hostnames, nslookup/dig works but apps fail, NRPT, WFP, scutil, /etc/resolver, systemd-resolved, /etc/resolv.conf, NetworkManager, VPN DNS leak residue (ProtonVPN/Mullvad/WireGuard/AnyConnect), AV/firewall blocking DNS or DoH, Tailscale DNS interaction, intermittent connectivity, remote diagnostics over SSH.