tycho-lang.com v0.7.0
Tycho / implicit arenas · value semantics transpiles to C / no GC
DOC. NO. 001 — MEMORY MODEL TYCHO An experimental systems language · transpiles to C

Automatic memory management. No garbage collector, no manual free.

A research project testing one idea: implicit hierarchical arenas under value semantics. Every scope owns a memory arena, freed on exit. There is no reference type, so the compiler can place every allocation and free from your code's structure alone. New here? Start with the tutorial ↗ — builds with cc and make, nothing else.

Spec — at a glance
v0.7.0tagged release
cc + makewhole toolchain
no GCarenas from scope
45stdlib packages
723gated fixtures

§01 The idea

Memory comes from scope, not a runtime.

A /

Every scope owns an arena

Allocation is a pointer bump. When the scope exits, the whole arena is freed in one step.

B /

No reference type

b := a copies. The compiler sees every value's lifetime from the syntax alone.

C /

Compiler-placed memory

Every allocation and free is inserted for you — no GC, no manual free, nothing to annotate.

LISTING 01 — examples/count.tyone buffer · O(n)
fn main():
    total := ""
    for i := 1; i < 6; i += 1:
        total = total + str(i)
        if i < 5:
            total = total + ", "
    println("counted: " + total)   # counted: 1, 2, 3, 4, 5

Listing 01. The string built inside the loop lives in main's arena — the compiler frees it for you on return.

FIG. 01— arena lifetimes
Arena lifetimes. Each bar is one allocation, drawn from where it is made to where it is freed. A scope's allocations all end on the same line — leaving the scope frees its whole arena in one step. The highlighted value is returned, so it crosses that line and lives on in main's arena.

§02 Why it stays fast

Value semantics, without the copies you'd expect.

  • A value can leave a scope only two ways, both visible in the source: down into a callee, or up to the caller.
  • A value you build and return is allocated straight into the caller's arena — return moves it, it doesn't copy.
  • acc = acc + x in a loop grows one buffer in place: the textbook O(n²) string build becomes O(n).

Where the model helps and where it costs are both measured — as machine-specific ratios, with the workloads that produce them — in the performance notes ↗. Pointer-shaped data like graphs and trees is where value semantics is least free, and the docs are honest about that.

LISTING 02 — examples/promote.tyreturn moves · zero copies
struct Person:
    name: string
    age: int

fn promote(p: Person) -> Person:
    q := p                # a full, independent copy
    q.age = p.age + 1
    return q             # moved into caller's arena, not copied

fn main():
    ada := Person("Ada", 36)
    older := promote(ada)
    println(str(ada.age) + " " + str(older.age))   # 36 37

Listing 02. return moves the value into the caller's arena; the copy q := p stays independent.

§03 The language

Small, and Go/Odin-shaped.

Python/Nim-flavored syntax, Go/Odin-like semantics; the value-semantics core comes from Hylo ↗.

Core
  • Value semanticsno aliasing, no GC
  • Generics$T, monomorphized
  • Sum typesOption / Result, match
Shape
  • Methods (UFCS)no classes
  • Closuresvalue capture
Systems
  • Concurrencyspawn, channels, parallel-for
  • FFI to Cextern fn, handles, bytes
  • Packages + corelibimport, 45 packages

§04 How it's checked

An experiment, but a heavily-checked one.

CompilerOne reference implementation, written in C, transpiling to C99 that any host compiler will take.
Corpusmake test builds and runs 723 fixtures against committed goldens, each under ASan/UBSan/LeakSanitizer.
SanitizersA fuzzer runs random programs through two builds of each program — native -O2 against ASan/UBSan — and the disagreement is the oracle; every example is built twice and compared to a golden.
Gatemake ci runs the whole check suite on your own machine — there's no cloud CI to take on faith.

It's experimental in scope, not in rigor — the honest caveats live in the performance notes ↗.

§05 Try it

A C compiler and make — that's the whole toolchain.

LISTING 02b — terminalprebuilt — nothing to build
# Linux x86-64; a Windows build is on the same release page
$ curl -fsSLO https://github.com/StefanVonRanda/tycho/releases/download/v0.7.0/tycho-v0.7.0-linux-x86_64.tar.gz
$ curl -fsSLO https://github.com/StefanVonRanda/tycho/releases/download/v0.7.0/tycho-v0.7.0-linux-x86_64.tar.gz.sha256
$ sha256sum -c tycho-v0.7.0-linux-x86_64.tar.gz.sha256
tycho-v0.7.0-linux-x86_64.tar.gz: OK
$ tar xzf tycho-v0.7.0-linux-x86_64.tar.gz && cd tycho-v0.7.0-linux-x86_64
$ ./tychoc examples/hello.ty && ./examples/hello
built examples/hello
what is your name: Ada
hello Ada

Listing 02b. The prebuilt route: the tarball carries tychoc, the core library and the examples. You still need cc — it is what tychoc hands the generated C to. Building from source below ends at the same prompt.

LISTING 03 — terminalhello.ty — the success-criterion demo
# a `cc` and `make`, nothing else
$ git clone https://github.com/StefanVonRanda/tycho
$ cd tycho
$ make                                  # builds ./tychoc
$ ./tychoc examples/hello.ty && ./examples/hello
built examples/hello
what is your name: Ada
hello Ada

Listing 03. The success-criterion demo: ask for a name, greet it.