Language-Agnostic Principles
Universal patterns that apply regardless of programming language.
Core Principles
Write Code for Humans First
- Names reveal intent —
calculateMonthlyPayment > calc(x, y)
- Functions do one thing — Small, focused, composable
- Types as documentation — Prefer expressive types over comments
- Explicit over implicit — No magic; behavior visible from call site
Favor Composition Over Inheritance
- Interfaces/protocols define contracts
- Inject dependencies; don't hardcode
- Decorate/wrap rather than subclass
Handle Errors as Values
- Result/Option types > exceptions for expected failures
- Exceptions only for truly exceptional (unrecoverable) cases
- Fail fast with context; recover gracefully where possible
Manage State Explicitly
- Immutable by default; mutate deliberately
- Pure functions where possible; isolate side effects
- State machines for complex workflows
Concurrency Without Shared Mutable State
- Message passing / channels / actors
- Immutable data structures
- Structured concurrency (scoped tasks, cancellation)
Universal Patterns
| Pattern |
Description |
| Repository |
Collection-like interface for data access |
| Unit of Work |
Track changes; commit atomically |
| Factory |
Encapsulate complex creation |
| Strategy |
Swap algorithms at runtime |
| Observer/Events |
Decouple producers from consumers |
| Decorator |
Add behavior without modifying core |
| Adapter |
Bridge incompatible interfaces |
| Circuit Breaker |
Fail fast under sustained errors |
| Retry with Backoff |
Handle transient failures |
| Saga |
Distributed transaction compensation |
Cross-Language Concerns
| Concern |
Guidance |
| Serialization |
Use schema-first (Protobuf, Avro, JSON Schema); version explicitly |
| API Contracts |
OpenAPI/gRPC; consumer-driven contracts (Pact) |
| Observability |
Structured logs (JSON); OpenTelemetry; correlation IDs |
| Configuration |
12-factor: env vars for config, secrets in vault |
| Testing |
Pyramid: unit (70%) → integration (20%) → E2E (10%); contract tests at boundaries |
| Dependencies |
Lockfiles committed; private registry; SBOM generation |
| Security |
SAST in CI; dependency scanning; signed artifacts |
Polyglot System Design
Service Boundaries = Language Boundaries
- Each service owns its data + language choice
- Communicate via well-defined contracts (gRPC, REST, async)
- Shared libraries only for truly universal utilities
Shared Conventions Across Languages
- Logging format — Same JSON schema, same field names
- Error format — Consistent error codes, messages, retryability
- Health checks —
/health + /ready endpoints standard
- Metrics — Prometheus exposition format; same naming conventions
- Tracing — W3C TraceContext propagation everywhere
Language Selection Criteria
| Factor |
Weight |
| Team expertise |
High |
| Ecosystem maturity (libs, tooling) |
High |
| Performance requirements |
Medium |
| Domain fit (data science, systems, web) |
Medium |
| Hiring pool |
Medium |
| Operational maturity (debugging, profiling) |
High |
| Long-term support |
High |
- TypeScript JavaScript — Modern JS/TS patterns
- Python — Pythonic patterns, tooling
- Go — Go idioms, concurrency
- Rust — Ownership, borrowing, async
- JVM Kotlin Scala — JVM ecosystem patterns
- Architectural Styles — Modular monolith vs microservices
- Design Patterns — Patterns across paradigms
Sources: Clean Code (Martin Fowler), Effective Software Architecture, Google Engineering Practices, Microsoft Patterns & Practices, Twelve-Factor App