Language Survey · Public Preview · version 2026.07.04

Tungsten vs the field

A release timeline of the field, the same program shown side by side, a feature matrix, and an honest accounting of where each language wins.

Orientation

What each language optimizes for

No language is wrong; each one chose a different thing to never compromise on. Knowing the prime directive explains nearly every design decision downstream of it.

1960 1970 1980 1990 2000 2010 2020

Tungsten 2026 · preview

"Pseudocode that runs."
Memory
Compile-time free insertion
Types
Dynamic + gradual ## T hints
Compiles
Native via LLVM; GPU via Metal
Never gives up
Readability-per-token

C 1972

"Trust the programmer."
Memory
Manual malloc/free
Types
Static, weak
Compiles
Native, everywhere
Never gives up
Proximity to the machine

Rust 2015

"Fearless systems programming."
Memory
Ownership + borrow checker
Types
Static, strong, inferred
Compiles
Native via LLVM
Never gives up
Memory safety without GC

Python 1991

"Readability counts."
Memory
Refcount + cycle GC
Types
Dynamic + optional hints
Compiles
Bytecode interpreter
Never gives up
The ecosystem

Ruby 1995

"Optimize for programmer happiness."
Memory
GC
Types
Dynamic, duck
Compiles
Bytecode + YJIT
Never gives up
Expressiveness

Go 2009

"Simplicity at scale."
Memory
GC, low-latency
Types
Static, structural interfaces
Compiles
Native, fast builds
Never gives up
Team velocity

Zig 2016

"No hidden control flow."
Memory
Manual, explicit allocators
Types
Static + comptime
Compiles
Native; best-in-class cross-compile
Never gives up
Explicitness

Odin 2016

"The joy of data-oriented programming."
Memory
Manual + context allocators
Types
Static, distinct
Compiles
Native via LLVM
Never gives up
Simplicity for games/tools

Swift 2014

"Safe, fast, expressive — for Apple's world."
Memory
ARC (automatic refcounting)
Types
Static, strong, inferred
Compiles
Native via LLVM
Never gives up
Platform integration

Fortran 1957

"Speed for the sciences."
Memory
Static + stack; manual since F90
Types
Static, strong
Compiles
Native, everywhere
Never gives up
Array & numerical speed

C++ 1985

"Zero-overhead abstraction."
Memory
Manual + RAII / smart pointers
Types
Static, strong
Compiles
Native via LLVM / GCC
Never gives up
You don't pay for what you don't use

Java 1995

"Write once, run anywhere."
Memory
GC on the JVM
Types
Static, nominal
Compiles
Bytecode → JIT (JVM)
Never gives up
Portability & the JVM

Julia 2012

"The speed of C, the feel of Python."
Memory
GC
Types
Dynamic + multiple dispatch
Compiles
JIT via LLVM
Never gives up
Science without two languages

Haskell 1990

"Purely functional, lazy by default."
Memory
GC
Types
Static, inferred, very strong
Compiles
Native via GHC
Never gives up
Purity & the type system

JavaScript 1995

"The language of the web."
Memory
GC
Types
Dynamic, coercive
Compiles
JIT (V8, JSC, …)
Never gives up
It runs everywhere

Clojure 2007

"A practical Lisp for the JVM."
Memory
GC on the JVM
Types
Dynamic; code is data
Compiles
JVM bytecode (JIT)
Never gives up
Immutability & the REPL

C# 2000

"Pragmatic OO for the .NET platform."
Memory
GC (CLR)
Types
Static, strong, inferred
Compiles
IL → JIT; Native AOT
Never gives up
Tooling & the ecosystem

Scala 2003

"Object-oriented and functional, fused."
Memory
GC (JVM)
Types
Static, strong, inferred
Compiles
JVM bytecode; Scala Native
Never gives up
Types and FP together

Kotlin 2011

"A better Java, pragmatically."
Memory
GC (JVM)
Types
Static, strong, inferred
Compiles
JVM bytecode; native / JS
Never gives up
Ergonomics & Java interop
Syntax

One program, nine languages

A 3-D Point with a constructor, read-only fields, a distance method, and a call — the everyday unit of object-shaped code. Watch the ceremony-to-algorithm ratio.

Tungsten
C
Rust
Python
Ruby
Go
Zig
Odin
Swift
point.w7 lines
+ Point -> new(@x, @y, @z) ro -> distance/1 (Δx² + Δy² + Δz²) << Point(3, 4, 0).distance(Point(0, 0, 0)) # => 5

