Tungsten – an expressive, fast programming language

jeffpeterson1 pts0 comments

Tungsten — Pseudocode that runs. Public preview version 2026.07.04

PUBLIC PREVIEW · v2026.07.04

Object-oriented · self-hosted · LLVM + Metal

Pseudocode<br>that runs.

An object-oriented language that reads like the math on your whiteboard — then compiles, through a compiler written in itself, to native binaries via LLVM and GPU kernels via Metal. No end, no braces, no return. Fewer tokens for the humans and the models reading along.

Install Tungsten →<br>Read the Docs

$ curl -fsSL tungsten-lang.org/install | sh<br>Copy

demo.w

1# Currency and percentages<br>2price = $499.99<br>4 price - 15% # => ≈$424.99<br>5 price - 15% + 8.25% # => ≈$460.05<br>7# Units of measurement<br>8c = 299_792_458 m/s<br>9m = 1 kg<br>10<br>11 e = m·c² # => ≈8.988×10¹⁶ J<br>12<br>13 3 ft + 12 in # => 4 ft<br>14 10 ft * 10 ft # => 100 ft²<br>15 2 m + 2 lbs # => error: dimension mismatch

Why Tungsten

No ends. No braces.<br>Just the algorithm.

Tungsten strips programming to its mathematical essence. Write code that looks like the pseudocode you'd put on a whiteboard.

💰

Native Currency

First-class support for dollars, cents, and percentage operations. No more floating-point money bugs.

$3.50 - 25¢ # => $3.25

📐

Units That Catch Your Mistakes

Meters, feet, kilograms — with automatic conversion and dimensional analysis, so mismatched units fail loudly instead of becoming bad numbers.

1 cm * 1 cm * 1 cm # => 1 cm³

Math That Reads Like Math

Write mathematical notation directly. Square roots, superscript exponents, deltas — your code reads like the textbook.

√(Δx² + Δy² + Δz²)<br>3² + 4² # => 25

🧱

Classes Without Noise

Define classes with +, methods with ->, output with . Arity is explicit. Everything else melts away.

+ Point<br>-> new(@x, @y, @z) ro

🎯

Exact Decimals by Default

3.14 is an exact decimal, not an IEEE float. Approximation is opt-in with ~ — so the default never surprises your accountant.

exact = 3.14 # Decimal<br>approx = ~3.14 # Float, opt-in

🌀

Complex, Quaternions & Beyond

Complex numbers, quaternions, octonions, sedenions — one generic implementation, specialized per scalar type, all the way out to 256-dimensional algebras.

z = Complex.new([~3.0, ~4.0])<br>z.abs # => 5

The GPU Is One Annotation Away

@gpu fn compiles a Tungsten function to Metal Shading Language — same file, same syntax, no FFI, no strings of C.

@gpu fn add_one(x, y, n)<br>i = gpu.thread_position_in_grid.x

🧠

Tensors, Zero-Copy on Metal

One allocation, three faces: a CPU array, a Metal buffer, and tensor views when the platform supports them — sharing the same bytes. Attention runs end-to-end on-device.

q = x.linear(wq) # bf16, on the GPU<br>attn = scores.softmax(1)

🤖

Dense by Design

No end, no braces, no self, no return. Every keyword the syntax omits is a token neither you nor a model has to spend — so more algorithm fits in the same context window.

# the whole method, not the ceremony<br>-> area w * h

By Example

Read it like pseudocode

Concrete examples from the language surface — nine features, one tab each.

Classes<br>Blocks<br>Case / recase<br>Generics<br>GPU<br>Tensors<br>Math Modes<br>Currency<br>Physics

Classes Without the Noise

Define a class with +, a method with ->, and output with . Arity after the slash tells you exactly how many arguments a method takes.

Instance variables are declared inline in the constructor with @. The ro suffix makes them read-only. No boilerplate getters, no verbose accessor declarations.

The prime notation (x') refers to the same-named property on the argument — so x - x' means "my x minus their x." And Δx is that difference in one glyph: √(Δx² + Δy² + Δz²) is a distance method that runs.

point.w

1+ Point<br>2 -> new(@x, @y, @z) ro<br>4 -> distance/1<br>5 dx = x - x'<br>6 dy = y - y'<br>7 dz = z - z'<br>9 (dx.sq + dy.sq + dz.sq).sqrt<br>10<br>11 # or, if you prefer<br>12 -> distance/1<br>13 √(Δx² + Δy² + Δz²)<br>14<br>15 Point(3, 4, 0).distance(Point(0, 0, 0)) # => 5

Blocks With an Implicit Subject

A block is just -> followed by an expression, and inside it item is already bound. No pipes, no lambda keyword, no parameter list for the common case.

Block passthrough goes further: pass a trailing block to a method that doesn't take one, and the block iterates the method's result. bag.items -> s += item loops over what items returns.

Accumulator methods read like recurrences — -> sum 0 declares the initial value inline, and the body folds into it.

blocks.w

1# blocks bind `item` implicitly<br>2squares = [1, 2, 3].map -> item ** 2<br>3evens = (1..10).select -> item % 2 == 0<br>5 squares # => [1, 4, 9]<br>6 evens.sum # => 30<br>8# block passthrough: a trailing block on a<br>9# no-block method iterates its result<br>10+ Bag<br>11 -> items<br>12 [10, 20, 30]<br>13<br>14s = 0<br>15Bag.new().items -> s += item # s => 60<br>16<br>17# even `n.times` is just passthrough on an Int<br>18u = 0<br>19(-5).abs -> u += 1 # runs 5 times

Case, Meet recase

Dispatch with case/when, close blocks by dedent. When an arm needs to re-enter the decision with a new value, recase expr re-dispatches the enclosing case — structured, no goto, no loop...

tungsten method like point runs metal

Related Articles