talktalk is a small, fully-typed language that kind of looks like Swift or Rust or Go if you squint really hard.
It wants to feel familiar and cozy, but still pack modern power — type inference, sum types, protocols, algebraic effects, and a little IR it gets lowered into before a very little interpreter runs it.
It's mostly a way for me to understand compilers. You shouldn't use talktalk. But you might enjoy perusing it.
Goals & non-goalswhat this thing is trying to be, and isn't
01Learning stuff
This is by far the biggest goal. I didn't super understand all the ins and outs of compilers. I still don't, but at least I have a way to learn now.
02Fully typed everything
Types are cool. You can add them when you want and leave them off when you don't.
03As much type inference as possible
I don't know if it's a good idea. It's probably not. I just think it's neat.
04Familiar-ish syntax
Haskell/ML-y syntax is beautiful. I hate it. This one has braces.
05Algebraic effects
Effects are like exceptions, but also like coroutines, but also like dependency injection. I'll explain later. Maybe.
06Syntax highlighting color schemes
I feel like making a full programming language is the only way to do this. Right? Right? Don't answer.
01Blazingly fast performance
I'm probably not gonna litter the codebase with sleeps. But I'm allowed to if I want.
02Soundness & decidability
Is this even possible? I saw a YouTube video that said it's not.
03Getting anyone to use it
Why would I? PHP exists. Use that.
The language tourwhat you can actually write in it
Primitives
Some types you've probably seen before. Tuples and records are maybe a little less common but we've got 'em.
Variables & expressions
The last expression in a block is its value. No semicolons required; no semicolons denied either.
Functions
Plain, boring, good. Trailing blocks work for callback-y things too.
Type annotations
Annotate when you like. Everything gets checked either way.
Generics & inference
Polymorphic by default. Spell things out if you want.
// Or be explicit: func identity<T>(x: T) -> T { x }
Closures
Closures capture their environment. They're values, so you can pass them around.
Structs
Structs are fields plus methods. init blocks let you customize construction.
Enums & pattern matching
Sum types with associated values. Match on them with if-let, let-else, or full match expressions.
Protocols & associated types
Protocols can have required methods, default methods, and associated types with their own bounds.
Algebraic effects
Effects are declared with a leading ' and handled by @handle blocks. Useful for exceptions, async, DI — pick your poison.
Effects as exceptions
Are effects just weird functions? Kind of. But you can also use them as exceptions.
Modules
Modules span files. This one isn't runnable in the browser, but the CLI handles it fine.
// Exports.tlk public let a = "we can export this string" // Main.tlk import { a } from ./Exports.tlk print(a)
A rough little HTTP server
There's already some rough HTTP stuff. Don't look at it too hard.
let http = HTTP.Server() http.get("/", func() { "hello from talk" }) http.get("/health", func() { "ok" }) print("Listening on http://localhost:3000") http.run(3000)
How it worksa compiler in six polite movements
Name::Raw(string) with Name::Resolved(symbol, string).In · source
let a = 1 + 2
Out · Lex
Let@0..3 Ident("a")@4..5 Eq@6..7 Int(1)@8..9
Plus@10..11 Int(2)@12..13 Eof@13..13
What's missinga short and honest list
Real I/O
You can print to stdout. That is, uh, literally it. Seems like something one might want more of.
Standard library
No hashmaps, no sort, no JSON. There also isn't an un-standard library, so I'm not sure why I put that in quotes.
Explicit mutation
Everything is mutable right now. It's chaos. The sky is crumbling. I have a Looney Tunes umbrella.
Mutable arrays
No push yet. If you are a functional programmer with a cool leather jacket, please enjoy this page.
Concurrency
But concurrency isn't parallelism! So parallelism? Also no.
Visibility modifiers
Everything public, all the time, baby. public exists as a keyword, mostly for vibes.
Real docs
You are looking at it. Kind of. (Hi.)
LSP & tooling
Syntax highlighting in a browser is fun. Real tooling is hard. Someday.
A better name
It's fine. I think it's fine. I'll stop saying it now.
Install & getting startedthree minutes, tops
- Install the binary. Homebrew on macOS, a prebuilt binary for Linux, or build from source with
cargo install --path . - Run the REPL.
talk repl. It's low-key my favorite part. - Read the tour above. Most of what the language does is covered in under five minutes.
- Open the docs for reference: language spec, pipeline internals, effects, and (eventually) a standard library.
- File a bug when something breaks. It will. That's how learning happens.