Pillar 02 · The wedge

Greppability

One name, one place. Every symbol has exactly one syntactic form at the spot it's declared, so a plain grep finds the definition — always, with no index, no language server, and no luck required.

Why "where is this defined?" is hard

In a mature TypeScript codebase, the simplest question — where does this name come from? — is often the hardest. The language offers half a dozen ways to spread one symbol across many places: overloads split a function into several signatures, decorators wrap it in something else, namespace and interface merging scatter a type across files, declare module augments code you don't own, and barrel index.ts files re-export everything so the path you import from isn't where anything actually lives.

A human copes with an LSP and muscle memory. An agent greps — it reads the repo as text — and every one of those constructs is a place the text lies about where the code is. Glyph removes them. The result is a language where search is a reliable primitive, not a heuristic.

01 One declaration, one form

A function, type, or component is declared exactly once, with one syntax. There are no overloads to split a signature and no way to redeclare a name — two top-level things with the same name is a hard error (E0100). So the search for a definition has exactly one answer.

TypeScript — four hits, one is the body $ grep -n "parseUser" src/
users.ts:4:  export function parseUser(
users.ts:9:  export function parseUser(
index.ts:2: export { parseUser } from
api.ts:7:   import { parseUser } from
Glyph — the first hit is the definition $ grep -n "fn parseUser" src/
users.glyph:12:fn parseUser(
  raw: unknown,
) -> Result<User, string> {

The declaration keyword is part of the name you search for. grep "fn parseUser" cannot match a call, an import, or a re-export — only the one place it's defined.

02 No barrel files — the import path is the location

Glyph imports never re-export, and a module whose only contents are imports is rejected (E0102). There is no index.ts laundering layer. So an import names the module the symbol actually lives in — the path is the address.

the import tells you exactly where to look
import myapp/users { parseUser }
//     ^^^^^^^^^^^ the file is src/myapp/users.glyph.
//     not a re-export of a re-export of a barrel.

03 No hidden ways to attach behavior

There are no decorators wrapping a function in an unseen layer, no namespace merging pooling members from across the tree, no declare module augmenting a third-party type from a file you'd never think to open, and no implicit this rebinding what a method refers to. A name resolves to one declaration, and everything that shapes it is visible at that declaration.

04 Even mutation is greppable

Greppability isn't only about finding definitions — it's about finding effects. Shared state lives in a std/store, and every change to it is a literal .set( or .update( call. So one search enumerates the entire write-surface of a piece of state, instead of hunting for assignments scattered through the file.

$ grep -rn 'tasks\.\(set\|update\)' src/
src/tasks.glyph:16:  tasks.update(fn(cur) { ... })
src/tasks.glyph:24:  tasks.set([])
# every place the task list can change, enumerated.
# nothing hides in an ordinary `x = ...` elsewhere.

A codebase is greppable when its text tells the truth about its structure. Every restriction here — one form per name, no re-exports, no merging — is there so that a search returns the answer, not a lead.

The benchmark — coming

The measurable version of this claim is precision: for a given symbol, what fraction of a plain grep's hits are the thing you were actually looking for, and how many steps does it take an agent to reach a definition? Glyph isn't in real-world use yet, so the chart below is a placeholder — it fills in with real numbers once there's a real codebase to measure.

Grep precision for a definition · higher is better

TypeScript vs Glyph

Glyph
pending
TypeScript
pending
Not measured yet We'll report grep precision and steps-to-definition from a real Glyph codebase as soon as one exists, and publish the numbers here whatever they turn out to be.

The payoff compounds with scale and with autonomy. A human learns a codebase's hiding places; an agent starting cold does not. Greppability is what lets a tool — or a new teammate — navigate by reading, the way the repo actually is.