Agents, not chatbots
tool, agent, and mcp are
keywords. JSON Schema, capability scoping, and retry policy are
generated from the type system, not hand-written.
Go runtime · one binary · readable syntax.
Tools, agents, MCP servers, supervised actors and ETL pipelines as first-class language constructs, not libraries bolted on after the fact.
fn main() {
println("hello, yoru")
}// JSON Schema + capability check generated automatically
tool SearchOrders {
description: "Search orders by customer email"
input {
email: Option[String] @doc("Customer email")
limit: Int = 10
}
output: [OrderSummary]
effect: [DB]
capability: .read_only
fn run(self, i: SearchOrders.Input) -> [OrderSummary] effect [DB] {
DB.query("SELECT * FROM orders WHERE email = $1", [i.email])
}
}agent OrderAgent {
model: "claude-sonnet-4-6"
system: "You are a helpful order management assistant."
tools: [SearchOrders, CancelOrder, RefundOrder]
config { max_turns: 10, budget_tokens: 8000 }
}
let agent_ref = spawn OrderAgent()
let reply = agent_ref.chat("Refund #ORD-4821 for user@example.com")pipeline HL7ToFHIR {
source: Kafka.stream(topic: "hl7-ingest")
|> transform: ValidateHL7.run partition: 4
|> transform: HL7Parser.parse partition: 4
|> transform: FHIRMapper.convert partition: 4
|> sink: FHIRStore.upsert
on_error: .dead_letter_queue(topic: "hl7-dlq", max_retries: 3)
checkpoint: .every(500.records)
}actor Counter {
state count: Int = 0
receive Increment { self.count += 1 }
receive GetCount -> Int { self.count }
}
// Supervisor restarts crashed children automatically
let sup = Supervisor.new(
strategy: .one_for_one,
children: [Child.spec(Counter, restart: .permanent)]
)service UserAPI {
prefix: "/v1/users"
middleware: [AuthMiddleware, RateLimiter(rps: 1000)]
GET "/{id}" -> User effect [DB]
fn get(req: Request, id: String) -> Result[User, NotFound] {
DB.find(User, id) ?? Err(NotFound)
}
}Today's services are concurrent, distributed, heterogeneous, and agentic. Every mainstream language addresses at most two. Yoru is built from the ground up for all four.
tool, agent, and mcp are
keywords. JSON Schema, capability scoping, and retry policy are
generated from the type system, not hand-written.
Algebraic effects unify async, errors, state and I/O. No coloured
functions. Swap a real LLM for a deterministic stub in tests by
changing one handle block.
ETL gets first-class syntax: typed sources and sinks, declarative
partition:, dead-letter queues, back-pressure and
checkpoints, all enforced at compile time.
Goroutine-per-actor with the Isolated Turn Principle. Supervision trees (OTP-inspired) decide whether to restart, escalate, or stop. Failures are events, not crashes.
Borrowed from Pony: iso, val, ref,
tag. The compiler proves data-race freedom statically.
No borrow checker, no GIL.
Services, MCP servers, pipelines and CLIs all compile (today interpret) from the same source. No proto files, no codegen step, no separate framework runtime.
tool, agent, effect and
pipeline are keywords, not annotations, not decorators,
not a framework. The compiler understands what they mean.
toolInputs, outputs, effects and capabilities live in the signature. JSON Schema is generated, not hand-written.
agentModel, system prompt, available tools, max turns and token budgets declared once. Re-spawnable as actors.
effectAsync, error, state and I/O share one mechanism. Swap a real LLM for a stub by changing a handle block.
pipelineSources, sinks, partitions, back-pressure, checkpoints and dead-letter queues, all enforced by the type system.
From println to a production service, you stay in the
same file. No proto, no codegen, no separate framework runtime.
The smallest possible Yoru file. fn main() and a
call to println. Run it directly with
yoru run hello.yr.
fn main() {
println("hello")
}
Give the same function a typed signature. Inputs, outputs and effects are now part of the type. JSON Schema gets generated from the source, not hand-written.
tool Echo {
input { msg: String }
output: String
fn run(self, i) {
i.msg
}
}
Wrap one or more tools in an agent. Model, prompt, budget and tool list are declared in one place. The compiler enforces that every tool is well-typed.
agent Helper {
model: "claude-sonnet-4-6"
system: "Reply briefly."
tools: [Echo]
config { max_turns: 6 }
}
Stream input through the agent. Sources, transforms and sinks are first-class. Back-pressure, partitioning and dead-letter queues are properties of the type, not the framework.
pipeline Greet {
source: Names.stream()
|> transform: Helper.chat
|> sink: Stdout
}
Expose the same pipeline over HTTP. Middleware, routing and effects compose with everything above. Still one file. Still no codegen step.
service GreetAPI {
prefix: "/v1"
middleware: [AuthMiddleware]
POST "/greet" -> String
}
Nothing here is new. The novelty is the composition: six well-studied ideas, lined up so they reinforce instead of fight each other. Each one carries a citation in the spec.
Isolated-Turn actors, M:N fibers, supervision trees. Failures are events, not crashes. (De Koster et al., AGERE 2016)
Algebraic effects unify async, errors, state and I/O. Strictly more expressive than async/await. (Leijen, 2016; Dolan et al., 2017)
Six reference capabilities (iso, val, ref, tag…). Data-race freedom proven at compile time. (Clebsch & Drossopoulou, OOPSLA 2013)
The three parallelism axes (data, pipeline, component) encoded directly in syntax. (Vassiliadis et al., DaWaK 2007)
Typed tool calls, capability scoping, auditable traces. The schema-hallucination bug class disappears. (ToolLLM, ICLR 2024)
Capability-secure objects, composition over inheritance, contracts by protocol. (Flageol et al., 2023)
Three doors. Pick the one that matches how you like to learn. Each one tells you how long it should take.
Build the Go binary, drop it on your PATH, run your first .yr file. Hello world to working REPL.
A guided tour through bindings, objects, effects, actors, pipelines, and agents. One concept per page.
referenceFull design rationale, comparisons, and the research that backs every decision. Read at your own pace.
Five dimensions that decide whether agentic systems are a language feature or a framework problem.
| Feature | Go | Python | Elixir | Rust | Yoru |
|---|---|---|---|---|---|
| Native tool / agent / MCP | ✗ | ✗ | ✗ | ✗ | ✓ |
| Algebraic effects | ✗ | ✗ | ✗ | ✗ | ✓ |
| First-class pipelines | ~ | ✗ | ✗ | ✗ | ✓ |
| Actors + supervision trees | ✗ | ✗ | ✓ | ✗ | ✓ |
| Reference capabilities | ✗ | ✗ | ✗ | ~ | ✓ |
✓ full · ~ partial / library-level · ✗ not available.
Long-lived services. Orchestration. Agents. Data flows. If your day involves one or more of these, Yoru exists to remove seams from your stack, not add another runtime to your dependency tree.