<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Oded Fuhrmann</title>
    <description>The latest articles on DEV Community by Oded Fuhrmann (@oded_fuhrmann_86130c99a67).</description>
    <link>https://dev.to/oded_fuhrmann_86130c99a67</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4024452%2Fb52499a5-3df4-4dd7-99f5-b04d8228f2f1.png</url>
      <title>DEV Community: Oded Fuhrmann</title>
      <link>https://dev.to/oded_fuhrmann_86130c99a67</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/oded_fuhrmann_86130c99a67"/>
    <language>en</language>
    <item>
      <title>E‑‑: The middle ground between English and Python</title>
      <dc:creator>Oded Fuhrmann</dc:creator>
      <pubDate>Fri, 10 Jul 2026 19:20:26 +0000</pubDate>
      <link>https://dev.to/oded_fuhrmann_86130c99a67/e-the-middle-ground-between-english-and-python-5eal</link>
      <guid>https://dev.to/oded_fuhrmann_86130c99a67/e-the-middle-ground-between-english-and-python-5eal</guid>
      <description>&lt;p&gt;&lt;em&gt;Or, what if you could dial how much English lives in your code, per line?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;You can dial the English-Python ratio per line, per value, per region. Whichever end of the spectrum makes sense right there.&lt;/p&gt;

&lt;h2&gt;
  
  
  The dial
&lt;/h2&gt;

&lt;p&gt;Here's the same intent expressed at three different points on the dial.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fully coded&lt;/strong&gt; — you commit to every value:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Set tempo to 70.
Set piece to Call [[compose_blues]] with tempo=tempo, key="E".
Return piece.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Mixed&lt;/strong&gt; — structure is code, one value is English:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Set tempo to {{ a tempo appropriate for a slow blues }}.
Set piece to Call [[compose_blues]] with tempo=tempo, key="E".
Return piece.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;More English&lt;/strong&gt; — most of the intent is described, not written:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Set piece to {{ compose a slow blues in E with a tempo appropriate for the style }}.
Return piece.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Same intent. Different English-Python ratios. Author chose.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;{{ ... }}&lt;/code&gt; markers are &lt;strong&gt;slots&lt;/strong&gt; — 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.&lt;/p&gt;

&lt;h2&gt;
  
  
  What E-- looks like
&lt;/h2&gt;

&lt;p&gt;E-- has a closed grammar of English-ish verbs: &lt;code&gt;Define&lt;/code&gt;, &lt;code&gt;Set&lt;/code&gt;, &lt;code&gt;Let&lt;/code&gt;, &lt;code&gt;Do&lt;/code&gt;, &lt;code&gt;Call&lt;/code&gt;, &lt;code&gt;Return&lt;/code&gt;, &lt;code&gt;Give back&lt;/code&gt;, &lt;code&gt;For each&lt;/code&gt;, &lt;code&gt;If&lt;/code&gt;, &lt;code&gt;Otherwise&lt;/code&gt;. Statements end in a period. Function references appear as &lt;code&gt;[[wikilinks]]&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;A canonical program:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Define [[describe]] taking n:
    If n is greater than 10:
        Give back "big".
    Give back "small".

For each n in &amp;lt;3, 42, 7&amp;gt;:
    Do [[print]]([[describe]](n)).
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Compiles to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;big&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;small&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verb-first, sentence-shaped, but structured enough to parse deterministically. Reads out loud like English.&lt;/p&gt;

&lt;h2&gt;
  
  
  Slots — where English lives inside code
&lt;/h2&gt;

&lt;p&gt;A slot is a &lt;code&gt;{{ ... }}&lt;/code&gt; placeholder containing an English description. At compile time, the compiler dispatches an LLM to resolve the slot to a concrete Python expression.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Value slots&lt;/strong&gt; — the simplest case:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Set tempo to {{ a tempo appropriate for a slow blues }}.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The compiler asks the LLM: "convert 'a tempo appropriate for a slow blues' to a Python expression." LLM returns &lt;code&gt;70&lt;/code&gt;. Compiler splices it in. Final code: &lt;code&gt;tempo = 70&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code slots (v0.2.0)&lt;/strong&gt; — for whole regions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Set tempo to 70.
{{ create a harmony using form with the tempo }}
Set piece to Call [[voices_list]] with sections=[harmony].
Return piece.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Resolution is a one-time cost.&lt;/strong&gt; 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.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this matters
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Accessibility meets precision.&lt;/strong&gt; 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.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Domain experts can code the parts they know.&lt;/strong&gt; 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.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Runtime is deterministic and cheap.&lt;/strong&gt; 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.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Programs are inspectable at multiple levels.&lt;/strong&gt; 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.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Static analysis is easy on structured code.&lt;/strong&gt; 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.&lt;/p&gt;

&lt;h2&gt;
  
  
  An example consumer: Forge
&lt;/h2&gt;

&lt;p&gt;E-- exists because a project called Forge needed a language its cohort could author.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;Here's a Recipe for a 12-bar blues:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;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.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;form&lt;/code&gt;, &lt;code&gt;drum_chorus&lt;/code&gt;, &lt;code&gt;guitar_solo_chorus&lt;/code&gt;, &lt;code&gt;voices_list&lt;/code&gt; are library functions in Forge's music library. The Recipe composes them like building blocks.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;A more advanced user might write a Recipe with slots:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;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.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where to go next
&lt;/h2&gt;

&lt;p&gt;Try it in 30 seconds:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;e-minus-minus
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then a tiny E-- program:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s1"&gt;'Set x to 5.\nDo [[print]](x).\n'&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; hello.emm
emm-transpile hello.emm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Prints:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. No LLM required for canonical E-- with no slots. See the &lt;a href="https://github.com/frmoded/e--/blob/main/README.md" rel="noopener noreferrer"&gt;README&lt;/a&gt; for slot resolution and free-English input.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;E-- itself:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://pypi.org/project/e-minus-minus/" rel="noopener noreferrer"&gt;E-- on PyPI&lt;/a&gt; — &lt;code&gt;pip install e-minus-minus&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/frmoded/e--" rel="noopener noreferrer"&gt;E-- on GitHub&lt;/a&gt; — source, examples, and the CLI&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/frmoded/e--/blob/main/docs/spec.md" rel="noopener noreferrer"&gt;The E-- language specification&lt;/a&gt; — the full grammar, the semantics, the design decisions&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/frmoded/e--/blob/main/README.md" rel="noopener noreferrer"&gt;The E-- README&lt;/a&gt; — quick-start, install, worked examples&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Forge (an example consumer):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/frmoded/forge-client-obsidian" rel="noopener noreferrer"&gt;Forge on GitHub&lt;/a&gt; — the Obsidian plugin that turns E-- Recipes into rendered music, generative art, and simulations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Get in touch:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;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 &lt;strong&gt;&lt;a href="mailto:frmoded@gmail.com"&gt;frmoded@gmail.com&lt;/a&gt;&lt;/strong&gt;. E-- is small and open-source (Apache 2.0). If you use it in your own project, let me know what you build.&lt;/p&gt;

</description>
      <category>python</category>
      <category>llm</category>
      <category>programming</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
