A small core lang with some extra fluff
Yap is a programming language. It's mine. I built it. Why? Because I got annoyed with everything else. So instead of doing something productive, I went peak software bro and made my own.
There's no grand vision here — just a bunch of features I like, without the stuff that sucks, keeping me from throwing my laptop out a window.
A dependently typed language with first-class, structural types, implicits, and zero runtime assumptions. The idea is to keep the core minimal, let types do their thing (and then nuke them!), and make everything customizable.
If you don’t like how something works, change it — preferably without rewriting the compiler.
It’s still early days, so expect broken things, missing features, a nonsensical mess and half-baked ideas. But hey, it already supports:
- Type system goodies
- Structural typing - so you don’t have to fight a nominal type system for no reason
- Dependent functions, Dependent Records, Variants, Recursive types
- Refinement types - because Naturals, Ranges, non-empty lists and such exist even if we pretend they don't
- Type inference - Momma always told me I had a short attention span
- Structural typing - so you don’t have to fight a nominal type system for no reason
- Implicits - so you don’t have to pass a million arguments manually
- Delimited continuations - for when you make an oopsie and need control flow to pretend it was intended
- Evaluator - It does things like
1 + 2and(\x -> x + 1) 2 - Foreign function interface - Just an excuse to write JS instead of actual yap code
- Module system - because you have a file system
- JS codegen - sue me (also, it's broken)
Check out the examples folder to get a more in depth overview of what is currently available. But for the TLDR crowd:
let Factorial: Type
= { compute: Num -> Num };
let fact: Factorial
= { compute: \n -> match n
| 0 -> 1
| _ -> n * (:compute (n - 1)) // :compute refers to the 'compute' field itself
};
let result = fact.compute 5; // 120Yes, this is actual, working syntax! Ensue bikeshedding.
Yap isn’t quite "usable" yet unless you enjoy debugging the compiler. If you're a masochist though, you'll need some groundwork:
- Install
z3- On macOS, use
brew install z3like a normal person
- On macOS, use
- Clone the repo
- Install
node- Easiest via
nvm. Eithernvm useornvm install
- Easiest via
- Install
pnpm pnpm installpnpm nearleybuilds the parser
That wasn't so hard! Now chop chop, fun part is coming
You know the drill:
pnpm run yap repl- Write some broken code
- sacrifice a goat
- pray it works
- get mad when it breaks
- Complain
The examples/README has a fairly good overview of what's currently supported, although I make no claims that anything outside of those carefully curated examples will work.
Yap isn’t trying to revolutionize programming. It will just do things in a way that makes sense to me:
- Minimal core – Small enough that even I can remember how it works.
- Sugar, spice and everything nice - This isn't an academic toy; it should actually be nice to use.
- Turing complete types - I solemnly swear you can nuke the bastards at runtime.
- No platform assumptions – The compiler should let you generate whatever garbage output you want. No judging.
- You’re in control – Defaults exist, but if you don’t like them, override them. No gatekeeping.
- Multi paradigm - let the flame wars begin
Whomever fancies it. Yap isn’t aimed at “frontend people” or “systems people” or whatever other tribe the internet has invented this week.
Most software is just trying to ship a product so it's for anyone who just wants normal, product-driven code without getting bogged down in platform-specific constraints.
See more in the FAQ
In case it wasn't obviours, this here is a work in progress (read: broken, just like my last relationship), so here's a list of things that still need to be done:
- Delimited continuations
- It already supports basic shift/reset and type inference/checking
- Resource usage semantics
- For those pesky mutations, references and IO handles
- Variadic arguments, named arguments... (Yes, I like arguing)
- Infix function application (less parens = better)
- Better syntax sugar for common patterns (shorthand matches, destructuring, backcalls, pipes, etc.)
whereclauses (because who likes deep nesting?)- Data traversal (nested updates, SQL-like goodies)
- Reflection (for runtime type-driven pattern matching)
- Recursive infinite data (Coinduction)
- Delimited continuations
- Effect system on top
- Lowered IR
- For annoying things like type erasure, monomorphization, FBIP optimizations, customizable data types, fusion, etc
- Syntax highlighting (so we can pretend it's a real language)
- LSP support (because writing a language without an LSP in 2025 is just rude)
- A debugger (because I am dumb)
- A REPL (technically it exists...)
- To Any or not to Any – Do I really want to introduce the TypeScript plague into my pristine little ecosystem?
- A gradual type system is a
Yay!in my book, but also a can of worms
- A gradual type system is a
- Effects - Simultaneously the bane of all devs, but also the thing that keeps the world running
- How to best allow for ergonomic effects?
- I should be able to log stuff without having to change a bazillion files
- Exclusive effects? Not like an exclusive/VIP club, you pleb! As in: allow all effects except for
X.
Yap has some… let’s call them character-building aspects.
- The
REPL- More like a suggestion than a real tool. - The
FFI- Functional in the same way a car with three wheels is technically functional. - The module system - Yeah, it exists.
- Testing - because I keep breaking everything every other day
- Comments - I forgot, ok?
- Tech debt 💀
- Well, lowering isn't a thing yet (but hey, at least it’s not not a thing, right?)
- The generator-monad-look-alike stuff... I wanted to be creative, k?
Improvements are coming, but for now, just squint and pretend everything is fine.
If you want to contribute, that’s cool! Open an issue, start a discussion, or throw a PR my way. I genuinely enjoy discussing ideas.
I also suck at communication, so feel free to continue to pester me with notifications while I continue to ignore them. Such is life.
“Yap” stands for “Yet Another Problem”. Because, let’s be real, that’s exactly what this is. Another problem I’ve decided to create for myself instead of just, you know, using something that works.
Could’ve called it “Just Another Language,” but then it wouldn’t have been as honest or as snarky. So here we are.
I don't know, you're better off asking a CS PhD Nobel Laureate logician.
Maybe it’s a terrible, and terribly flawed, idea. Maybe it’s genius. Maybe it’s just a complete dumpster fire wrapped in my own personal code therapy session.
Could it ever be fully usable, safe, sound, fast, feature-rich and whatever else your shiny programming language needs to be? Probably not. Maybe it’ll never turn into something functional. But do I like it? Yeah, I do. I think it’s cool. If you do too, cool. If you don’t, cool. Either way, it's here.
And it works... kinda.