Yoru v0.1 · Phase 0
Phase 0 · 716 tests passing · Tree-walking interpreter

A language for agentic systems that still reads like software.

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.

v0.1.0 · Phase 0 | Go 1.22 runtime | MIT licensed
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)
  }
}

Backend languages were built for a different workload.

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.

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.

Effects, not async/await

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.

Pipelines as primitives

ETL gets first-class syntax: typed sources and sinks, declarative partition:, dead-letter queues, back-pressure and checkpoints, all enforced at compile time.

Actors & supervision

Goroutine-per-actor with the Isolated Turn Principle. Supervision trees (OTP-inspired) decide whether to restart, escalate, or stop. Failures are events, not crashes.

Reference capabilities

Borrowed from Pony: iso, val, ref, tag. The compiler proves data-race freedom statically. No borrow checker, no GIL.

One binary, one language

Services, MCP servers, pipelines and CLIs all compile (today interpret) from the same source. No proto files, no codegen step, no separate framework runtime.


Not a framework stack. A language shape.

tool, agent, effect and pipeline are keywords, not annotations, not decorators, not a framework. The compiler understands what they mean.

tool

Typed actions

Inputs, outputs, effects and capabilities live in the signature. JSON Schema is generated, not hand-written.

agent

Bounded autonomy

Model, system prompt, available tools, max turns and token budgets declared once. Re-spawnable as actors.

effect

Honest side-effects

Async, error, state and I/O share one mechanism. Swap a real LLM for a stub by changing a handle block.

pipeline

Typed ETL by syntax

Sources, sinks, partitions, back-pressure, checkpoints and dead-letter queues, all enforced by the type system.


One language, every step.

From println to a production service, you stay in the same file. No proto, no codegen, no separate framework runtime.

  1. 01

    Hello

    The smallest possible Yoru file. fn main() and a call to println. Run it directly with yoru run hello.yr.

    fn main() {
      println("hello")
    }
  2. 02

    Tool

    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
      }
    }
  3. 03

    Agent

    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 }
    }
  4. 04

    Pipeline

    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
    }
  5. 05

    Service

    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
    }

Yoru borrows what already worked.

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.

from

BEAM (Erlang / Elixir)

Isolated-Turn actors, M:N fibers, supervision trees. Failures are events, not crashes. (De Koster et al., AGERE 2016)

from

Koka, Eff, OCaml 5

Algebraic effects unify async, errors, state and I/O. Strictly more expressive than async/await. (Leijen, 2016; Dolan et al., 2017)

from

Pony

Six reference capabilities (iso, val, ref, tag…). Data-race freedom proven at compile time. (Clebsch & Drossopoulou, OOPSLA 2013)

from

Spark, Dataflow, Beam

The three parallelism axes (data, pipeline, component) encoded directly in syntax. (Vassiliadis et al., DaWaK 2007)

from

ToolLLM & MCP

Typed tool calls, capability scoping, auditable traces. The schema-hallucination bug class disappears. (ToolLLM, ICLR 2024)

from

Behavioural object research

Capability-secure objects, composition over inheritance, contracts by protocol. (Flageol et al., 2023)


Start with Yoru

Three doors. Pick the one that matches how you like to learn. Each one tells you how long it should take.


How Yoru compares.

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.


For engineers building long-lived systems.

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.