explainx.ai0k
TrendingNewsPathwaysSkills
Pricing
explainx.ai

Upskill in AI — 16 free pathways, live workshops & bootcamps, and 50+ courses from practitioners. Plus the skills, tools, and MCP servers to practice on.

follow us

follow on google

Add explainx.ai as a preferred source

corporate training

support@explainx.ai

get started

Find your pathTake Free Evaluation

community

Join the community

learn

mind: share how you thinkpathways — start freeworkshopsbootcampscoursescompare Explainxcertificationsmock testsexplainx universitycorporate traininglearn skills & mcp

discover

skillsmcp serversexplainx mcptoolsmdx readeragentsllmsdesignsdictionarypeopleagi trackerfelony benchranks

company

aboutvisionmissionteaminstructorsteach on explainxpartnershipscommunityhackathonscareers

content

daily AI newsstate of AI — live resultsblogreleasespromptsgeneratorsresource libraryfor LLMsexplainx.ai kids

solutions

all solutionsdeveloper upskillingmarketing upskillingproduct manager upskillingleadership upskilling

newsletter · weekly

Get AI news, tools, and insights in your inbox.

supportcontactprivacytermsdata rightshow we create contentsubmission guidelines

© 2026 AISOLO Technologies Pvt Ltd

explainx.ai

On this page

  • The short version
  • What programming languages should expose to an agent
  • What still glues a language community
  • Syntax sugar is the wrong optimization
  • Agents will not replace compilers
  • Human tooling and agent tooling
  • Guarantees beat ergonomics when the agent writes the types
  • Ask the program, do not hop file and line
  • Let the agent query the runtime
  • What people are asking
  • Prompts to paste into a coding agent today
  • Honest limitations
  • What this changes in the repo you have
  • Related on explainx.ai
← Back to blog

explainx / blog

Programming Languages in the AI Era: What to Expose to Agents

Programming Languages, Coding Agents, Developer Tools, Language Tooling, Opinion

José Valim on programming languages for coding agents: expose types, a queryable program database, and runtime state.

Sep 27, 2026·21 min read·Yash Thakker
add explainx.ai
go deep
Programming Languages in the AI Era: What to Expose to Agents

If coding agents are users of your programming languages and tools, stop spending the next year on syntax sugar. Start exposing three things: explicit types and invariants, a queryable program database, and runtime state the agent can inspect without a human debugger. That is what changes what you build this month.

José Valim, who created Elixir and works at Dashbit, published that argument on September 24, 2026 as Evolving programming languages in the AI era. The essay has two parts, reflections and agentic tooling. The Hacker News thread was small, about 18 points, and the useful comments were specific. This post is explainx.ai's read for people who already ship with coding agents: what to expose, what to leave alone, and which prompts you can paste before a program database exists.

The same shift is already visible in how teams run a coding-agent loop. The harness, the checks, and the facts the agent can look up decide the quality of the diff. A prettier operator does not.

The short version

table · 2 cols
QuestionAnswer
Is syntax the thing to optimize?No. Optional chaining and similar sugar help humans type. Agents treat syntax as tokens in and tokens out. A language "for agents" that only changes syntax is fitting today's context window.
Will agents replace compilers?No. You still want one architecture-independent representation, lowered per machine. No single model covers systems code, proofs, fault-tolerant concurrency, queries, and hardware.
Should we kill LSPs?Keep them for editors. Agents are bad at file, line, and column. Give them a database they can ask by symbol: where is this defined, who calls it, where can this value become null.
What should a language expose to an agent?Explicit types and invariants, a queryable program database, and runtime state. These help even when agents write about 20 percent of the code.
Should we rewrite in Elixir?No. The Erlang VM already inspects processes and supervisors, so the runtime advice is easy to see there. Port the idea, not the stack.
Why not program on an AST humans cannot read?Human review is the bottleneck. A notation reviewers cannot audit does not shorten the merge.

What programming languages should expose to an agent

