Per AutoModerator's request I hereby confirm that the whole purpose of this project is to be LLM-generated.
I've been building ARO, a declarative programming language where every statement follows a single grammatical pattern: Action the Result preposition the Object.
The idea is that business features should be readable by anyone — developers, PMs, compliance officers — without translation. Here's a complete REST API:
(listUsers: User API) {
Retrieve the <users> from the <user-repository>.
Return an <OK: status> with <users>.
}
(createUser: User API) {
Extract the <data> from the <request: body>.
Validate the <data> against the <user: schema>.
Create the <user> with <data>.
Store the <user> into the <user-repository>.
Emit a <UserCreated: event> with <user>.
Return a <Created: status> with <user>.
}
(Send Welcome Email: UserCreated Handler) {
Extract the <user> from the <event: user>.
Send the <welcome-email> to the <user: email>.
Return an <OK: status> for the <notification>.
}
That's not pseudocode. It compiles and runs.
HTTP routes come from an openapi.yaml contract — the feature set name matches the operationId. No routing DSL, no decorators. No OpenAPI file, no server. The event handler at the bottom fires automatically whenever a UserCreated event is emitted. You don't call it — you just add it.
What makes it interesting
You only write the happy path. There are no try/catch blocks, no null checks, no error codes. When Retrieve the <user> from the <user-repository> where id = <id> fails, the error message IS that statement. The code literally becomes its own error message. Sounds crazy, works surprisingly well for internal tools and prototyping.
Contract-first APIs. Your OpenAPI spec is the single source of truth for routing. Drop it next to your .aro files and the server starts. This forces you to design your API before implementing it, which is usually what you want.
Event-driven architecture is built in. Emit an event, and any feature set whose business activity matches EventName Handler picks it up. Adding a new side-effect to user creation is just adding a new feature set file — you never touch existing code.
Plugins in any language. Write extensions in Swift, Rust, C, or Python. They all compile to a shared C ABI. Works in both interpreter mode (aro run) and compiled binaries (aro build). For example Lowbar (wip).
Native compilation. aro build ./MyApp produces a standalone binary through LLVM. No runtime needed on the target machine.
Cross-platform. macOS, Linux, and (someday) Windows. Built-in HTTP server, file system operations with directory watching, and TCP sockets — no external dependencies.
100+ working examples covering HTTP APIs, file watchers, sockets, data pipelines, state machines, WebSocket chat, and more.
Honest weaknesses
Not production-ready. The error philosophy that makes the language elegant also makes it insecure. You can't catch specific errors or implement fallback logic. Great for prototypes, internal tools, build systems and learning — not for your payment system.
The grammar is restrictive by design. Everything must be Action Result Preposition Object. Sometimes that makes things verbose or awkward. You won't replace Python with this. The constraint is the feature, but it's also the limitation.
No real type system yet. Type checking is in progress. For now it's dynamically typed at runtime, which means some errors that should be caught at compile time aren't.
Tooling is minimal. No step-debugger, yet.
Small community. There's no ecosystem of libraries, no Stack Overflow answers, no tutorials beyond the docs, the books and the examples in the org-repo.
Why it exists
I'll be honest: I wanted to see what happens when you let AI help you tackle a domain you're not fully confident in — language design, parsers, compiler theory. The AI doesn't stop you from doing daft things, but the process taught me more about lexers, ASTs, and code generation than I ever expected. It also gave me a deeper knowledge about agentic coding and training a local model. It started as a learning experiment and grew into something with native compilation, multi-language plugins, and a coherent design philosophy. Sometimes the best education comes from poking at something you probably shouldn't, with tools that don't know any better.
Books
- Essential Primer A concise introduction to ARO for developers who want to get up to speed quickly
- The Language Guide Comprehensive guide to ARO: from mental model to native compilation
- ARO By Example Build a real web scraper from scratch: project setup through Docker deployment
- The Plugin Guide Write plugins in Swift, Rust, C, C++, or Python: architecture, manifests, testing, and publishing
- Construction Studies Deep dive into the compiler internals: lexer, parser, AST, semantic analysis, and LLVM codegen
Try it, break it, tell me what's wrong
brew tap arolang/aro && brew install aro
aro run ./Examples/HelloWorld
Binaries for macOS and Linux are on the releases page. Requires Swift 6.2 if building from source.
I'm actively developing this and would love feedback — especially the kind that comes as GitHub issues. Found a confusing error message? Missing a built-in action? Think the scoping rules are wrong? Something that just doesn't make sense? That's exactly what I want to hear.
Website: https://arolang.github.io/aro/
Open an issue: https://github.com/arolang/aro/issues
Repo: https://github.com/arolang/aro
Docs & Language Guide (PDF): https://github.com/arolang/aro/releases/latest/download/ARO-Language-Guide.pdf
Mastodon: @aro@uitsmijter.io
Top comments (0)