Skip to main content

Languages & selection

A language is not a popularity contest—it is a tradeoff among problem domain, team skill, and runtime constraints. This page captures selection dimensions, a compact map of families, and questions to ask in design review.

Selection dimensions

DimensionQuestionsSignals
Problem domainLatency, throughput, safety, delivery shapeEmbedded / server / client / scripting
Type systemHow many errors caught before runStatic strong vs dynamic + tests
RuntimeGC, ownership, VM, interpreterPauses, determinism, cold start
EcosystemLibraries, tooling, hiring, docsPackage mgr, LSP, official guides
InteropExisting code, FFI, platform APIsC ABI, JNI, Wasm, ObjC/Swift
MaintainabilityTeam skill, migration costModule boundaries, refactor tools
tip

Default: Prefer a language the team already masters with a mature ecosystem; add a second language only when metrics prove a bottleneck (latency, memory, binary size).

Type systems at a glance

StyleExamplesUpsideCost
Static strongRust, Swift, Go, Java, TS (strict)Clear contracts, safer refactorsBoilerplate, generics curve
GradualTypeScript, Python + hintsEasier migrationNeeds lint for consistency
DynamicRuby, untyped PythonFast prototypesRegressions need discipline

Practice: Enable strict mode in TypeScript/Python; centralize boundary types (API DTOs, config); stop any from spreading.

Language map (personal notes)

LanguageI reach for it whenThink twice when
SwiftApple UI, system APIs, safer concurrency defaultsLinux-only server with no Swift bench
TypeScriptWeb full stack, tooling, JSON/API-heavy workCPU-bound core without native/Wasm path
PythonData scripts, glue, internal toolsHigh-concurrency long-lived sockets without asyncio + load tests
GoSimple concurrent services, CLI, sidecarsRich domain models without team discipline
RustPerf/safety-critical pieces, FFI, infraFirst version of CRUD product (iteration cost)

Not a ranking—validate with measurements per project.

Review checklist (PR / design)

  • Does a new dependency introduce a second memory or async model?
  • Are public APIs typed with explicit error shapes?
  • Reusing existing format, lint, and test harness?
  • Are scripting languages confined to boundaries (build, migrate, ops)?

Performance vs language

Language is rarely the first bottleneck. Before switching:

  1. Profile: CPU flame graphs, allocations, lock wait.
  2. Algorithm & I/O: N+1 queries, serialization, blocking calls.
  3. Boundary: Native/Rust/C on hot paths; keep business code in the incumbent language.