1#[cfg_attr(feature = "serde", derive(serde::Serialize))]
36#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
37#[allow(missing_docs)]
38pub enum Language {
39 Python,
40 Rust,
41 JavaScript,
42 TypeScript,
43 Go,
44 Bash,
45 C,
46 Cpp,
47 Java,
48 MechGen,
52 Ideal,
59}
60
61impl Language {
62 pub fn all() -> [Language; 11] {
64 [
65 Language::Python,
66 Language::Rust,
67 Language::JavaScript,
68 Language::TypeScript,
69 Language::Go,
70 Language::Bash,
71 Language::C,
72 Language::Cpp,
73 Language::Java,
74 Language::MechGen,
75 Language::Ideal,
76 ]
77 }
78
79 pub fn name(self) -> &'static str {
81 match self {
82 Language::Python => "python",
83 Language::Rust => "rust",
84 Language::JavaScript => "javascript",
85 Language::TypeScript => "typescript",
86 Language::Go => "go",
87 Language::Bash => "bash",
88 Language::C => "c",
89 Language::Cpp => "cpp",
90 Language::Java => "java",
91 Language::MechGen => "mechgen",
92 Language::Ideal => "ideal",
93 }
94 }
95
96 pub fn from_name(name: &str) -> Option<Language> {
99 match name.to_ascii_lowercase().as_str() {
100 "python" | "py" => Some(Language::Python),
101 "rust" | "rs" => Some(Language::Rust),
102 "javascript" | "js" | "node" => Some(Language::JavaScript),
103 "typescript" | "ts" => Some(Language::TypeScript),
104 "go" | "golang" => Some(Language::Go),
105 "bash" | "sh" | "shell" => Some(Language::Bash),
106 "c" => Some(Language::C),
107 "cpp" | "c++" | "cxx" => Some(Language::Cpp),
108 "java" => Some(Language::Java),
109 "mechgen" | "mg" | "redox" => Some(Language::MechGen),
110 "ideal" => Some(Language::Ideal),
111 _ => None,
112 }
113 }
114}
115
116#[cfg_attr(feature = "serde", derive(serde::Serialize))]
119#[derive(Debug, Clone)]
120pub struct LanguageProfile {
121 pub language: Language,
123 pub token_efficiency: f64,
126 pub determinism: f64,
129 pub reliability: f64,
132 pub safety: f64,
135 pub evidence: Vec<&'static str>,
137}
138
139impl LanguageProfile {
140 pub fn fitness(&self) -> f64 {
143 (self.token_efficiency + self.determinism + self.reliability + self.safety) / 4.0
144 }
145}
146
147impl std::fmt::Display for LanguageProfile {
148 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
149 write!(
150 f,
151 "{}: fitness {:.2} (tokens {:.2}, determinism {:.2}, reliability {:.2}, safety {:.2})",
152 self.language.name(),
153 self.fitness(),
154 self.token_efficiency,
155 self.determinism,
156 self.reliability,
157 self.safety
158 )
159 }
160}
161
162pub fn profile(lang: Language) -> LanguageProfile {
165 match lang {
166 Language::Python => LanguageProfile {
167 language: lang,
168 token_efficiency: 0.85,
169 determinism: 0.45,
170 reliability: 0.45,
171 safety: 0.35,
172 evidence: vec![
173 "compact syntax, minimal boilerplate; most-represented language in LLM training data",
174 "dynamic typing defers agent mistakes to runtime; tracebacks are readable but late",
175 "environment drift (interpreter version, site-packages) breaks reproducibility without lockfile discipline",
176 "arbitrary I/O & exec by default; no capability gating; sandboxing requires external containment",
177 ],
178 },
179 Language::Rust => LanguageProfile {
180 language: lang,
181 token_efficiency: 0.55,
182 determinism: 0.9,
183 reliability: 0.95,
184 safety: 0.8,
185 evidence: vec![
186 "verbose types/lifetimes cost tokens, but rustc diagnostics (spans + suggested fixes) are the best self-correction signal of any mainstream language",
187 "Cargo.lock + rustfmt + stable editions: agent edit→build loops are highly reproducible",
188 "borrow checker + no UB in safe code: most agent mistakes are caught before running",
189 "memory-safe by default; `unsafe` is greppable/gateable; still full ambient I/O authority",
190 ],
191 },
192 Language::JavaScript => LanguageProfile {
193 language: lang,
194 token_efficiency: 0.75,
195 determinism: 0.5,
196 reliability: 0.4,
197 safety: 0.4,
198 evidence: vec![
199 "compact and heavily represented in training data",
200 "silent coercion + undefined-not-an-error swallow agent mistakes instead of surfacing them",
201 "lockfiles help but ecosystem churn and engine differences hurt reproducibility",
202 "ambient filesystem/network in Node; no default sandbox",
203 ],
204 },
205 Language::TypeScript => LanguageProfile {
206 language: lang,
207 token_efficiency: 0.65,
208 determinism: 0.55,
209 reliability: 0.7,
210 safety: 0.4,
211 evidence: vec![
212 "types add tokens over JS but catch a large share of agent mistakes at compile time",
213 "tsc diagnostics are good though less actionable than rustc's",
214 "type erasure at runtime: guarantees end where JS begins (same runtime safety posture)",
215 "config sprawl (tsconfig matrix) adds standing context an agent must track",
216 ],
217 },
218 Language::Go => LanguageProfile {
219 language: lang,
220 token_efficiency: 0.6,
221 determinism: 0.85,
222 reliability: 0.7,
223 safety: 0.55,
224 evidence: vec![
225 "explicit-but-plain syntax; gofmt is canonical (zero formatting nondeterminism)",
226 "go.mod/go.sum + hermetic-ish builds: strong reproducibility",
227 "static types + explicit error returns; diagnostics terser than rustc's",
228 "memory-safe; ambient I/O authority; goroutine leaks are a quiet failure mode",
229 ],
230 },
231 Language::Bash => LanguageProfile {
232 language: lang,
233 token_efficiency: 0.9,
234 determinism: 0.35,
235 reliability: 0.2,
236 safety: 0.2,
237 evidence: vec![
238 "extremely terse for orchestration; one-liners are token-cheap",
239 "word-splitting/quoting pitfalls fail silently — the classic agent foot-gun",
240 "environment-dependent (PATH, locale, shell flavor): poor reproducibility",
241 "every command is an arbitrary side effect; `rm -rf` distance from any typo",
242 ],
243 },
244 Language::C => LanguageProfile {
245 language: lang,
246 token_efficiency: 0.6,
247 determinism: 0.6,
248 reliability: 0.3,
249 safety: 0.15,
250 evidence: vec![
251 "UB (buffer overflows, use-after-free) turns agent mistakes into silent corruption rather than diagnostics",
252 "compiler errors catch syntax/type issues; memory errors escape to runtime or worse",
253 "build reproducibility varies wildly with toolchain/platform macros",
254 "no memory safety, no sandbox: highest blast radius per generated line",
255 ],
256 },
257 Language::Cpp => LanguageProfile {
258 language: lang,
259 token_efficiency: 0.45,
260 determinism: 0.55,
261 reliability: 0.35,
262 safety: 0.2,
263 evidence: vec![
264 "template-error diagnostics are notoriously unactionable (poor self-correction signal)",
265 "huge surface + UB inherited from C; modern subsets help but agents mix eras",
266 "build systems (CMake et al.) add heavy standing context",
267 "same unmanaged blast radius as C",
268 ],
269 },
270 Language::Java => LanguageProfile {
271 language: lang,
272 token_efficiency: 0.4,
273 determinism: 0.75,
274 reliability: 0.7,
275 safety: 0.6,
276 evidence: vec![
277 "boilerplate-heavy (class ceremony, getters): worst token economy of the mainstream set",
278 "static types + managed runtime catch most agent mistakes; stack traces are structured",
279 "Maven/Gradle reproducibility is decent with lockfiles/BOMs",
280 "memory-safe JVM; SecurityManager deprecated, so containment is external",
281 ],
282 },
283 Language::MechGen => LanguageProfile {
291 language: lang,
292 token_efficiency: 0.8,
310 determinism: 0.97,
321 reliability: 0.94,
341 safety: 0.95,
353 evidence: vec![
354 "token (MEASURED, multi-language): ~7% terser than Rust BUT MORE verbose than C/Go head-to-head (factorial+binsearch tokens: Go 102, C 106, Rust 134, MechGen 137) — its Option/Result + explicit-effect + type machinery (which earns 0.95 safety) costs the tokens that C/Go save via inference + unsafe sentinels. So ≈ C/Go tier (0.60), NOT above them. Earlier 0.73 was Rust-only-anchored bias, corrected. The big text→bytes win is only in the separate binary Agentic Binary Language artifact",
355 "determinism — MechGen's most verifiably superior axis: ALL FOUR output channels EMPIRICALLY verified reproducible — byte-stable Agentic Binary Language IR (cmp-identical), formatter idempotence (property-verified this session after fixing 2 round-trip bugs the property found), deterministic ontology/manifest, byte-identical `--check --json`. No mainstream toolchain offers a byte-stable IR artifact or deterministic structured-diagnostic channel by design",
356 "reliability = catching + first-pass success. Catches broadly (static types, sound effects, match exhaustiveness, arity, contracts) with machine-readable code+span+fix diagnostics + self-healing. First-pass: a deterministic, COMPLETE self-ontology (--emit-ontology; keyword section derived from the lexer's own table — 102 keywords, 100% coverage, drift-guarded by test; effects verified to match exactly) lets an agent ground in verified ground-truth instead of guessing syntax — unique among the profiled languages. Crash-robustness empirically demonstrated (60k fuzzed inputs, 0 panics) AND formatter round-trip property-tested. DISCOUNTED below Rust for *correctness* maturity: that property test FOUND 2 real round-trip bugs this week (effect annotation + path separator) — now fixed with permanent regression coverage, but finding them confirms the discount is warranted",
357 "memory-safe AND sound/mandatory/enforced capability effects: a function can't perform net/fs/io/exec it didn't declare. Soundness PROPERTY-VERIFIED single-function (6000 programs) AND transitively through call chains (4000 chains — the propagation path that previously had a bug), every undeclared effect flagged, zero false positives. Best-in-class containment vs Rust's ambient authority; `--check --json` exposes every function's declared-vs-inferred effect surface for pre-run sandboxing",
358 ],
359 },
360
361 Language::Ideal => LanguageProfile {
366 language: lang,
367 token_efficiency: 0.85,
375 determinism: 0.97,
378 reliability: 0.95,
382 safety: 0.96,
385 evidence: vec![
386 "DESIGN TARGET, not a measurement (see IDEAL_AGENTIC_LANGUAGE.md): the composite ceiling for a text language an LLM writes",
387 "three axes (determinism/reliability/safety) are designable to ~0.95+ and demonstrated this session; token is FLOORED ~0.72 (identifiers+literals = 62% of bytes, irreducible)",
388 "composite ≈ 0.90 — cannot honestly exceed it for text; the only way past is paradigm change (tool-mediated structured construction over a deterministic no-exec binary artifact), which scores on the framework track, not here",
389 ],
390 },
391 }
392}
393
394pub fn profiles() -> Vec<LanguageProfile> {
396 Language::all().iter().map(|&l| profile(l)).collect()
397}
398
399pub fn rank_languages() -> Vec<LanguageProfile> {
402 let mut v = profiles();
403 v.sort_by(|a, b| {
404 b.fitness()
405 .partial_cmp(&a.fitness())
406 .unwrap_or(std::cmp::Ordering::Equal)
407 });
408 v
409}
410
411#[cfg_attr(feature = "serde", derive(serde::Serialize))]
413#[derive(Debug, Clone)]
414pub struct LanguageComparison {
415 pub a: LanguageProfile,
417 pub b: LanguageProfile,
419 pub fitness_delta: f64,
421 pub axis_deltas: Vec<(&'static str, f64)>,
423}
424
425pub fn compare_languages(a: Language, b: Language) -> LanguageComparison {
427 let pa = profile(a);
428 let pb = profile(b);
429 let axis_deltas = vec![
430 ("tokens", pa.token_efficiency - pb.token_efficiency),
431 ("determinism", pa.determinism - pb.determinism),
432 ("reliability", pa.reliability - pb.reliability),
433 ("safety", pa.safety - pb.safety),
434 ];
435 LanguageComparison {
436 fitness_delta: pa.fitness() - pb.fitness(),
437 a: pa,
438 b: pb,
439 axis_deltas,
440 }
441}
442
443impl std::fmt::Display for LanguageComparison {
444 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
445 writeln!(
446 f,
447 "{} vs {}: fitness delta {:+.2}",
448 self.a.language.name(),
449 self.b.language.name(),
450 self.fitness_delta
451 )?;
452 for (axis, d) in &self.axis_deltas {
453 writeln!(f, " {axis}: {d:+.2}")?;
454 }
455 Ok(())
456 }
457}
458
459#[cfg(test)]
460mod tests {
461 use super::*;
462
463 #[test]
464 fn ideal_is_the_ceiling_at_about_0_93() {
465 let ideal = profile(Language::Ideal);
470 assert!(
471 (ideal.fitness() - 0.93).abs() < 0.01,
472 "Ideal composite {:.4} should be ~0.93 (revised token floor)",
473 ideal.fitness()
474 );
475 assert_eq!(rank_languages()[0].language, Language::Ideal, "Ideal must top the field");
476 for l in Language::all() {
477 if l != Language::Ideal {
478 assert!(
479 profile(l).fitness() <= ideal.fitness() + 1e-9,
480 "{} exceeds the Ideal ceiling — re-derive the ceiling",
481 l.name()
482 );
483 }
484 }
485 }
486
487
488 #[test]
489 fn every_language_profiles_with_evidence() {
490 for l in Language::all() {
491 let p = profile(l);
492 assert!(
493 p.evidence.len() >= 3,
494 "{} needs ≥3 evidence lines",
495 l.name()
496 );
497 for s in [p.token_efficiency, p.determinism, p.reliability, p.safety] {
498 assert!((0.0..=1.0).contains(&s), "{} score out of range", l.name());
499 }
500 }
501 }
502
503 #[test]
504 fn from_name_roundtrip_and_aliases() {
505 for l in Language::all() {
506 assert_eq!(Language::from_name(l.name()), Some(l));
507 }
508 assert_eq!(Language::from_name("c++"), Some(Language::Cpp));
509 assert_eq!(Language::from_name("JS"), Some(Language::JavaScript));
510 assert_eq!(Language::from_name("klingon"), None);
511 }
512
513 #[test]
514 fn ranking_is_deterministic_and_sorted() {
515 let r1 = rank_languages();
516 let r2 = rank_languages();
517 let names1: Vec<_> = r1.iter().map(|p| p.language.name()).collect();
518 let names2: Vec<_> = r2.iter().map(|p| p.language.name()).collect();
519 assert_eq!(names1, names2);
520 for w in r1.windows(2) {
521 assert!(w[0].fitness() >= w[1].fitness());
522 }
523 }
524
525 #[test]
526 fn axis_judgments_hold_directionally() {
527 let rust = profile(Language::Rust);
530 let python = profile(Language::Python);
531 let bash = profile(Language::Bash);
532 let c = profile(Language::C);
533 assert!(
534 rust.reliability > python.reliability,
535 "static > dynamic for catching agent mistakes"
536 );
537 assert!(
538 python.token_efficiency > rust.token_efficiency,
539 "python is terser than rust"
540 );
541 assert!(
542 bash.safety < 0.4 && c.safety < 0.4,
543 "bash/C are the high-blast-radius pair"
544 );
545 assert!(
546 rust.determinism > bash.determinism,
547 "cargo lockstep > shell env drift"
548 );
549 }
550
551 #[test]
552 fn comparison_deltas_are_consistent() {
553 let cmp = compare_languages(Language::Rust, Language::Bash);
554 assert!(cmp.fitness_delta > 0.0);
555 let sum: f64 = cmp.axis_deltas.iter().map(|(_, d)| d).sum();
556 assert!(
557 (sum / 4.0 - cmp.fitness_delta).abs() < 1e-9,
558 "fitness delta = mean of axis deltas"
559 );
560 let disp = format!("{cmp}");
561 assert!(disp.contains("rust vs bash"));
562 }
563}