What's happening: + opens a class, -> new(@x, @y, @z) ro declares the constructor, binds three read-only instance fields, and generates the accessors — one line. distance/1 says the method takes one argument; Δx means "my x minus theirs" (shorthand for x - x', the prime reading the argument's same-named property). The algorithm is the line √(Δx² + Δy² + Δz²) — exactly what you'd write on the whiteboard, and it runs.

point.c14 lines
#include <math.h> #include <stdio.h> typedef struct { double x, y, z; } Point; double distance(Point a, Point b) { double dx = a.x-b.x, dy = a.y-b.y, dz = a.z-b.z; return sqrt(dx*dx + dy*dy + dz*dz); } int main(void) { printf("%g\n", distance((Point){3,4,0}, (Point){0,0,0})); }

The trade: No methods, no encapsulation — a struct and a free function. Honest and fast, but read-only fields, accessors, and namespacing are all on you. And nothing stops distance from being handed a struct of kilograms.

point.rs13 lines
struct Point { x: f64, y: f64, z: f64 } impl Point { fn distance(&self, o: &Point) -> f64 { ((self.x-o.x).powi(2) + (self.y-o.y).powi(2) + (self.z-o.z).powi(2)).sqrt() } } fn main() { let p = Point { x: 3.0, y: 4.0, z: 0.0 }; println!("{}", p.distance(&Point { x: 0.0, y: 0.0, z: 0.0 })); }

The trade: Compile-time memory safety with zero runtime cost — and the &self/&Point borrow ceremony that buys it. Data and behavior live in separate blocks (struct + impl). Immutability is the default, which Tungsten asks you to declare with ro.

point.py12 lines
import math from dataclasses import dataclass @dataclass(frozen=True) class Point: x: float; y: float; z: float def distance(self, o): return math.sqrt((self.x-o.x)**2 + (self.y-o.y)**2 + (self.z-o.z)**2) print(Point(3,4,0).distance(Point(0,0,0)))

The trade: Closest to Tungsten in spirit — significant whitespace, dynamic types. But read-only fields take a decorator import (@dataclass(frozen=True)), self is threaded by hand, and every dunder convention is one more thing to know. Tungsten folds all of that into -> new(@x, @y, @z) ro.

point.rb13 lines
class Point attr_reader :x, :y, :z def initialize(x, y, z) @x, @y, @z = x, y, z end def distance(o) Math.sqrt((x-o.x)**2 + (y-o.y)**2 + (z-o.z)**2) end end puts Point.new(3,4,0).distance(Point.new(0,0,0))

The trade: Tungsten's closest ancestor — message-passing OO, blocks, expressiveness-first. The visible differences are the ends, the separate attr_reader declaration, and the constructor assignment line. Tungsten is roughly "Ruby with the ceremony dedented away."

point.go15 lines
package main import ( "fmt" "math" ) type Point struct{ X, Y, Z float64 } func (p Point) Distance(o Point) float64 { return math.Sqrt(math.Pow(p.X-o.X, 2) + math.Pow(p.Y-o.Y, 2) + math.Pow(p.Z-o.Z, 2)) } func main() { fmt.Println(Point{3, 4, 0}.Distance(Point{0, 0, 0})) }

The trade: Maximum uniformity — one obvious way to write everything, which is why teams scale on it. The cost: exported-by-capitalization, no operator for **, and visibility/ceremony rules that exist for the linker, not the reader.

point.zig16 lines
const std = @import("std"); const Point = struct { x: f64, y: f64, z: f64, fn distance(self: Point, o: Point) f64 { const dx = self.x - o.x; const dy = self.y - o.y; const dz = self.z - o.z; return @sqrt(dx*dx + dy*dy + dz*dz); } }; pub fn main() void { const p = Point{ .x = 3, .y = 4, .z = 0 }; std.debug.print("{d}\n", .{p.distance(.{ .x = 0, .y = 0, .z = 0 })}); }

The trade: Nothing happens that you can't see — no hidden allocation, no operator overloading, no exceptions. Superb for systems work; verbose for math, where @sqrt builtins and .{ .x = … } literals stand where notation could be.

