# Introducing em—dash

Published 2026-06-11 by [Clinton Judy](https://judy.io/about).

> I sent my friend Joe an apology letter. It compiles.

a heartfelt apology

I sent an apology to my friend Joe last week. It opens:

> I owe you one. I have been drafting this letter since 2024–25, rewriting every half-finished, half-honest version before this one. The truth — and I say this with my whole chest — is that I treated you badly.

It's at least a full page long. Full remorse. Napkin math concluding the fault splits 100–0 against me. A standing offer to be judged not by my words, but by the record.

Also, the letter is nonsense. I don't owe Joe anything (to my knowledge?) What I actually share with Joe is the same nerdy dry sense of humor.

Because in reality, it's a hidden program. If you run it, the apology letter does this:

$  bin/emdash run heartfelt-apology.em
FUCKYOUFUCKYOUFUCKYOUFUCKYOUFUCKYOU
(it does not stop)

I should back up.

## The AI tell

At some point in the last year, the em-dash went from an elegant punctuation mark — like this — to an obvious indicator that AI is responsible for the words you're reading. I've loved the em dash since long before it became a fingerprint. Now, every '—' I type arrives pre-incriminated.

So I leaned all the way in. If my favorite punctuation mark is machine code now, fine. **Let's make it machine code.**

## Enter em—dash

**em—dash** is an esoteric programming language in which the dashes are the *entire* syntax. Every character that is not a dash is a comment. The words are decoration. The punctuation is the program. Which means a tweet, a LinkedIn thinkpiece, or a heartfelt apology can quietly be executable.

## An alphabet of three line segments

The whole character set is three lengths of horizontal line.

- Hyphen-minus U+002D Compound words make it free in prose, so it carries the least meaning. Opcode letter; binary 0.

– En dash U+2013 The terminator. Rare in prose (ranges, mostly) so the language spends it carefully.

— Em dash U+2014 The structure. Formerly elegant, now fully robotic. It introduces data. Binary 1.

That hierarchy is the design principle. Hyphens are cheap, so they do the bulk hauling. Em dashes are common enough to be structural and distinctive enough to mean something. En dashes are precious — real prose barely uses them — so they get the rare, decisive jobs, like slamming a number shut.

(macOS will sell you the whole alphabet: `-` is a hyphen, option+`-` is an en dash, option+shift+`-` is an em dash. Now you're armed.)

## Twenty opcodes, zero delimiters

Under the punctuation, it's a stack machine, in the proud tradition of [Whitespace](https://esolangs.org/wiki/Whitespace). Opcodes are short sequences of the three symbols, and the code is **prefix-free**: no opcode is the beginning of any other. That's the entire parser. No delimiters, no spaces — the dashes just stream in, and the moment a sequence matches, an instruction fires.

-  hyphen –  en dash —  em dash

Read it left to right: - - -  duplicates the top of the stack, - — -  adds, – - -  opens a loop. A lone —  is special: it doesn't run anything — it opens a *number*.

## How punctuation becomes a number

After that opening em dash, the machine reads dashes as bits: hyphen is 0, em dash is 1, and an en dash says the number is over. Then the value lands on the stack, where an instruction like OUTC (output character) can spend it.

Here's the language's "hello world" program, which prints "!" (codepoint 33):

My editor sighed —  again —  at my low- key, half- baked, semi- ironic, over- long sentences —  circa 2024 –  my self- styled, 2013– 14- ish voice.

▸ read it like the interpreter ◂ give the prose back

Click the toggle. The complaining evaporates and eleven dashes remain — and eleven dashes are two instructions:

—
—
-
-
-
-
—
–
-
–
-
push
1 0 0 0 0 1 → 33
end
outc

push 33 · output codepoint 33 · prints "!"

A sentence complaining about its own punctuation, and the punctuation spends the whole time printing an exclamation point. Note the en dash drifting after "circa 2024" like a misplaced British parenthetical — that's the terminator. Every flourish is doing a job.

And because *every non-dash character is a comment* — even in the middle of an opcode — an instruction can be smeared across half an essay. The words can say anything. This is the load-bearing trick.

## The apology, disassembled

Now you can read my letter the way the machine does. Hover the dashes:

I owe you one. I have been drafting this letter since 2024– 25, rewriting every half- finished, half- honest version before this one. The truth —  and I say this with my whole chest —  is that I treated you badly. I was self- absorbed, short- tempered, and thin- skinned. You deserved better —  so much better —  than what I gave. What I gave was second- rate.

For 18– 19 months I let my self- importance run the show. From May– June of last year especially, I was flat- out unbearable. …

-  hyphen · bit 0 –  en dash · terminator —  em dash · bit 1

Sixteen instructions total. [Here is the entire letter, in its entirety.](https://raw.githubusercontent.com/judy/emdash/main/examples/heartfelt-apology.em) And as the machine reads it:

$  bin/emdash disasm heartfelt-apology.em

   3:59   LOOP
   4:69   PUSH 70      F
   9:31   OUTC
  10:64   PUSH 85      U
  13:62   OUTC
  16:29   PUSH 67      C
  19:35   OUTC
  22:23   PUSH 75      K
  26:5    OUTC
  29:18   PUSH 89      Y
  32:44   OUTC
  35:26   PUSH 79      O
  41:5    OUTC
  42:19   PUSH 85      U
  45:14   OUTC
  46:32   END

Ninety dashes spread over two thousand characters of remorse, and every single word is a comment.

## The duplicitous hyphen

There's a second tier for people who find prose inefficient: exotic Unicode dashes that each alias an entire opcode. One character, one instruction. My favorites:

‑ U+2011 → DUP The non-breaking hyphen. Visually identical to a regular hyphen, but I think it will keep line-breaks from forming? Official title: the duplicitous hyphen.

− U+2212 → NEG The minus sign. For minusing.

― U+2015 → OUTC The quotation dash. Use before an author's name. You won't see AI generate these as much, but try telling your  friends that it's not an em-dash.

⸺ U+2E3A → LOOP The two-em dash. It's for "bleeping" out all your f⸺g swear words. Ain't that neat?

⸻ U+2E3B → END The three-em dash. No one uses this any more. Makes sense, it's bordering on... well, borders.

&shy; U+00AD → BREAK The soft hyphen: an invisible debugger breakpoint. It's up there, I swear.

Every other dash in Unicode is reserved (as much as you can reserve characters for yourself). Using one is a lexer error with a bespoke diagnostic — `U+1806 MONGOLIAN TODO SOFT HYPHEN is reserved; this program is too powerful`.

## Handle with care

A language made of punctuation is fragile in ways no other language gets to be. Unicode normalization — the tidying that text pipelines do constantly, silently — will quietly swap the duplicitous hyphen for a plain one and change what your program *does*. Some editors substitute dashes on paste. So the toolchain ships a `dump` command that names every dash's codepoint, one per line, for debugging by squinting.

## The confession inside the confession

Of course I didn't write the apology. I wrote this:

$  cat apology.asm

loop
  say "FUCKYOU"
end

The assembler turns that into the ninety dashes. Then I handed the dash sequence to Claude — the very LLM whose em-dash habit started the whole discourse — and asked it to write a sincere apology around them: every dash in order, no extras, prose that scans like a person at their lowest. There's a `verify` tool that checks a draft against the target program, dash by dash, so the model can iterate until:

$  bin/emdash verify heartfelt-apology.em apology.em

draft realizes the target program: all 90 dashes correct. Send it.

This is constrained writing — the same family as lipograms and Oulipo — and it turns out LLMs are *unsettlingly* good at it.

## A Heartfelt Apology

I can't commit to a prank. I sent the fake apology letter to Joe, and immediately followed up with what it was actually about.

I also didn't write this esolang from scratch. This was an evening project playing around with [Claude Fable 5](https://www.anthropic.com/news/claude-fable-5-mythos-5). Around a half-hour of back-and-forth discussion with the model, and then asking if Fable could write the whole thing at once. And it did.

One day later, the [US Government banned Fable 5](https://www.anthropic.com/news/fable-mythos-access), citing "national security". I'm not gonna comment on that, other than to say that it was probably my fault for asking it to write a joke programming language that uses em-dashes as syntax.

The interpreter, the spec, the assembler, and the complete apology live on GitHub: [em—dash](https://github.com/judy/emdash). I have no future plans for it. It's a joke, a puzzle, and a love letter to the em dash. But if you do find a use for it, or write something fun with it, let me know!
