E‑‑: The middle ground between English and Python A developer introduced E--, a programming language that allows developers to dial the ratio of English to Python per line. The language uses {{...}} slots for English descriptions resolved by an LLM at compile time, producing deterministic Python code. E-- aims to combine the readability of English with the precision of code, offering a middle ground between natural language and traditional programming. Or, what if you could dial how much English lives in your code, per line? Modern LLM code generation has a strange property. Your program's behavior is a function of your prompt, the model's mood, and whatever context happened to be in memory. There's no single artifact you can point to and say "this is what runs." Same input, different output. Same request, different code. You can work around this — cache LLM output, freeze model versions, forbid regeneration at runtime. But you're always working around the LLM, never with it. E-- flips the shape. What if the LLM's involvement was constrained to a specific structural slot in your source, resolved once at compile time, and everything else was normal deterministic code? Now you can pick, per value, how much LLM you want in your program. Once picked, the result is byte-for-byte reproducible. You can dial the English-Python ratio per line, per value, per region. Whichever end of the spectrum makes sense right there. Here's the same intent expressed at three different points on the dial. Fully coded — you commit to every value: Set tempo to 70. Set piece to Call compose blues with tempo=tempo, key="E". Return piece. Mixed — structure is code, one value is English: Set tempo to {{ a tempo appropriate for a slow blues }}. Set piece to Call compose blues with tempo=tempo, key="E". Return piece. More English — most of the intent is described, not written: Set piece to {{ compose a slow blues in E with a tempo appropriate for the style }}. Return piece. Same intent. Different English-Python ratios. Author chose. The {{ ... }} markers are slots — placeholders where you write English instead of a value. E-- treats them as first-class syntax. At compile time, the compiler resolves each slot to a concrete Python expression. Then normal deterministic code runs. E-- has a closed grammar of English-ish verbs: Define , Set , Let , Do , Call , Return , Give back , For each , If , Otherwise . Statements end in a period. Function references appear as wikilinks . A canonical program: Define describe taking n: If n is greater than 10: Give back "big". Give back "small". For each n in <3, 42, 7 : Do print describe n . Compiles to: python def describe n : if n 10: return "big" return "small" for n in 3, 42, 7 : print describe n Verb-first, sentence-shaped, but structured enough to parse deterministically. Reads out loud like English. A slot is a {{ ... }} placeholder containing an English description. At compile time, the compiler dispatches an LLM to resolve the slot to a concrete Python expression. Value slots — the simplest case: Set tempo to {{ a tempo appropriate for a slow blues }}. The compiler asks the LLM: "convert 'a tempo appropriate for a slow blues' to a Python expression." LLM returns 70 . Compiler splices it in. Final code: tempo = 70 . Code slots v0.2.0 — for whole regions: Set tempo to 70. {{ create a harmony using form with the tempo }} Set piece to Call voices list with sections= harmony . Return piece. The slot at line 2 is at a statement position — the compiler asks the LLM to produce statements plural , which get spliced in at proper indentation. Resolution is a one-time cost. The compiler caches every slot resolution keyed by the slot's text. Subsequent builds are cache hits — no LLM call, byte-identical output. Once your slots are resolved, the resulting Python is a normal deterministic artifact you can inspect, run, share, freeze, whatever. Accessibility meets precision. Programming languages have historically had to pick. English-like DSLs Inform 7, AppleScript, SQL traded expressiveness for readability. Full programming languages trade readability for expressiveness. E-- doesn't force the choice: use precise syntax where you know what you want; use English where you'd rather describe. Both on the same line if you want. Domain experts can code the parts they know. A musician writes structural composition — call these functions, in this order, combine them. They defer specifics — key, tempo, scale characteristics — to English descriptions. Same for a biologist authoring a simulation: fix the experimental structure, let the LLM pick reasonable parameters. Same for a designer, a hobbyist, a student. Runtime is deterministic and cheap. Because slot resolution happens at compile time and gets cached, no LLM call ever happens at runtime. Same source, same behavior forever. Cost scales with authoring, not execution. Programs are inspectable at multiple levels. You have the source structured, human-readable, English-y , the resolved intermediate still E--, slots now filled , and the compiled Python. Three artifacts you can look at when things break. Traditional LLM-generated code gives you only the natural-language input and the possibly regenerated output — the intermediate structure has evaporated. Debug that: you've got a bug you can't reproduce, in code you didn't write, on a system that costs you an API call to inspect. Static analysis is easy on structured code. Chip palette insertion, dependency graph extraction, wikilink navigation — all straightforward on E-- syntax. Trade-off: inside a code slot, the resolved code is opaque to structural tooling. You choose per-slot whether structure or delegation matters more. E-- exists because a project called Forge needed a language its cohort could author. Forge is an environment for creative work — music composition, generative art, running simulations — where non-programmers author computable notes. The cohort's users are musicians, artists, researchers. Python was inaccessible. Description-only was imprecise. E-- filled the middle. Every note has three facets: a Description in prose, a Recipe in E--, and the compiled Python. All three are visible in the editor at once. Here's a Recipe for a 12-bar blues: Let harmony = Call form . Let drums = Call drum chorus with profile="standard". Let guitar = Call guitar solo chorus . Let piece = Call voices list with sections= harmony, drums, guitar . Return piece. form , drum chorus , guitar solo chorus , voices list are library functions in Forge's music library. The Recipe composes them like building blocks. That Recipe transpiles to Python which constructs the musical score via music21 and renders it as MusicXML in the user's editor. Once the Recipe is written, everything downstream is deterministic. Two users open the same note and get the same blues. A more advanced user might write a Recipe with slots: Let tempo = {{ a tempo appropriate for a slow blues }}. Let key = {{ a key that pairs well with a moody vocal style }}. Let piece = Call compose blues with tempo=tempo, key=key. Return piece. They know the structure — compose a blues, at some tempo, in some key. Specifics they'd rather delegate. LLM resolves once at compile time; result caches; subsequent renders are pure. Forge is one consumer. E-- itself is a language substrate any system could build on. If you want your users to author programs that are precise enough to run but accessible enough to read — with escape hatches to English wherever they want them — E-- is a shape that works. Try it in 30 seconds: pip install e-minus-minus Then a tiny E-- program: printf 'Set x to 5.\nDo print x .\n' hello.emm emm-transpile hello.emm Prints: x = 5 print x That's it. No LLM required for canonical E-- with no slots. See the README https://github.com/frmoded/e--/blob/main/README.md for slot resolution and free-English input. E-- itself: pip install e-minus-minus Forge an example consumer : Get in touch: If you're building a tool that could use E--, if you have questions about the design, or if you'd like to collaborate on where the language goes next — email me at frmoded@gmail.com . E-- is small and open-source Apache 2.0 . If you use it in your own project, let me know what you build.