point.odin14 lines
package main import "core:fmt" import "core:math" Point :: struct { x, y, z: f64 } distance :: proc(a, b: Point) -> f64 { dx := a.x - b.x; dy := a.y - b.y; dz := a.z - b.z return math.sqrt(dx*dx + dy*dy + dz*dz) } main :: proc() { fmt.println(distance(Point{3, 4, 0}, Point{0, 0, 0})) }

The trade: Deliberately procedural — no methods at all, by design. Notably for this survey: Odin has built-in fixed-size matrix and array-programming types, the only other language here that treats linear algebra as a language concern rather than a library.

point.swift11 lines
import Foundation struct Point { let x, y, z: Double func distance(to o: Point) -> Double { ((x-o.x)*(x-o.x) + (y-o.y)*(y-o.y) + (z-o.z)*(z-o.z)).squareRoot() } } print(Point(x: 3, y: 4, z: 0).distance(to: Point(x: 0, y: 0, z: 0)))

The trade: The most ergonomic static language in the survey — memberwise initializers, let immutability, argument labels that read like prose. The closest competitor to Tungsten's ceremony count, with static types; it's also the other language here with first-class Metal access (via separate .metal files, not in-language kernels).

The Matrix

Feature by feature

✓ first-class  ·  ~ partial, library-grade, or in flux  ·  — absent by design or omission. Preview-status Tungsten features are footnoted, not hidden.