Valim's reflections ask what happens to communities, ergonomics, and compilers if agents write most code. The tooling half is the part you can act on without waiting for that future. He is explicit that the tools help even if agents write only about a fifth of the code. You do not need a new language. You need the facts an agent currently has to guess.

Three surfaces, in the order a coding agent actually fails:

  1. Explicit types and invariants. Full type inference is a convenience for people who dislike writing signatures. Agents can write the signatures, and they can write proofs. Inference-friendly languages are often a subset of what a checker could express, so optimizing for inference can shrink both the programs you can write and the properties you can state.
  2. A queryable program database. Symbols, references, call graphs, types, and data-flow, stored so an agent can ask a question. Language servers already compute much of this and then hide it behind "go to definition" at a cursor position.
  3. Runtime state. Breakpoint stepping is a human interface. An agent can instrument, trace, and correlate faster, and it may be the thing watching production. Expose processes, queues, sockets, and failure policy as something it can query, with a permission boundary.

A coding agent surrounded by explicit control surfaces, standing in for the types, program queries, and runtime state a language should expose

Weekly digest3.5k readers

Catch up on AI

Curated AI updates on agents, skills, and MCP — delivered to your inbox. Unsubscribe anytime.

That list is also a filter for language-roadmap arguments. If the next proposal is another piece of sugar, ask which of the three surfaces it feeds. If the answer is none, it can wait.

What still glues a language community

Valim starts from a plain observation. Communities form around shared sensibilities. Python's is that there should be one obvious way. Ruby's is programmer happiness. Lisp's is that you can reshape the language. If agents write most of the code, the shared act of writing is thinner. The open question is what replaces it as the thing people belong to. He does not pretend to have the replacement. He asks whether belonging is worth preserving, and what the next glue might be.

Ecosystems are the concrete version of that question. Web frameworks, tensor libraries, data pipelines, and GUI toolkits exist because hard problems were expensive, so people pooled the work. Agents cut that cost in a specific way: known algorithms, paper implementations, and ports of code that already exists. Smaller languages can catch up on those jobs faster than they could when every port was a multi-year volunteer project.

The opposite force is just as real. If a library is cheap, a team may skip the shared one and ask an agent for a private fork that matches today's schema. Agents can shrink the cost of an ecosystem and, at the same time, weaken the reason an ecosystem forms. That tension is the part worth sitting with. "Agents will write our frameworks for us" and "agents will fragment our frameworks" can both be true.

A comment on the Hacker News thread pushed the first force further: AI undercuts language-specific ecosystems and strengthens language-agnostic ones, because you can port the ecosystem. A reply is the correction explainx.ai would keep. Porting is a project with a boundary and a test suite, so the agent can change something and see what broke. Third-party packages are the uneven part. They carry implicit behavior, thin tests, and version pins. "Port the ecosystem" hides that middle.

The language-agnostic shape people already ship looks like multi-language SDKs: agent frameworks with a binding per language, Dagger-style SDKs, and Kubernetes APIs that every language talks to through a client. The shared object is a protocol. Each language binding is a port. The port stays honest only while each binding has tests the agent can run. A generated client with no checks is how you get five slightly different bugs and a false sense that the ecosystem moved with you.

Syntax sugar is the wrong optimization

A large share of language evolution is ergonomics. The last decade added optional chaining in language after language because a chain of null checks is miserable to type and easy to get wrong by hand. Agents are not bored by boilerplate. The operator still matters when a human is reading a hot path. It is a weak reason to spend a language's next year.

Token efficiency is the usual rebuttal: shorter syntax means fewer tokens, so the agent is cheaper and fits more code in context. Valim treats that as a tail criterion. Models get cheaper, and context windows get larger. A new language marketed as "for agents" that mostly changes syntax is optimizing the context limit you have this quarter.

He has used agents on HTML, CSS, JavaScript, Elixir, Rust, and Lean. The syntax gaps that feel enormous to a human author matter less to the model. From the model's side it is tokens in and tokens out. That matches what teams see when the same harness drives several languages: the failures cluster on missing facts and weak checks, not on whether the language has a terse null operator.

