Back to browse
GitHub Repository

A small, closed, Unicode-first language that emits Rust.

3 starsRust

Topaz – A small application language that compiles through Rust

by yo_tafo·Jun 18, 2026·2 points·1 comment

AI Analysis

●●SolidWizardryBig Brain

Transpiles to Rust for native binaries without the borrow checker headache.

Strengths
  • Differential harness ensures interpreter and compiler output match exactly.
  • Zero external dependencies and forbid unsafe code across the entire workspace.
  • Unicode-first identifiers allow non-ASCII variables without silent normalization.
Weaknesses
  • New language means zero ecosystem libraries compared to Python or Rust.
  • Performance promises explicitly disclaimed in this early v5.2 public release.
Target Audience

Backend developers wanting Rust performance without Rust syntax

Similar To

Nim · Carbon · V

Post Description

Hi HN, I'm Matt, CTO at STUDIO HAZE in Seoul. I've wanted to build a programming language for twenty years, ever since Ruby got me wondering what a small language out of Korea might look like. Today I'm opening the repo for the first time, as Topaz v5.2.

Topaz reads like Python or TypeScript, runs on a reference interpreter (topaz run), and builds a self-contained native binary by lowering to Rust, then handing off to the Rust toolchain (topaz build).

function factorial(n: int) -> int { if n < 2 { return 1 } return n * factorial(n - 1) } print("10! = {factorial(10)}") // 10! = 3628800

The idea: application logic should have a small, fixed surface with one obvious way to write each thing, and the compiler does the hard part underneath. Writing glue in Python and TS, I kept re-making the same policy decisions — errors, absence, cleanup. Topaz decides those once: Result for recoverable failure, optionals for absence, defer for cleanup.

Identifiers are Unicode from the lexer up, with no implicit normalization — names compare by scalar sequence, so what you typed is what matches. Deliberate, not an oversight: NFC and NFD forms aren't silently merged, and the module resolver rejects imports that would collide under NFC/NFD or case folding.

function 인사하기(이름: string) -> string { return "안녕하세요, {이름}님!" } print(인사하기("토파즈")) // 안녕하세요, 토파즈님!

sql, sh, and path strings are tagged templates: interpolations stay structurally separate from the literal text, so a value is never spliced into the query as raw SQL. Below, a classic injection attempt; the printed value is the template's structure, not a concatenated string:

let user = "'; DROP TABLE t; --" let q = sql"SELECT * FROM t WHERE name = {user}" print("{q}") // <sql template, 2 part(s), 1 interpolation(s)>

To be clear on scope: this is a representation, not a database driver — there's no query-execution or parameter-binding layer yet. Injection is impossible by construction at this layer; a driver that consumes the value safely is future work.

Why compile through Rust instead of C or LLVM? I'm not trying to replace Rust — if you want to write Rust, write Rust. It's just a good thing to land on: I inherit its memory safety and a mature backend for free, the build is reproducible, and the binary needs no Topaz runtime. Topaz is what you write; Rust is what it becomes.

Every fixture runs through both the interpreter and the compiler, and their stdout and exit status must agree; the moment they diverge, a test goes red. Both engines share the same runtime value model, so agreement is structural, not coincidental. cargo test --workspace is green at 635 tests. CI runs on Linux, macOS, and Windows, and every commit clears clippy -D warnings and cargo fmt --check.

Implementation notes:

- Whole toolchain (lexer, parser, checker, interpreter, emitter) is pure Rust, zero crates.io dependencies, forbid(unsafe_code). - The module resolver rejects path collisions from platform-specific case folding or normalization, keeping imports unambiguous across OSes.

Some history, since opening at v5.2 looks odd: v1 was a Lisp dialect (now separate), v2 a Python-like surface, v3 and v4 an internal tool we ran next to Rust in our products. v5.2 is the first version I'm comfortable showing.

The honest catch: it's early, with basically no ecosystem yet. The topaz binary runs, checks, and emits on its own, but topaz build shells out to cargo, so that command needs a working Rust toolchain. This is not "easy Rust." It's a small application surface that happens to compile through Rust.

Docs at https://topaz.ooo. License Apache-2.0. Try it with:

topaz run examples/hello.tpz topaz build examples/hello.tpz --out-dir out --run

I'd love feedback on the diagnostics, the generated Rust, the module semantics, and Unicode edge cases. Please tear into it.

Similar Projects

Developer Tools●●Solid

Nimic – write pure Python and compile AOT to native binaries via Nim

Python-to-Nim transpiler with ctypes-backed types when Cython and Numba already exist.

Big BrainNiche Gem
dima-quant
5018d ago