FeatureTungstenCRustPythonRubyGoZigOdinSwiftClojureJSHaskellC#ScalaKotlinJuliaFortranC++Java
Blocks close by dedent ~layout rule~Scala 3 indent
Exact decimals by default1 3.14 is Decimal; ~3.14 floats~decimal module~BigDecimal~Decimal lib~0.1M; ratios~Scientific lib~decimal type~BigDecimal~BigDecimal~Rational, BigFloat~BigDecimal
Unit-of-measure literals2 299_792_458 m/s~uom crate~pint lib~Measurement API~units pkg~squants lib~Unitful.jl~user-defined literals~units lib
Currency literals2 $3.50 − 25¢
Unicode math notation √ Δ · ² Σ ∫~identifiers only~custom ops~custom ops√ ÷ ⋅ ×
Classes ~struct+impl~struct+method~struct+fnby design~defrecordES6 classdata + typeclassesstructs + dispatch~derived types
Traits / protocols trait + istraits~ABCsmodulesinterfaces~comptime duckprotocolsprotocolstypeclassesinterfacestraitsinterfaces~Holy traits~abstract interfaces~concepts (C++20)interfaces
Generics, monomorphized Complex<f64>macroshints only~GC-shapedcomptimeparapoly~+ witness tables~dictionaries~reified, JIT~erased + @specialized~reified inlineJIT-specializedtemplates~erased
Complex & quaternion numbers Complex→Sedenion, per scalar~num crates~cmath / numpy~Complex only~complex128~std Complex~complex+quat~Numerics pkg~ratio/bignum~Data.Complex~System.Numerics~Spire lib~libraryComplex built-inCOMPLEX native~std::complex~libraries
Pattern matching3 ~case/when + recase~switchmatchmatch (3.10)case/in~switch~switch~switchswitch~core.match~destructuringnativepatterns (C# 8+)match~when~Match.jl~select case~switch~switch (21)
Case re-dispatch (recase)
Operator overloading typed dispatchtraitsdundersby designby designNum instancesoperator fun~interface ops
GPU kernels in-language @gpu fn → MSLCUDA dialectwgpu/WGSL stringsTriton DSL~separate .metalWebGPU stringsAccelerate DSLILGPU libCUDA.jl kernels~CUDA FortranCUDA C++TornadoVM
Zero-copy GPU tensors Metal 4, bf16 attention~PyTorch / MLX~MPSGraph / MLX~TF.js~TorchSharpCuArray~libtorch / Eigen~DJL
FP math modes, scoped @strictmath/@fastmath blocks~per-file flagsintrinsics only@setFloatMode@fastmath~compiler flags~pragmasstrictfp
Memory management compile-time freemanualownershiprefcount+GCGCGCmanual+allocatorsmanual+contextARCGC (JVM)GCGCGC (CLR)GC (JVM)GC (JVM)GCmanual/allocatablemanual + RAIIGC (JVM)
Compiles to native LLVM~GraalVMGHC~Native AOT~Scala Native~Kotlin/Native~JIT (LLVM)~GraalVM
Self-hosted compiler stage1 ≡ stage2 .llCPython is CCRuby is CC++~C++ core~ClojureScriptV8 is C++GHC in HaskellRoslyn in C#scalac in Scala~kotlinc~Julia + C++gfortran is CGCC/Clang in C++javac in Java
REPL plots, live scrubnREPLnodeGHCicsiscalakotlinc~LFortran~clingjshell
String interpolation "[x]" + unit conversion~format! macrof""#{}\(x)str concat${…}$"{x}"s"$x""$x""$x"std::formatString.format
Structured concurrency4 ~goroutines~pthreadsasync + threads~asyncio, GIL~threads/ractorsgoroutines~in flux~threadsactorscore.async, STM~async, 1 threadSTM, green threadsasync/TaskFuture, AkkacoroutinesTasks, @spawncoarraysstd::threadthreads, virtual
Package manager ~bit + registry, previewcargopipgemmodules~build.zig.zonvendoredSPMdeps.ednnpmcabalNuGetsbtGradlePkgfpm~Conan / vcpkgMaven
Windows support macOS + Linux

1 Exact-decimal semantics are the language definition and the reference interpreter's behavior; the native compiler's decimal path is being hardened for the preview.  2 Units, currency, and percentage literals currently run on the reference interpreter; native-compiler support is on the preview roadmap.  3 Tungsten's destructuring patterns (=> arms with binding and guards) are specified but not yet implemented — today's compiler ships case/when plus the recase re-dispatch, which no other surveyed language has.  4 Tungsten ships goroutines; the fuller task/channel/supervisor model is still being built out. We mark it honestly.

Rich Literals

Tungsten is rich, literally

IP addresses, dates, money, rationals, colours — values the lexer reads as first-class tokens, where other languages reach for a string and a constructor. Every result below is real compiler output.

3/4 + 1/4 1/1 Rational
bare / gives an exact fraction — not 0, not 0.75
yyyy-mm-dd - yyyy-mm-dd Days
arithmetic straight on date literals
550e8400-e29b-41d4-a716-446655440000 UUID
a bare UUID — no quotes, no uuid.parse("…")
#FF0000 #FF0000 Color
yes — # is normally a comment; a hex colour is the exception
10.0.0.0/8 10.0.0.0/8 IPv4 · CIDR
the CIDR prefix is part of the value, not a substring
₹50/- ₹50.00 Currency
the Indian ₹50/- notation — plus £, ¥, ₩, €, and $. The sign picks the currency.
0.1 + 0.2 0.3 Decimal
exact by default; most others say 0.30000000000000004
:-) 41 Char
emojichars are short and fun
U+1F600 😀 Char
a bare codepoint literal — U+1F600 is 128512, no quotes or escapes
299_792_458 m/s 299792458 m/s Quantity
elsewhere: a units library and a lot of ceremony
yyyy-mm-ddThh:mm:ssZ DateTime
full ISO 8601 — no constructor, no parse step
1..10 1..10 Range
1...10 excludes the end
~3.14 3.14 Float
IEEE-754 is the opt-in, spelled with a leading ~
Deep Dives

Four dimensions where the differences bite

1 · Numbers: what does 0.1 + 0.2 equal?