There is a human-review exception, and it matters. Sugar that makes a diff readable still earns its keep, because a person merges the change. The mistake is treating readability sugar as the agent interface. Readability is for the reviewer. Guarantees, queries, and runtime facts are for the agent.

Agents will not replace compilers

The follow-up question writes itself: if agents write the code, why keep the language? Let the agent emit assembly. Valim rejects that, for reasons that survive contact with a shipping product.

A desktop or server binary still has to run on more than one architecture. You do not want a separate hand-maintained assembly listing per chip. You want a representation that is independent of the machine, and a lowering step that knows the machine. That is a compiler and a higher-level language, even if no human was meant to type the higher-level form.

The second reason is that we do not have one computational model that covers the work. Systems languages, theorem provers, Erlang-style concurrency, query languages, and hardware-description languages encode different meanings and different promises. Expecting one low-level target to unify them throws away the reason those languages exist. The agent can target all of them. It cannot collapse them into one semantics without losing the guarantee you picked the language for.

So languages stay. The design question changes. If you stop optimizing the language for the human who types it, you optimize for what the agent, the compiler, and the reviewer can rely on. That is the bridge into the tooling half of the essay.

Human tooling and agent tooling

Most agent tooling so far automates what humans already do. Agents write the same tests, read the same logs, and call the same language server. Valim's sharper claim is that agents can do work humans skip because it is tedious, steep, or too large to hold in one head. The interface should match that, not a cursor.

table · 3 cols
SurfaceBuilt for a person at a cursorBuilt for an agent
SyntaxOptional chaining, inference, less typingExplicit types and invariants, even if they are verbose
NavigationLanguage server: file, line, column, go to definitionQuery: symbol, callers, data-flow, "where can this be null"
CheckingTests the author thought to writeCorrect-by-construction, static proofs, runtime enforcement, property tests, fuzzing
DebuggingBreakpoints, step, watch a localTraces, correlated events, a query over live processes and queues
LocalityJump between files you rememberStill required. Monkey-patches and implicit hooks stay hard to trace
ReviewThe diff has to be readableThe same constraint. An unreadable notation does not remove the reviewer

The left column does not go away. People still edit, and people still review. The right column is the work that is currently missing from most language roadmaps.

Guarantees beat ergonomics when the agent writes the types

Languages trade expressiveness, guarantees, and ergonomics. If an agent writes a large share of the program, ergonomics can give ground. The example Valim uses is inferring function signatures. Inference saves a human from typing what the compiler already knows. An agent does not need that saving. Written types give the compiler, the next agent, and the reviewer more to check.

There is a harder constraint under the convenience. Languages whose types can be fully inferred are generally a subset of languages whose types can be checked. Chasing inference can rule out type systems that say more. Agents have already written proofs in systems more demanding than a typical application language. Boris Cherny's Lean 4 and TLA+ pass over the Claude Agent SDK is one public data point: short prompts, a large pile of theorems, bugs in concurrency and state that tests are bad at catching. The cost of machine-checked proofs is a separate story, and it points the same direction. The limit is less "the model cannot write the annotation" and more "the language and the review process have to be able to use it."

Guarantees are not only static. Valim sorts them into four layers, and a language can mix them:

table · 3 cols
LayerWhat it promisesEveryday shape
Correct by constructionInvalid programs are hard to expressExhaustive matches, capability types, "this state cannot exist"
Statically establishedA checker proves a property before the program runsTypes, proofs, static analysis
Runtime-enforcedThe running system refuses a bad actionGarbage collection, process isolation, capability checks
Empirically validatedYou try to break itTests, property tests, fuzzing

Erlang and Elixir sit in the runtime-enforced row on purpose. Isolated processes and message passing give up some concurrent algorithms — not every lock-based design maps cleanly — and in return you get isolation and fault tolerance for the programs that fit. That trade is a product decision, not a syntax decision. Frameworks have to make the same kind of trade at their own layer. A web framework that lets any code reach into any other code's state is asking the agent to rediscover the boundary on every task.

