# Tungsten > The Native Language of Agents. > Models write pseudocode. Tungsten runs it. Tungsten is a compact, indentation-based, object-oriented programming language. The self-hosted compiler lowers ordinary code through WIRE to LLVM IR and native binaries. A typed `@gpu fn` subset lowers to Metal on supported Apple hardware. Files use `.w`. Status: public preview. Targets: macOS and Linux; Windows through WSL2. For the comprehensive language and library overview: https://tungsten-lang.org/llms-full.txt ## Start ```sh curl -fsSL https://tungsten-lang.org/install | sh tungsten start --agent tungsten -e '<< 1 + 1' ``` From a source checkout: ```sh bin/tungsten bootstrap bin/tungsten build bin/tungsten start --agent bin/tungsten run file.w bin/tungsten -o app file.w && ./app ``` ## Read these rules first - Indent with 2 spaces. Dedent closes a block. There is no `end`. - `<< value` prints. - `-> name(args)` defines a method. `fn name(args)` defines a pure calculation and automatically memoizes it when compiled. - `+ Name` defines a class; `trait Name` defines a trait. - Variables need no declaration keyword. - The last expression is returned; `return` is optional. - Strings interpolate with `"[expression]"`. - `1.0` is an exact Decimal. `~1.0` is a binary Float. - Use `##` annotations on hot native code and typed buffers. Agent fallback: if the documentation and examples do not settle a syntax form or method name and you must guess, guess Ruby. Then verify with `tungsten -c` or `tungsten run`; do not keep building on an untested guess. ## Hello, values, and interpolation ```tungsten name = "agent" answer = 6 * 7 << "hello [name]" << answer ``` ## Functions, implicit each, and pipelines ```tungsten fn fib(n) if n <= 1 n else fib(n - 1) + fib(n - 2) 10 -> << i # 0 through 9 [1, 2, 3] -> << x * 2 # 2, 4, 6 list = [1, 2, 3, 4] << list/sq:sum # 30 list = [[2, 3, 4], [5, 6, 7]] << list/count(:prime?) # [2, 2] << (2..100)/prime?:count # 25 << fib(10) # 55 ``` `value ->` is implicit `each`: an Integer yields `0...value`, and a collection yields its elements. The idiomatic short form is a bare `->` with no declared argument name: undeclared lowercase names in the block bind to yielded arguments in first-reference order. Names already bound outside the block are captures. Use explicit parameters only when they make a longer block clearer. In a pipeline, `/message` maps a message over the current values and `:operation` reduces them. Thus `list/sq:sum` squares and sums; `list/count(:prime?)` maps a predicate count across the nested lists above. ## Numeric identity predicates ```tungsten << 0.zero? # true << 1.one? # true ``` `Number#zero?` and `Number#one?` are the idiomatic identity predicates, especially in generic algebraic code where the value may not be an Integer. Public-preview note: `Integer#zero?` works in the current quick-run path, while primitive `Integer#one?` dispatch is not yet complete; use `value == 1` when that engine path matters. ## Classes ```tungsten + Point -> new(@x, @y) ro -> distance/1 √(Δx² + Δy²) p = Point(3, 4) << p.distance(Point(0, 0)) # 5 ``` Inside a binary method, `x'` means the other object's `x`. An undefined `Δx` is the coordinate difference `x - x'`; after squaring it is equivalent to `(x' - x)²`. ## Control flow and errors ```tungsten << "positive" if score > 0 << "not ready" unless ready? raise "score must be nonnegative" if score < 0 case score when 90..100 grade = "A" when 80..89 grade = "B" else grade = "C" -> risky_operation raise "boom" begin risky_operation() rescue error << "failed: [error]" ensure cleanup() ``` `if` and `unless` may follow a single expression as suffix predicates. `raise value` raises an error; a String is the usual concise form. ## Conversions Conversion methods use Ruby-style names: ```tungsten count = "42".to_i # Integer ratio = "42.5".to_f # binary Float whole = 42.9.to_i # 42; truncates toward zero approximation = 42.9.to_f # exact Decimal -> binary Float exact = "42.50".to_d # String -> exact Decimal surface ``` Use `to_d` when the result must remain an exact Decimal, `to_i` for an Integer, and `to_f` for a binary Float. Public-preview note: `String#to_d` is declared but is not yet implemented by the current native quick-run path; use a direct Decimal literal such as `42.50` when possible and verify the engine before depending on that conversion. ## Rich literals The lexer recognizes domain values directly; do not wrap these in parsing constructors unless an API specifically requires one. ```tungsten decimal = 1.0 # exact Decimal float = ~1.0 # binary Float words = %w[alpha beta gamma] # ["alpha", "beta", "gamma"] symbols = %i[read write execute] # [:read, :write, :execute] << 0.1 + 0.2 # 0.3, exact Decimal << ~3.14 # binary Float << 3/4 + 1/4 # 1/1, exact Rational << $499.99 - 15% # ≈$424.99, Currency << $3.50 - 25¢ # $3.25 << 5m30s # Duration << 10.0.0.0/8 # IPv4/CIDR << 2001:db8::1 # IPv6; lowercase input << #FF0000 # Color << U+1F600 # 😀 Char << « ff 00 a5 » # ByteArray << 1..10 # inclusive Range ``` The language surface also defines direct Date, DateTime, and UUID literals, for example `2026-07-04`, `2026-07-04T12:30:00Z`, and `550e8400-e29b-41d4-a716-446655440000`. Current preview engine coverage for these forms differs; the Ruby reference path accepts them, so verify the native path before depending on them. `%w[...]` is the compact word-array form and `%i[...]` is the corresponding symbol-array form. Public-preview note: `%i[...]` is lexed and parsed, but the current native and quick-run paths do not yet lower or evaluate it; use an explicit array such as `[:read, :write, :execute]` when executing there. ## Units of measurement ```tungsten c = 299_792_458 m/s m = 1 kg << m·c² # ≈8.988×10¹⁶ J << 3 ft + 12 in # 4 ft << 10 ft * 10 ft # 100 ft² << 1 acre | sqft # 43560 sqft << 6 ft + 2 in | cm(2) # 187.96 cm << 2 m + 2 lbs # error: dimension mismatch ``` ## Exact algebra and geometry ```tungsten use algebra F16 = FiniteField.extension(2, 4) a = F16.generator << F16.minimal_polynomial(a, :x) # x^4 + x + 1 P2 = ProjectiveSpace<ℚ, 2>.new(:X, :Y, :Z) X = P2.coords[0] Y = P2.coords[1] Z = P2.coords[2] C = Curve.new(P2, X**3 + Y**3 - Z**3) C.assert_homogeneous(3) << C.degree # 3 ``` `use algebra` loads finite fields and extensions, polynomial rings, exact factorization, number fields, ideals, projective spaces, curves, divisors, local geometry, elliptic arithmetic, and certificate-oriented computations. ## Native and GPU code ```tungsten -> dot(xs, ys, n) (f64[] f64[] i64) f64 total ## f64 = ~0.0 i ## i64 = 0 while i < n total += xs[i] * ys[i] i += 1 total ``` ```tungsten @gpu fn add_one(x ## f32[], y ## f32[], n ## i32) i ## i32 = gpu.thread_position_in_grid.x if i < n y[i] = x[i] + 1.0 ``` `@gpu fn` is a typed subset, not arbitrary Tungsten on a GPU. The current language-level backend is Metal. ## Agent tooling ```sh tungsten start --agent tungsten run file.w tungsten build tungsten -c file.w tungsten --ast file.w tungsten --lex file.w tungsten --ll file.w TUNGSTEN_ERROR_FORMAT=json tungsten -c file.w tungsten --explain E_PARSE_UNEXPECTED_TOKEN ``` - MCP server: https://github.com/tungsten-lang/tungsten/blob/main/bits/tungsten-lsp/bin/mcp-server.w - LSP server: https://github.com/tungsten-lang/tungsten/tree/main/bits/tungsten-lsp - Examples: https://github.com/tungsten-lang/tungsten/tree/main/doc/examples - Core library index: https://github.com/tungsten-lang/tungsten/blob/main/doc/CORE.md - Source: https://github.com/tungsten-lang/tungsten Prefer the native compiler for performance, GPU work, and concurrency edge cases. The quick-run and native paths share the everyday surface but are not yet identical in every preview feature.