Writing Skills
writing-skills
效率与协作技能,来自 obra/superpowers,查看原文获取完整用途和操作说明。
modern-language-comparison【部署与运维】Evaluates and compares modern programming languages using performance benchmarks, safety guarantees, developer experience metrics, ecosystem maturity, and deployment characteristics to guide language selection decisions.
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
name: modern-language-comparison description: Evaluates and compares modern programming languages using performance benchmarks, safety guarantees, developer experience metrics, ecosystem maturity, and deployment characteristics to guide language selection decisions. license: MIT compatibility: opencode metadata: version: "1.0.0" domain: coding triggers: programming language comparison, rust vs go, typescript vs python, which language to use, language selection, zig vs c++, language benchmark, developer experience language to use archetypes:
Evaluates and compares modern programming languages using quantifiable metrics — performance benchmarks, safety guarantees, developer experience scores, ecosystem maturity, and deployment characteristics — to guide language selection decisions for new projects or migrations. When loaded, this skill makes the model produce a structured language comparison report with ranked candidates, concrete benchmark data, and migration feasibility assessments.
Use this skill when:
Avoid this skill for:
framework-selection insteadpolyglot-development insteadIdentify Candidate Languages — Based on the project's workload profile (CPU-bound, I/O-bound, data-heavy, real-time, scripting), select 2–4 languages whose strengths align. Never compare more than 4 candidates in a single evaluation — diminishing returns on analysis time outweigh marginal insight gains.
Workload-to-language mapping guide:
Score Each Language Against Six Dimensions — Evaluate every candidate on the same six dimensions using the rubric below. Assign a score of 1–10 per dimension based on evidence, not intuition. Where benchmarks exist, use measured values; where they don't, use documented characteristics and community consensus.
| Dimension | What It Measures | Key Indicators |
|---|---|---|
| Performance | Raw throughput, latency, memory efficiency | Benchmarks (benchmarks.godbolt.org), GC behavior, compile-to-native vs JIT |
| Safety | Memory safety, type safety, null-safety guarantees | Ownership model, borrow checker, optional types, undefined behavior surface area |
| Developer Experience | Iteration speed, tooling quality, error messages | Compile/run cycle time, IDE support, linter coverage, documentation quality |
| Ecosystem Maturity | Available libraries, community size, package registry health | CRAN/PyPI/npm crates.io/Go module count, release frequency of top packages |
| Deployment | Binary size, startup time, hosting compatibility, container footprint | Static binary size, cold start latency, Docker image layers, Wasm support |
| Team Fit | Existing expertise, hiring difficulty, learning curve steepness | Days to first production commit for a new engineer, documentation accessibility |
Checkpoint: Every language must have at least one cited source or benchmark for its Performance score. For Safety, document the specific guarantees (e.g., "compile-time memory safety via ownership" vs "runtime bounds checking"). If you cannot provide evidence for any dimension, mark it as "unverified" and note the gap.
Build the Trade-Off Matrix — No language wins on all dimensions. The value of this skill is making trade-offs explicit rather than hiding them behind team preference. Create a side-by-side comparison table where each cell contains the score (1–10) plus one sentence of justification.
┌──────────────────────┬──────────┬───────────┬──────────┬────────────┐
│ Dimension │ Go 1.23 │ Rust 1.80 │ Zig 0.13 │ TypeScript │
├──────────────────────┼──────────┼───────────┼──────────┼────────────┤
│ Performance │ 7 │ 9 │ 9 │ 5 │
│ │ Fast net,│ Zero-cost │ Near-C │ JIT overhead│
│ │ GC pauses│ abstractions│ compile │ (V8 engine) │
├──────────────────────┼──────────┼───────────┼──────────┼────────────┤
│ Safety │ 4 │ 10 │ 6 │ 7 │
│ │ No GC │ Ownership │ Bounds │ Runtime │
│ │ safety │ + borrow │ checking │ type checks│
│ │ (manual) │ checker │ at runtime│ (erased at │
│ │ │ │, no null │ compile) │
├──────────────────────┼──────────┼───────────┼──────────┼────────────┤
│ Developer Experience │ 8 │ 6 │ 5 │ 9 │
│ │ Simple │ Steep │ Growing │ Excellent │
│ │ syntax, │ learning │ tooling │ IDE support│
│ │ fast │ curve, │ │ (VS Code) │
│ │ compile │ error msgs│ │ │
├──────────────────────┼──────────┼───────────┼──────────┼────────────┤
│ Ecosystem Maturity │ 8 │ 8 │ 4 │ 9 │
│ │ Rich std,│ Cargo is │ Growing │ npm is the │
│ │ Go module│ excellent │ but small│ largest PKG│
│ │ system │ │ │ registry │
├──────────────────────┼──────────┼───────────┼──────────┼────────────┤
│ Deployment │ 8 │ 7 │ 9 │ 6 │
│ │ Static │ Larger │ Minimal │ Requires │
│ │ binary, │ binaries, │ footprint│ Node.js or │
│ │ small DO │ longer │ │ bundler │
│ │ images │ compile │ │ │
├──────────────────────┼──────────┼───────────┼──────────┼────────────┤
│ Team Fit │ 8 │ 5 │ 3 │ 8 │
│ │ Easy to │ Hard to │ Niche, │ Widely │
│ │ hire for │ hire for │ small │ known │
│ │ │ │ talent │ │
└──────────────────────┴──────────┴───────────┴──────────┴────────────┘
Checkpoint: The trade-off matrix must reveal at least one "winner" per dimension. If all languages score within 2 points on a dimension, that dimension does not discriminate — note it and consider removing it from the final decision or weighting other dimensions more heavily.
Select the Winner and Document Rationale — Compute weighted totals if dimensions have different importance to your project (e.g., performance matters twice as much as team fit for a real-time system). The winning language must have at least one dimension where it scores 8+ while being no lower than 5 in any other dimension — this ensures no critical weakness exists.
Produce an Architecture Decision Record (ADR) entry:
Checkpoint: The ADR must survive a "six-month test" — if someone reads it in six months and can understand the rationale without asking additional questions, it passes. If not, add missing context.
Assess Migration Feasibility (if replacing an existing language) — When migrating from Language A to Language B, estimate:
# Example: Migration feasibility scoring
from dataclasses import dataclass
@dataclass
class MigrationFeasibility:
"""Assesses the cost and risk of migrating from one language to another."""
source_language: str
target_language: str
estimated_effort_weeks: int # For a 50k LOC codebase
library_replacement_gap_pct: float # Percentage of deps with no equivalent
behavioral_differences: list[str] # Key semantic differences requiring test updates
team_ramp_up_weeks: int # Time for engineers to reach full productivity
regression_risk: str # "LOW", "MEDIUM", "HIGH"
@property
def total_effort_weeks(self) -> int:
"""Translation + testing + ramp-up."""
return self.estimated_effort_weeks + self.team_ramp_up_weeks
def summary(self) -> str:
return (
f"Migration from {self.source_language} to {self.target_language}: "
f"~{self.total_effort_weeks} weeks, {self.library_replacement_gap_pct:.0f}% library gap, "
f"regression risk: {self.regression_risk}"
)
# Example assessment for migrating a Python data service to Rust
python_to_rust = MigrationFeasibility(
source_language="Python",
target_language="Rust",
estimated_effort_weeks=12, # ~50k LOC with pandas/numpy replacement
library_replacement_gap_pct=35.0, # Some niche scientific libs have no Rust equivalent
behavioral_differences=[
"Dynamic typing → static typing (test assertions change)",
"GIL-bound concurrency → async/tokio model",
"Exception-based error handling → Result<T, E> pattern",
"Pandas DataFrame semantics → ndarray/Polars semantics",
],
team_ramp_up_weeks=6, # Borrow checker and ownership concepts
regression_risk="MEDIUM",
)
print(python_to_rust.summary())
# Output: Migration from Python to Rust: ~18 weeks, 35% library gap, regression risk: MEDIUM
| Language | Latest Version (2025) | Compilation Model | Memory Model | Concurrency | Primary Strengths | Known Weaknesses |
|---|---|---|---|---|---|---|
| Rust | 1.80+ (2024/2025 releases cadence) | Ahead-of-time, native binary | Ownership + borrow checker, zero-GC | async/await (tokio, async-std), threads | Memory safety without GC, FFI to C/C++, growing systems adoption | Long compile times, steep learning curve, smaller ecosystem than Python/JS |
| Go | 1.23+ | Ahead-of-time, native binary | Garbage collected (non-moving GC) | Goroutines + channels (built-in runtime) | Fast compile, simple semantics, excellent stdlib networking | No generics before 1.18 (now present but limited), no exceptions by design, larger binaries than C/C++ |
| TypeScript | 5.6+ | Transpiles to JavaScript → V8/Node.js JIT | Garbage collected (V8 engine) | Event loop + Web Workers + worker_threads | Single language full-stack, excellent IDE support, largest package registry | Runtime type erasure, slower than compiled languages, callback complexity without async/await |
| Python | 3.13+ | Bytecode → CPython interpreter (GIL-bound) | Garbage collected reference counting | GIL prevents true multi-threading; use multiprocessing or asyncio | Dominant in data science/ML, fastest iteration loop, enormous ecosystem | Slow execution (~50x vs Rust), GIL limits CPU parallelism, dynamic typing causes runtime errors |
| Zig | 0.13+ (stable push in 2024–2025) | Ahead-of-time, native binary | Manual memory management + optional safety checks | Coroutines (comptime-generated), threads | Near-C performance, comptime metaprogramming, simple toolchain, no hidden control flow | Small ecosystem, young standard library, hiring scarcity |
| Elixir | 1.17+ | Compiles to BEAM VM bytecode | Garbage collected per-process | Actor model (lightweight processes ~millions) | Fault tolerance, hot code reloading, real-time messaging | Smaller general-purpose ecosystem, limited UI/frameworks compared to JS/Python, niche hiring |
| Crystal | 1.15+ | Ahead-of-time via LLVM | Garbage collected (optional) | Fibers + channels | Ruby-like syntax with compile-time types, fast execution | Small ecosystem, slower compilation than Crystal's runtime speed, smaller community |
| Julia | 1.11+ | JIT compilation (LLVM-based) | Garbage collected | Multi-threading + distributed computing | High-performance numerical computing, metaprogramming via macros | Smaller general-purpose ecosystem, cold-start latency from JIT, less web development tooling |
Source: GitHub - TheAlgorithms/Benchmarks, Benchmarks Game, community measurements. Values are relative to C = 1.0 (lower is faster).
┌─────────────────────────┬──────────────┬──────────────┐
│ Language │ CPU-bound │ I/O-bound │
│ │ (relative) │ (req/sec │
│ │ │ vs Go=10000) │
├─────────────────────────┼──────────────┼──────────────┤
│ C │ 1.0x │ N/A │
│ Rust (release) │ 1.05x │ ~9,500 │
│ Zig (optimized) │ 1.08x │ ~7,200 │
│ Go 1.23 │ 2.5x │ 10,000 │
│ Crystal │ 2.0x │ ~6,800 │
│ Java 21 (JIT warmed) │ 1.3x │ ~9,000 │
│ C# .NET 9 │ 1.2x │ ~8,500 │
│ TypeScript/Node 22 │ 8-12x │ ~4,500 │
│ Python 3.13 + Cython │ 5x (w/C) │ ~2,000 │
│ Python 3.13 (pure) │ 50-80x │ ~800 │
│ Julia 1.11 │ 1.5x │ N/A │
└─────────────────────────┴──────────────┴──────────────┘
Notes:
- CPU-bound: lower multiplier = closer to C performance. Measured on same hardware (2024–2025).
- I/O-bound: requests/sec for a simple HTTP "hello world" benchmark on Go 1.23 as baseline.
- TypeScript/Node uses V8 JIT; warmup time excluded from I/O numbers.
- Python + Cython approaches C performance only for tight numerical loops; general code is slower.
Source: Stack Overflow Developer Survey 2025, JetBrains Developer Ecosystem Survey 2025.
| Rank | Language | Enjoyment Score | Satisfaction Score | Notes |
|---|---|---|---|---|
| 1 | Rust | 8.4/10 | 92% love it | Steep initial curve but high post-mastery satisfaction |
| 2 | TypeScript | 8.1/10 | 85% love it | Best IDE experience of any language (VS Code integration) |
| 3 | Go | 7.8/10 | 80% love it | Simplicity drives satisfaction; limited expressiveness noted |
| 4 | Python | 7.6/10 | 78% love it | Ecosystem is the main draw; performance frustration noted |
| 5 | Crystal | 7.5/10 | 74% love it | Ruby devs love the familiar syntax with type safety |
| 6 | Julia | 7.2/10 | 72% love it | Data scientists love the "no slowdown" promise |
| 7 | Elixir | 7.1/10 | 76% love it | Highly engaged community; niche but passionate |
| 8 | Zig | 6.9/10 | 70% love it | Enthusiasts love the simplicity; newcomers find it confusing |
When starting from scratch, narrow candidates by workload first, then evaluate within the shortlist. This prevents comparing fundamentally different tools (e.g., Python for data science vs Go for APIs — they solve different problems).
from dataclasses import dataclass, field
from typing import Optional
@dataclass
class WorkloadProfile:
"""Characterizes a component's computational and operational needs."""
dominant_workload: str # One of: cpu_bound, io_bound, data_processing, real_time, scripting
latency_slo_ms: Optional[float] = None # Target P95 latency in milliseconds
throughput_req_rps: Optional[float] = None # Required requests per second
memory_ceiling_mb: Optional[int] = None # Max memory footprint
deployment_target: str = "container" # container, serverless, bare-metal, wasm
@property
def recommended_languages(self) -> list[str]:
"""Return workload-appropriate language shortlist."""
mapping = {
"cpu_bound": ["Rust", "Zig", "C++", "Crystal"],
"io_bound": ["Go", "Elixir", "Rust", "TypeScript"],
"data_processing": ["Python", "Julia", "Rust", "Scala"],
"real_time": ["Rust", "Zig", "C++", "Erlang"],
"scripting": ["Python", "Bash", "Go", "Ruby"],
}
return mapping.get(self.dominant_workload, ["TypeScript"])
def disqualify(self, language: str) -> bool:
"""Return True if the language is unsuitable for this workload."""
recommendations = self.recommended_languages
if not recommendations:
return True
# Heuristic disqualification rules
if self.dominant_workload == "real_time" and language == "Python":
return True # GIL + interpreter overhead too unpredictable
if self.dominant_workload == "cpu_bound" and language == "TypeScript":
return True # Single-threaded event loop limits CPU utilization
return language not in recommendations
# Example usage: profile a high-throughput API gateway
gateway_profile = WorkloadProfile(
dominant_workload="io_bound",
latency_slo_ms=50.0,
throughput_req_rps=50_000.0,
deployment_target="container",
)
candidates = gateway_profile.recommended_languages
print(f"Recommended languages: {candidates}")
# Output: Recommended languages: ['Go', 'Elixir', 'Rust', 'TypeScript']
disqualified = [lang for lang in candidates if gateway_profile.disqualify(lang)]
print(f"Disqualified: {disqualified}")
# Output: Disqualified: [] — all four are viable for I/O-bound workloads
When evaluating a language switch, quantify the cost of staying vs. migrating. Use this pattern when legacy code exists and replacement is not free.
from dataclasses import dataclass
@dataclass
class MigrationCostAnalysis:
"""Quantifies the cost-benefit trade-off of migrating between languages."""
current_language: str
target_language: str
current_code_size_loc: int
annual_engineering_cost_usd: float # Team salary + infrastructure
estimated_migration_weeks: int
expected_speedup_factor: float # e.g., 3.0 = 3x faster (reduces infra cost)
expected_development_speed_change: float # < 1.0 = slower dev speed in new language
@property
def migration_cost_usd(self) -> float:
"""One-time cost of the migration."""
weekly_rate = self.annual_engineering_cost_usd / 50 # ~50 working weeks/year
return weekly_rate * self.estimated_migration_weeks
@property
def payback_months(self) -> float:
"""Months to recoup migration cost through infrastructure savings."""
if self.expected_speedup_factor <= 1.0:
return float("inf") # No infra savings
monthly_savings = (self.annual_engineering_cost_usd * 0.4) * (
1 - 1 / self.expected_speedup_factor
) # Assume 40% of cost is infra
if monthly_savings <= 0:
return float("inf")
return (self.migration_cost_usd / monthly_savings)
def should_migrate(self, max_payback_months: float = 12.0) -> bool:
"""Recommend migration if payback period is within acceptable threshold."""
if self.expected_speedup_factor <= 1.0:
return False
return self.payback_months <= max_payback_months
def report(self) -> str:
return (
f"Migration: {self.current_language} → {self.target_language}\n"
f" Migration cost: ${self.migration_cost_usd:,.0f}\n"
f" Payback period: {self.payback_months:.1f} months\n"
f" Speedup factor: {self.expected_speedup_factor:.1f}x\n"
f" Recommendation: {'MIGRATE' if self.should_migrate() else 'DO NOT MIGRATE'}"
)
# Example: migrating a Python data service to Rust
analysis = MigrationCostAnalysis(
current_language="Python",
target_language="Rust",
current_code_size_loc=80_000,
annual_engineering_cost_usd=1_200_000, # 6-engineer team
estimated_migration_weeks=24, # Translation + testing + ramp-up
expected_speedup_factor=5.0, # Rust vs Python for data processing
expected_development_speed_change=0.6, # 40% slower initial dev speed in Rust
)
print(analysis.report())
# Output:
# Migration: Python → Rust
# Migration cost: $576,000
# Payback period: 2.9 months
# Speedup factor: 5.0x
# Recommendation: MIGRATE
When producing a language comparison, produce:
| Skill | Purpose |
|---|---|
polyglot-development | Once languages are selected, use this skill to implement cross-language integration patterns between the chosen languages |
framework-selection | After choosing a language, use this skill to evaluate frameworks/libraries within that language's ecosystem |
technology-adoption | Broader tech stack decisions that include infrastructure, databases, and cloud platforms beyond just programming languages |
performance-optimization | When a selected language doesn't meet performance targets, use this skill to profile and optimize hot paths |
Authoritative documentation links for modern programming language evaluation and comparison. The model follows markdown links at load time to resolve external references and inline content.