One Hacker News reader described a concrete version of this bet, and it is evidence, not a stack to copy. They prototype games by embedding AssemblyScript in a Rust host specifically because agents write it: static types, the same language in native code and in the browser, a compiler that runs in the browser, and no external dependencies. They pair it with a state library that stops the model from tangling UI and state, which makes tests and replay straightforward. The interesting part is the pair of constraints: types the compiler checks, and state the test can see. That is Valim's "guarantees and inspectable state" point, showing up in a language he did not mention.

Ask the program, do not hop file and line

Language servers were built for editors. Their operations assume a document and a position: this file, this line, this column. Agents lose that position. They guess a path, guess a line, and then edit the wrong overload. Valim's experience building Tidewave was that a tool which answers "where is foo_bar documented?" or "where is BarBaz defined?" fits an agent better than a protocol that demands a precise source coordinate.

Language servers often already have the underlying facts: symbols, references, call graphs, types, and sometimes data-flow. The suggestion is to expose those facts as a database with a query language. SQLite, Datalog, or a small DSL all qualify. A human should not have to write SQL to find references. An agent will, because writing a query is the same kind of step as calling a tool. And it can compose questions an IDE would never ship as a button.

Two queries that are impractical as menu items and ordinary as agent requests:

sql
-- Public functions that eventually call charge_card
SELECT caller
FROM call_graph
WHERE callee = 'charge_card'
  AND caller_visibility = 'public';
sql
-- Paths where customer_id can become null before save_order
SELECT path
FROM data_flow
WHERE symbol = 'customer_id'
  AND can_be_null = 1
  AND reaches = 'save_order';

Most repositories do not have these tables. The examples are the shape of the tool, so you can tell a real answer from a file-and-line guess. The same database can back linters that refuse patterns you do not want an agent to introduce.

Locality still matters, and a database does not repeal it. Monkey-patching, implicit hooks, and dynamic rebinding let one file change the behavior of the whole system. Those edges stay hard to trace even when the call graph is queryable. If your language makes action-at-a-distance the normal way to extend behavior, the agent will miss it, and so will the query. That is an argument for fewer invisible hooks, which is also an argument a human reviewer would make.

Agent skills and DESIGN.md are the repo-level version of the same move: write the fact down in a form the agent can load, instead of hoping it infers taste from a pile of files. A program database is that move applied to the code itself. Skills tell the agent how you work. The database tells it what the program is.

Let the agent query the runtime

Debuggers are a human interface. You set a breakpoint, step a line, and look at a local. An agent can add instrumentation, collect a trace, and line that trace up with a failing request faster than a person can click. If agents write a large share of the code, they will also get asked to watch production. Logs and dashboards are a start. A queryable runtime is the matching interface.

Elixir's advantage here is the Erlang VM, and Valim is honest about standing on it. You can already inspect processes, sockets, applications, supervisors, ETS tables, and message queues. The gap he names is exposure: tools, a query language, or a sandbox, so an agent can look without becoming a new way to damage the system. Safe exposure is the product problem. The raw capability is older than coding agents.

Other stacks have pieces of this and rarely present them as one query surface. A supervisor tree, a service mesh, a tracing span, and a container restart policy are all runtime facts. Isolation boundaries for agents matter here twice. The program may use isolation as a guarantee, and the agent inspecting production needs its own boundary so a diagnostic query cannot become a write.

This is also why "rewrite it in Elixir" is the wrong takeaway. The advice travels. If your runtime can list workers, restart policies, queue depth, and open sockets, put that behind a tool the agent can call. If it cannot, say so in the tool result. A confident guess about a supervisor that does not exist is worse than a gap.

What people are asking

The essay is Valim's opinion. He thanks Quinn Wilton, Chris McCord, Ryan Lopopolo, Chad Fowler, Rob Knight, Danila Poyarkov, and conversations at ElixirConf. He notes that AI was used for style and grammar, not as a silent co-author of the claims. The Hacker News thread did not crown a winner. It stress-tested three ideas that show up the moment you try to use the essay on a real repo.

