RSS Amplifier

Vadym Tyemirov · May 21, 2026

Why AI Agents Need Their Own Programming Language

0
Sign in to vote or save

Vadym Tyemirov · Vadym Tyemirov

The software engineering industry is quietly crossing a historic threshold.

For decades, programming language design has been optimized for human cognitive limits. We developed strict static typing, garbage collection, and expressive syntax sugar to help human brains organize logic, manage memory, and prevent bugs.

Today, however, the primary author and executor of code is increasingly an AI agent.

Yet, we are still forcing these agents to write and run code in environments designed for human developers.

When we ask an AI agent to automate a file-processing pipeline or run an HTTP workflow, we typically hand it a Python interpreter or a Bash terminal. These languages are powerful because they are dynamic, implicit, and offer maximum freedom. But when given to an autonomous agent, this flexibility becomes a massive reliability and security risk:

  • Hidden execution paths: Dynamic imports, runtime exceptions, and hidden side effects make it impossible to statically verify what a script will do before it runs.

  • Borrow-checker deadlock: If we force agents to write safer languages like Rust, they easily get trapped in infinite compiler error correction loops.

  • Concurrency failures: Writing locks, threads, and async code is a notorious source of hallucinated logic and race conditions for models.

If we want to build a stable, secure ecosystem of autonomous agents, we need to stop thinking of programming languages as interfaces for human typing. We need to think of them as execution contracts between an AI planner, a verifier, and a sandboxed runtime.

This is the thesis behind Lo.

In current agent architectures, developers often select languages like Go for model execution. The reasoning is pragmatic: Go is a syntactically tiny language. With only 25 keywords, the entire grammar is small enough to fit comfortably within a model’s weights and context window. This minimizes generation friction and yields a surprisingly efficient token economy. Go is expressive and versatile, yet simple.

But if syntactic simplicity is the ultimate goal, why not have agents generate Assembly?

Assembly is even simpler; its vocabulary of instructions is minuscule. Yet, Assembly is a terrible language for AI agents. Because it lacks high-level abstractions, doing anything useful requires hundreds of lines of boilerplate. The state-space of potential logical errors explodes, and the token economy is destroyed.

The ideal programming language for an AI agent must therefore sit in a very specific sweet spot: syntactically minimalist, yet semantically expressive.

Minimalist syntax: Reduces context window overhead and generation friction.

Expressive semantics: Allows the model to describe complex workflows in very few tokens.

Furthermore, we must re-evaluate what “clean code” means for a non-human author. Humans dislike verbosity because of physical typing limits and visual clutter. But for an AI agent, verbosity is synonymous with explicitness—and explicitness is safety.

A verbose, explicit syntax functions as a cognitive scaffold for LLMs. When an agent is forced to explicitly write out constructors (e.g., Int.new(200) instead of 200) and declare boundary handlers, it anchors the model’s attention mechanism to the strict constraints of the environment. This feeds a self-reinforcing thinking loop: as the model generates the explicit types and boundaries, it reinforces its own execution path, keeping the next generated tokens firmly aligned with the code’s invariants.

This is where Lo fits. The design is informed by years of scaling data pipelines, recommendation systems, and trading engines at companies like Shopify, BlackRock, and Morgan Stanley. In those environments, the most stable, auditable codebases are declarative dataflow graphs.

Lo takes this structural efficiency and wraps it in a tiny, agent-optimized grammar.

Lo is a typed, declarative, graph-first execution plan language. It does not replace general-purpose languages. Instead, it serves as a restricted execution contract:

  1. The Planner (AI): Proposes a workflow by generating a Lo program.

  2. The Verifier (Host/Human): Statically inspects the program before execution to see exactly what files will be read, what networks will be hit, and what effects will be committed.

  3. The Runtime: Executes the approved action graph in a sandboxed environment.

To maintain its syntactic sweet spot, Lo enforces a strict set of language disciplines:

In Lo, calling a constructor like File.write(...) or HTTP.Server.new(...) is a pure expression. It simply returns a description of the target action (a committable target). Nothing is actually written, and no server is started, until the target is explicitly triggered by the commit keyword.

# Pure construction (safe to dry-run and inspect)
target_effect = Match.new(status_code,
    Int.new(200): File.append(success_log, request_data),
    _: File.append(error_log, request_data)
)
# Explicit activation (the only place a side effect can happen)
commit target_effect

Because Lo separates construction from activation and uses a graph-first architecture, a verifier can inspect the program before a single instruction runs.

Running a command like lo inspect workflow.lo yields a structured report:

This allows the host platform to enforce fine-grained access control before letting the agent execute a plan.

Lo v0.3 has no anonymous functions, lambdas, classes, or statement loops. All data transformations are represented as pipelines using the pipe operator (|>) passing through named flows (e.g., List.map(numbers, Double)). This keeps the compiler simple, prevents variable scoping hallucinations, and makes it incredibly easy for an LLM to generate syntactically correct code on the first try.

Lo has no hidden exceptions. There is no try/catch or throw. If a function or adapter operation can fail, it must return a fallible type T! (which represents success T or a nominal Error value). The compiler forces error handling at boundary points (onError handlers) so that error bubbling and diagnostic trace collection are 100% deterministic.

Lo is currently in its v0.3 language proposal phase. The specification is written and stable, and the repository is public on GitHub.

Our next immediate milestones are:

  1. The Verifier MVP: A compiler front-end that can parse .lo files, validate the grammar, and perform static type-checking on our conformance test suite.

  2. The Inspector: A tool to extract and print a full permission and side-effect report from any Lo program.

  3. The Runtime Interpreter: A sandboxed execution environment targeting basic file processing and HTTP workflows.

This is an early, spec-first project. We wanted to get the design details right before writing the compiler. Now that the spec is ready and the repository is public, we are opening up for contributors.

If you are interested in:

  • Compiler front-ends (parser, AST, type-checkers)

  • Sandboxing and runtime virtualization

  • Language design for AI systems

  • Critique of our core semantics or standard library

Check out the public repository: github.com/tyemirov/Lo

Read through specification.md, take a look at the open issues in ISSUES.md, or reach out. Let’s build the execution layer for the next generation of software agents.

No posts

Read the original on vadymtyemirov1.substack.com

Comments

Nothing yet. Say the first thing.

    Sign in to join the conversation.