Ask the others and binary floating point answers back. In Python, JavaScript, Ruby, Julia, Go, and most of the field, 0.1 + 0.2 surfaces as 0.30000000000000004; C and C++ print a tidy 0.3 only because their default precision rounds the error out of sight — it is still there. Either way, exactness is a library you must remember to import (Python's decimal, Ruby's BigDecimal, Rust's rust_decimal crate).

Tungsten inverts the default: 3.14 is an exact decimal, and binary floats are the opt-in, spelled ~3.14. The approximate thing carries the visual warning label, not the exact thing. Money, percentages, and measurements build on that foundation — they're literals, not libraries.

When you do want hardware floats, you get real control: three compile-time math modes and scoped @strictmath/@fastmath blocks, with FMA contraction rules precise enough to keep a determinant of equal products exactly zero.

numbers.w — Tungsten
# exact decimals by default — floats are opt-in with ~ << 0.1 + 0.2 # => 0.3 << 0.1 + 0.2 == 0.3 # => true price = $499.99 << price - 15% # => ≈$424.99 << $3.50 - 25¢ # => $3.25
numbers.py — Python
print(0.1 + 0.2) # => 0.30000000000000004 from decimal import Decimal print(Decimal("0.1") + Decimal("0.2")) # opt-in, # and Decimal(0.1) — without quotes — is already wrong

2 · Generics: who pays for abstraction?

Rust, Zig, and Odin monomorphize — every instantiation becomes specialized machine code, and abstraction costs nothing at runtime. Python and Ruby erase — types are hints or absent, and every operation pays dynamic dispatch. Go and Swift sit between (dictionary-passing and witness tables, with specialization when the optimizer feels like it).

Tungsten joins the monomorphizing camp — unusual for a dynamically-flavored language. Complex<f64>.new(…) stamps out a real Complex$f64 class with native f64 arithmetic, recursively specializing parent classes, validated against with T in (…) constraints.

One consequence worth bragging about: Complex, Quaternion, Octonion, Sedenion, and larger algebras up to 256 dimensions are all ordinary library code, specialized per scalar type, with typed operator-overload dispatch choosing the right * per operand pair.

complex.w — Tungsten
z = Complex<f64>.new([~3.0, ~4.0]) << z.abs # => 5 — native f64 all the way q = Quaternion<f32>.new([~1.0, ~0.0, ~0.0, ~0.0]) # Octonion, Sedenion … 256-dim algebras: same machinery
complex.rs — Rust
// num-complex crate; monomorphized the same way use num_complex::Complex; let z = Complex::<f64>::new(3.0, 4.0); println!("{}", z.norm()); // => 5 // quaternions: another crate; octonions: write your own

3 · The GPU: in the language, or bolted on?

This is the sharpest divide in the survey. In every mainstream language, GPU programming means leaving the language: CUDA C++ is a separate dialect with its own compiler; Python's Triton is an embedded DSL compiling traced Python; Rust passes WGSL shader strings to wgpu; Swift keeps kernels in separate .metal files behind ~40 lines of pipeline boilerplate.

In Tungsten, @gpu fn is a function annotation. The compiler lowers that function to Metal Shading Language while the rest of the file lowers to LLVM — one syntax, one file, no FFI, no string-embedded shaders. Simdgroup 8×8 cooperative matrices are available for tiled matmuls, and the Tensor class drives Metal 4 cooperative tensors for bf16 linear layers.

The honest caveat: today it targets Metal only — Apple GPUs. The dialect stack is designed for CUDA/WebGPU backends to attach later, but they don't exist yet. If you need NVIDIA today, Tungsten's GPU story isn't yours yet.

kernel.w — Tungsten
## f32[]: x ## f32[]: y ## i32: n @gpu fn add_one(x, y, n) i = gpu.thread_position_in_grid.x ## i32 if i < n y[i] = x[i] + 1.0 # host dispatch: same file, ~4 more lines
kernel.cu — CUDA C++
__global__ void add_one(float* x, float* y, int n) { int i = blockIdx.x * blockDim.x + threadIdx.x; if (i < n) y[i] = x[i] + 1.f; } // + cudaMalloc, cudaMemcpy ×2, launch config, // cudaFree … ≈25 lines of host ceremony, // in a separate compiler (nvcc), NVIDIA-only

4 · Memory & errors: the comfort spectrum

Memory: C and Zig hand you the allocator; Odin adds context-scoped allocators; Rust proves safety at compile time and charges you the borrow checker; Swift refcounts; Python, Ruby, and Go collect garbage. Tungsten frees at build time instead: its model is compile-time free insertion — escape analysis frees non-escaping heap values deterministically at compile time, so hot paths don't churn the heap in the first place.

Errors: Rust and Zig encode failure in return types (Result, error unions) — rigorous, and viral through every signature. Go spells it out longhand (if err != nil, a quarter of many functions). Python, Ruby, Swift, and Tungsten use exceptions (raise/rescue with conditional modifiers like raise X if y), keeping the happy path unindented.

Tungsten's choices here are deliberately conventional — the innovation budget went to notation, numerics, and the GPU, not to a novel memory or error model.

errors.w — Tungsten
-> withdraw(amount) raise InsufficientFunds if amount > @balance @balance -= amount
errors.go — Go
func (a *Account) Withdraw(amount int) error { if amount > a.balance { return fmt.Errorf("insufficient funds") } a.balance -= amount return nil }
Head to Head

Eight matchups, called fairly

vs C the substrate

Not really competitors — Tungsten's runtime is C, and its binaries link a C runtime. C wins on ubiquity, ABI, and a 50-year toolchain. Tungsten exists because "trust the programmer" doesn't scale to notation-heavy domains.

Tungsten: expressiveness, safety, GPU  ·  C: ubiquity, ABI, zero runtime

vs Rust the safety maximalist

Rust owns the systems niche: no GC, provable memory safety, fearless concurrency, cargo. Tungsten doesn't contest it — it offers monomorphized generics and native binaries without the borrow checker's learning curve, freeing memory at compile time instead, for domains where notation matters more than lifetime annotations.

Tungsten: ceremony, math notation, REPL  ·  Rust: no-GC safety, ecosystem, concurrency

vs Python the incumbent

Python's ecosystem is insurmountable in the short term — that's just true. Tungsten's counters: native binaries (ship a standalone executable, not a runtime), exact decimals by default, units in the language, GPU kernels without leaving the file, and dramatically fewer tokens per algorithm — which now also means cheaper LLM generation.

Tungsten: native speed, numerics, GPU, tokens  ·  Python: every library ever written

vs Ruby the ancestor

Tungsten is recognizably Ruby-descended — blocks, message passing, happiness-first. The pitch to a Rubyist is direct: keep the expressiveness, drop the ends, gain native binaries, real generics, complex & quaternion numbers, and a GPU. Rails has no Tungsten equivalent yet; Carbide is embryonic.

Tungsten: native compile, numerics, GPU  ·  Ruby: Rails, gems, 30 years of maturity

vs Go the team player

Go's goroutines, std library, and one-binary deploys make it the boring-in-a-good-way server language. Tungsten compiles to one binary too, and it has working goroutines — but Go's scheduler, tooling, and ecosystem are far more mature, so Go still wins the concurrent-server matchup. Tungsten wins when the problem is mathematical.

Tungsten: notation, numerics, GPU  ·  Go: concurrency, deploys, stdlib, team scale

vs Zig the explicit one

Opposite poles of one axis: Zig makes everything visible (allocators, control flow, errors); Tungsten makes everything disappear (ceremony, memory, dispatch). Zig's comptime and cross-compilation are genuinely brilliant. They share a virtue: both compilers explain exactly what they did.

Tungsten: brevity, notation, no manual frees  ·  Zig: explicitness, comptime, cross-compile

vs Odin the data-oriented craftsman

The other language here that believes linear algebra belongs in the language — Odin has built-in matrix types and array programming, aimed at games and tools. Odin rejects OO entirely; Tungsten is OO to the bone. Kindred spirits about math, opposite conclusions about objects.

Tungsten: OO, no manual memory, GPU codegen  ·  Odin: determinism, simplicity, SOA-friendly data

vs Swift the platform twin

The nearest neighbor: LLVM-compiled, Apple-platform-strong, ergonomics-obsessed, Metal-capable. Swift has Xcode, ABI stability, and a decade of production. Tungsten's differences: GPU kernels in-language (not separate .metal files), exact decimals, units, dedent blocks, and a REPL that plots. If you live outside Apple's world, Swift's edge shrinks and Tungsten's Linux story matters.

Tungsten: in-language GPU, numerics, brevity  ·  Swift: tooling, maturity, iOS/macOS APIs

Where the field is ahead — plainly

  • Maturity. Every other language here has shipped production software for 8–50 years. Tungsten is a public preview; expect sharp edges, and report them.
  • Ecosystem. cargo, pip, gems, and Go modules each host hundreds of thousands of packages. Tungsten's bit registry is just opening.
  • Concurrency. Tungsten has working goroutines, but the fuller structured-concurrency model (channels, supervisors) is still maturing. Go, Rust, and Swift are further along.
  • Windows. Tungsten targets macOS and Linux. Everyone else (except early-Swift history) runs on Windows.
  • Static guarantees. Rust, Swift, Zig, Odin, and Go catch whole bug classes at compile time that Tungsten, as a dynamic language with gradual hints, catches at runtime — or in your specs.
  • IDE support. rust-analyzer, gopls, Pyright, and SourceKit set a bar Tungsten's editor tooling hasn't reached yet.
  • GPU portability. @gpu fn targets Metal today. CUDA's ecosystem and NVIDIA's installed base are a different universe; the multi-dialect design anticipates more backends, but they aren't built.