"I already picked a language because agents write it." The AssemblyScript-inside-Rust comment is the cleanest example. The choice was not "agents like this syntax." It was static types, one language on two targets, a compiler with no package to install, and a state model that keeps UI and state from collapsing into each other. That is a guarantees story. If your agent-facing language pitch is "fewer tokens per function," you are answering a different question than the person who already switched.

"Just port the ecosystem." The thread's pushback is the one to keep. An agent iterates when the project is self-contained and the tests fail loudly. A language community's third-party ecosystem is not that project. It is hundreds of packages, each with its own implied contracts. Multi-language SDKs (agent frameworks, Dagger-style SDKs, Kubernetes clients) are what a language-agnostic ecosystem actually looks like in practice. They work when the protocol is the shared artifact and each binding is tested. They fail when someone generates the bindings and calls the job done.

"Why not program on an AST, or any representation humans find hard?" The reply in the thread matches the essay. Human review is the bottleneck. Optimizing a notation reviewers cannot read does not move the merge. Valim's version is the constructive half: keep the languages, change the optimization target. Guarantees, queryable program facts, and runtime inspection are legible to a reviewer in a way a private bytecode is not. You can still ask an agent to show the query it ran and the invariant it checked.

A related confusion is worth killing early. What an AI agent is and what a language server is are different layers. An agent can call a language server today. That does not make the language server a good agent interface. The server answers editor questions. The database answers program questions. You want both while people and agents share the codebase.

Prompts to paste into a coding agent today

These are generic on purpose. They do not assume Elixir. Each one tells the agent to admit a missing index instead of inventing a file and a line. Paste one, point it at a real function in your repo, and read whether the answer is a symbol or a guess.

1. Null flowing into a call. Needs a program database or a type-aware data-flow index. A language server hop is a weak substitute. If you do not have that index, the honest result is "I cannot answer this," plus the tests that would catch it.

text
List every public function that can pass null or nil into save_order.
Name the functions and the types involved.
If you only have file and line guesses, say the index does not support this query.
Do not invent line numbers.

2. Where a type lives. Many language servers can go to a definition if you hand them a position. This prompt refuses that shape. It still works, partially, in repos where symbols are unique and the agent can search. Treat a file path with no symbol name as a failed answer.

text
Where is the type OrderTotal defined?
Answer with the symbol name, the module or package, and the other symbols that reference it.
Do not answer with file and line guesses.

3. Who restarts this when it dies. Needs a runtime query or an explicit config the agent can read (supervisors, service manifests, process managers). On a laptop with only source files, the agent should say the runtime is not connected and point at the config a human would open.

text
Which supervisors, workers, or restart policies restart this process when it fails?
If the runtime does not expose that, say so and list the config files a person would read.
Do not guess a supervisor name.

4. Action at a distance. This is the locality check. It needs data-flow plus an honest list of extension mechanisms. Most codebases can answer the second half from a search. The first half is the program-database question.

text
Trace the paths where customer_id can become null between the public entry point and save_order.
Prefer a call graph or a data-flow query.
If this codebase uses monkey-patching, implicit hooks, or dynamic rebinding, list those as untraced.
Say which part you actually verified.

Claude Code commands and skills are how you stop retyping these. A command that wraps prompt 1 is worth more than a new lint rule nobody runs. The command should still be allowed to return "no index." A skill that forces a confident call graph out of grep is how agents fabricate architecture.

Honest limitations

Valim is writing from Elixir. The VM already lets you inspect processes, sockets, supervisors, and queues. Teams on languages without that runtime should not hear "adopt Elixir." They should hear "name the three surfaces you do not have, and build the cheapest one that stops a class of guess."

Porting a whole ecosystem with an agent still needs tests. A self-contained module with a property test is a fair agent task. A transitive dependency tree is not "just a port."

Human review remains the bottleneck. That caps two tempting ideas at once: a language whose only virtue is agent syntax, and a representation humans cannot review. The diff still has to be something a person can refuse.

The essay is one person's opinion, updated by conversation, and he says those opinions will move. The 20 percent figure is a floor he chose to stop people from waiting for a fully agent-written codebase. It is not a measurement of your team. The Hacker News sample is 18 points, so treat the comments as sharp questions, not a poll.

A program database that is stale is worse than none. If the index lags the branch the agent is editing, the query will bless a call graph that is already wrong. Build the refresh into the same loop that runs tests. And a runtime query in production is a privileged tool. Read-only by default, sandboxed, and logged. Inspection that can also send messages or kill processes is a new incident path.

What this changes in the repo you have

You do not need a language redesign to use the essay. In the repo you will touch this month:

  • Prefer an explicit signature and a stated invariant on the module the agent edits most. Leave inference in place everywhere else. The goal is one place where the checker, the agent, and the reviewer see the same constraint.
  • Add one query you wish the language server answered, even if the first version is a script over a compiler dump. "Public functions that reach this call" is enough to learn whether agents use it.
  • Expose one runtime fact through a tool: restart policy, queue depth, or open connections. Document that the tool is read-only.
  • When you ask an agent to port or generate a library, require the tests that make the next iteration possible. A port without a failing test is a draft, not an ecosystem.

Syntax work can continue. It is just no longer the main event. Communities will still need a reason to share a framework after agents make private forks cheap. The reason that survives is a shared guarantee: one implementation everyone can query, test, and inspect, instead of a pile of generated lookalikes with no common facts.

Related on explainx.ai

  • Loop engineering for coding agents — the harness around the edit, which is where missing program facts show up
  • Context, prompt, loop, harness — why the stack around the model matters more than a shorter syntax
  • Boris Cherny, Opus 5.5, Lean, and TLA+ — an agent writing the explicit proofs Valim says languages should make room for
  • What are agent skills? — durable instructions, the repo-level cousin of a program database
  • DESIGN.md templates for agents — a structured spec an agent can read instead of inferring taste
  • What are AI agents? — the layer that calls tools, distinct from the language server those tools wrap
  • Claude Code commands — where the four prompts above can live so you do not retype them
  • Agent sandboxes and isolation — the boundary a runtime query needs before it watches production

Primary source: Evolving programming languages in the AI era, José Valim, Dashbit, September 24, 2026.


Language tooling and the Dashbit essay are described as of September 27, 2026. Program-database and runtime-query interfaces are uneven across languages, and a prompt that works on one stack may only be able to report that the index does not exist on another.

Spotted something out of date? Let us know.

People in this article

  • Boris Cherny →Head of Claude Code at Anthropic
Explore people in AI →
Yash Thakker

Written by

Yash Thakker

Yash is an AI expert with over 300K learners. Join his workshops →

View Yash Thakker in People in AI →

Related posts

May 21, 2026

oh-my-pi (omp): the batteries-included terminal coding agent that gets edits right the first time

Mario Zechner's Pi, extended with production-grade harness engineering: hashline edits that eliminate whitespace battles, LSP-driven renames, lldb/dlv/debugpy integration, 14-provider web_search, and task isolation across APFS/btrfs/overlayfs—5.5k stars and climbing.

Sep 27, 2026

Gemini 4 Arena Demos: The 3D Jump, and What Is Still a Rumor

A September 27, 2026 wave of arena clips is being read as Gemini 4 Pro: a floatplane against Claude Opus 5.5, a motion comparison against GPT-6 Astra, and one-shot 3D scenes. Google has only confirmed early post-training. This is the demo catalog, with the claims that do not hold.

Sep 27, 2026

What a Prince of Persia Fan Port Shows About Coding Agents

Priyan R spent months handing Prince of Persia to frontier coding agents and only playing the result. Opus 5.5 got a level-1 screen from 8,429 differing pixels down to 2. The useful part for anyone grading agents is the oracle and the diff, not a leaderboard of model names.