We are currently working on new rules for what content should and shouldn't be allowed on this website, and are looking for feedback! See Esolang:2026 topicality proposal to view and give feedback on the current draft.

Regards,

From Esolang
Jump to navigation Jump to search
Regards,
Paradigm(s) imperative
Designed by User:Kvashaihor
Appeared in 2026
Memory system variable-based
Computational class Turing complete
Reference implementation regards.py (Python 3)
Influenced by Chef, Shakespeare
File extension(s) .rgrd

Regards, is an esoteric programming language whose source code is a passive-aggressive corporate email thread. It was created in 2026.

Its syntax is built from email conventions. The > markers that email clients put in front of quoted replies are the language's indentation, so quote depth is block depth. A message ends when it is signed off, which makes a sign-off such as Best, the halt instruction; the language is named after one of them. Earlier messages quoted below the signature define people, and people are the language's functions.

Program structure

A program is one email message, optionally quoting a thread beneath it.

Subject: <program name>              ← program name, ignored by the interpreter
Cc: <Name>, <Name>                   ← who Replying all. reaches (optional)

Hi <name>,                           ← entry point (Hello, Hey and Dear work too)

<body>                               ← statements; > depth is block depth

Best,                                ← HALT
Ihor                                 ← ignored
P.S. …                               ← also ignored (optional)

Sent from my iPhone                  ← turns on autocorrect (optional)

On Tue, 8 Sep 2026, Priya Raman <priya@…> wrote:
> <the quoted thread below the signature is the standard library>
> <each quoted message defines a person you can call>
Region Role
Header lines Subject: is the program name, and decorative. Cc: lists who Replying all. reaches.
Body, from Hi …, to the sign-off The program.
Quoted thread below the signature Previously defined messages (people), available to call.

Below the sign-off, only four things are allowed: the signature name, P.S. lines, the Sent from my iPhone pragma, and On …, <Name> wrote: blocks. Anything else is unreachable code and an error. P.S. lines are ignored.

A quoted message's own text sits at one level of >, and its blocks are counted from there, so a loop body inside a quoted message is at > >. Messages quoted inside a quoted message are one level deeper again, and everyone in the thread, however deep, is callable. >> and > > are the same depth.

Lexical rules

All statements are matched case-insensitively with normalized whitespace. Email clients rewrite text as it is typed, so the lexer undoes it: curly quotes become straight quotes, and , and -- are all the same dash.

Variables

A variable is named by its last word, lowercased, with a trailing s dropped. open reqs, req and Reqs are one variable, which is what lets a program declare 5 open reqs and then close one req. The corollary is that open reqs and closed reqs are also one variable. Words of three letters or fewer, and words ending in ss, keep their s. The pronouns it and that refer to whichever variable was mentioned last before the current statement.

Values are integers with no upper limit. Halving and splitting round toward negative infinity. Wherever a table below says <n>, <a> or <expr>, a number, a variable, what's left after splitting … or someone's take may be written. The one exception is Just to level-set, we have <n> <var>., where <n> must be a plain number. The backlog and jargon have their own sections below.

Statements

Declaration and assignment

Statement Meaning
Just to level-set, we have <n> <var>. declare var, assign n
Just to level-set, <var> is <n>. declare var, assign n
Per the attached, <var> is now <expr>. reassign
<var> is off the table. var = 0
Happy to take this offline. variables declared from here to the end of the block are private
We have a hiring freeze on <var>. writes to var silently do nothing from here on
The freeze on <var> is lifted. writes to var work again
Looping in <Name>. / +<Name> no effect; everyone in the quoted thread is already callable

Arithmetic

Statement Meaning
Good news — we've added another <var>. var += 1
Quick flag: one <var> is now closed. var -= 1
Doubling down on <var>. var *= 2
Let's cut <var> in half. var //= 2
Rolling <a> into <b>. b += a
Backing <a> out of <b>. b -= a
Scaling <b> by <a>. b *= a
Splitting <b> across <a>. b //= a
what's left after splitting <b> across <a> b % a (expression)
somewhere between <a> and <b> a random integer from a to b, both included (expression)

Conditions

Condition Meaning
we still have <var> var > 0
<var> is at zero var == 0
we're under <n> on <var> var < n
we're over <n> on <var> var > n
we're at <n> on <var> var == n
there's nothing left after splitting <var> across <n> var % n == 0

Control flow

Statement Meaning
If <cond>: if; the body is the next quote level
That said, if <cond>: else if
That said: else
Per my last email, while <cond>: while
Bumping this. re-send the current message: restart the program, or the person being called, from the top
As discussed, <Name>. call person Name
As discussed, <Name>, re: <a>. call Name with a as the ask
<Name>'s take call Name and use their net-net (expression)
<Name>'s take on <a> the same, with a as the ask (expression)
Net-net, <a>. end the current person's message and report a back
I am currently OOO, returning <date>: error handler for the rest of the block
Resending with the attachment: <file>. import the people quoted in another program
Replying all. / Replying all, re: <a>. call everyone on the Cc: line at once
Going forward, "<phrase>" means "<statement>". define jargon (see below)

Bumping this. does not remember anything about the first attempt. Variables keep their values, but every statement runs again, including the ones that set them up.

Input and output

Statement Meaning
Circling back on <var>. print var (or any expression), then a newline
Circling back on "<literal>". print a literal, filling in [placeholders], then a newline
+Leadership for visibility. flush stdout
Thoughts? / Please advise. read an integer into the last-mentioned variable
Let me spell <a> out. / Let me spell out <a>. print the character with code a, without a newline
Reading between the lines. read one character's code into the last-mentioned variable, or -1 at the end of input

Literals work like a mail merge. Each [placeholder] is filled from the variable of that name, and a placeholder that matches no variable is printed exactly as typed. With reqs at 3 and no variable called name, this prints Hi [First Name], we have 3 open reqs:

Circling back on "Hi [First Name], we have [reqs] open reqs".

Sign-offs and pragmas

Statement Meaning
Best, / Thanks, / Cheers, / Warm regards, / Kind regards, / Best regards, / Many thanks, / Sincerely, halt, exit code 0
Regards, halt, exit code 1
Sent from my iPhone disable all optimizations (there aren't any) and turn on autocorrect
Sorry for the delay! sleep 1 second
Thanks in advance. warn if the previous Thoughts? did not get a number back
Hope you're well., Thanks! and other pleasantries nothing, unless HR is cc'd (see below)
Blocking <n> minutes for this. (or hours) start a timebox
FYI … a comment; the whole line is ignored

A bare Regards, halts with exit code 1, because it is not a friendly sign-off. Only the original email's sign-off sets the exit code; a person who signs off with a bare Regards, returns normally. Thanks in advance. only ever warns and never stops the program, and the warning cannot be turned off.

With Sent from my iPhone in the message, a line that does not parse gets a second chance: misspelled words are matched against the language's own vocabulary, one word at a time before several at once, and each correction prints a warning such as autocorrected `Circlign` to `circling`.

Blocking 30 minutes for this. starts a timebox. Every statement after it costs one second of the meeting, and so does every loop check, so 30 minutes allows 1,800 statements. When time runs out the program stops with we're over time. An out-of-office cannot catch this, because the auto-reply is over time too. All replies to a reply-all share the same clock.

People are functions

A person becomes callable by being defined in the quoted thread below the signature. Their name is the first name in the On …, <Name> wrote: line, and they are called with As discussed, <Name>.

There is one shared set of variables: a person reads and changes the same variables as the caller, unless the call is taken offline. Values can also be passed in as the ask and returned as a net-net (see below). The person halts on their own sign-off and control returns to the caller. A person who never signs off is a parse error, because the thread is still open.

A person can call themselves. After 1000 nested calls the interpreter stops with the error this thread has too many replies. Let's set up a meeting.

Net-net

Net-net, <a>. ends the person's message on the spot and reports the value back. The value is used by asking for the person's take:

Just to level-set, budget is Priya's take.
Circling back on Dave's take on budget.

A take calls the person and evaluates to their net-net. Signing off without one is an error when a take was asked for. A plain As discussed, Dave. still works on a person who gives a net-net: the net-net ends the message early and the value is discarded. A net-net in the original email is an error, because there is nobody to report back to.

The ask

As discussed, Dave, re: <a>. and Dave's take on <a> both pass one value, which the person reads as the ask. It is a copy, so changing it does not change the caller's variable.

Passing an argument takes the call offline. The person gets a private scope holding the ask, and anything they declare with Just to level-set stays in it. A plain call without re: shares everything. The private scope is what makes recursion possible; see the recursion example.

Taking it offline

Happy to take this offline. makes the rest of its block private. Anything declared after it with Just to level-set disappears when the block ends, as does anything created by assigning to a name nobody had declared. Variables that already existed are still shared, so Good news — we've added another req. inside the block changes the same req as outside it.

A person never sees the caller's offline variables, only the shared ones.

Out of office

I am currently OOO, returning <date>: (or I'm currently OOO) covers the rest of the block it sits in. When a statement after it fails at runtime, even deep inside a called person, the reply quoted underneath runs in its place and the program continues after that block. The date is ignored.

Just to level-set, we have 12 open reqs.
Just to level-set, we have 0 teams.

I am currently OOO, returning Monday:
> Circling back on "no teams yet, so no split. Back Monday".

Splitting reqs across teams.
Circling back on reqs.

Statements before the auto-reply are not covered, and an error inside the auto-reply itself is not caught. Parse errors in the program itself are never caught, since they happen before the program starts; a broken attachment is a runtime error and can be caught. Net-net and Bumping this. are not errors and pass through.

Attachments

Resending with the attachment: finance.rgrd. reads another program and makes everyone quoted in its thread callable from then on. The attachment's own body never runs. File names are relative to the program being run, and a person in the attachment replaces anyone on the thread with the same name. A missing or unparseable attachment is an error at the line that asked for it, so an out-of-office can catch it.

Reply-all

A Cc: line above the greeting lists people by name. Replying all. calls all of them at once, each on its own interpreter thread, and waits for every reply to finish before continuing. Replying all, re: <a>. gives each of them the same the ask.

Replies share variables with no locking, so concurrent updates to the same variable can be lost. In one run where two people each added 1 to a shared counter 20,000 times, the counter finished at 23,187. Lines printed by different people can arrive in any order.

When a reply fails, the program stops with that error after the other replies finish, unless an out-of-office around Replying all. catches it. A quoted message can have its own Cc: line, which applies to Replying all. statements in that message. HR is never called, because HR is only cc'd for visibility.

The backlog

Statement Meaning
Adding <a> to the backlog. add a to the backlog
Picking up the next backlog item as <var>. take the oldest item
Picking up the most urgent backlog item as <var>. take the newest item
we still have a backlog the backlog is not empty (condition)
the backlog is empty the backlog is empty (condition)
the size of the backlog number of items (expression)

The next item is the one that has waited longest, and the most urgent one is whatever arrived last. Picking up from an empty backlog is an error. A word in front names a separate backlog, as in Adding 5 to the design backlog. Backlogs belong to the whole thread: offline scopes do not hide them, and all replies to a reply-all see the same ones.

Jargon

Going forward, "<phrase>" means "<statement>". defines a new phrase. Before the program runs, every later line that matches the phrase is replaced with the statement, including lines in the quoted thread; lines above the definition are unaffected.

Going forward, "let's action [ticket]" means "Adding [ticket] to the backlog".

Let's action 3.

A word in [brackets] matches any text and is carried into the statement. If the statement has no final punctuation, it takes the phrase's, so Let's action 3. becomes Adding 3 to the backlog. Jargon can be defined in terms of other jargon and can replace built-in phrases, including sign-offs. Jargon that expands indefinitely is an error.

When HR is cc'd

When HR is on the Cc: line, between one fifth and one third of the email's statements, including those inside blocks, must be pleasantries: Hope you're well., Hope you are doing well., Hope this helps., Hope you had a great weekend., Thanks!, Thank you., Appreciate it., Much appreciated., Thanks in advance. or Sorry for the delay!. Too few is a parse error (too curt), and so is too many (sycophantic). FYI lines and jargon definitions are not counted. The rule is modelled on INTERCAL's requirement that a program say PLEASE neither too rarely nor too often.

Without HR on cc, pleasantries do nothing, and Replying all. never calls HR.

Saved emails

The reference interpreter also runs emails saved as .eml files. Transfer encodings are decoded, and the Subject: and Cc: headers are kept, so reply-all and the HR rule apply. The plain-text part is used when present; an HTML-only email is flattened to text, with <blockquote> quoting turned into > quoting so the quoted thread still defines people. Resending with the attachment: <file>. prefers a real attachment of that name inside the email over a file on disk. Outlook-style threads, which stack earlier messages under From:/Sent: header blocks instead of quoting them with >, are understood in any program: each header block counts as On …, <Name> wrote:, and the message under it as quoted. Forwarded messages are handled the same way. The first name is taken from Dave Okonkwo <dave@example.com>, Okonkwo, Dave and dave.okonkwo@example.com alike.

Errors

Error messages stay in the voice of a corporate email. An error that no out-of-office catches stops the program with exit code 2.

warning: `Sent from my iPhone` present; optimizations disabled, autocorrect on.

warning: autocorrected `Circlign` to `circling` (line 6)

error: Dave isn't on this thread. Happy to resend (line 3)

error: nobody told me about `budget`. Can you send it over? (line 3)

error: `Let's synergize.` isn't something I can action (line 3)

error: unreachable code after `Best,`. (line 8)
       Nothing below a sign-off is read. This is true of email generally.

error: splitting across zero. That's not a realistic plan (line 5)

error: this thread has too many replies. Let's set up a meeting (line 4)

error: Dave signed off without a net-net. What's the takeaway? (line 4)

error: `Net-net` in the original email. There's nobody to report back to (line 6)

error: the attachment `finance.rgrd` didn't come through. Can you resend? (line 5)

error: nobody is cc'd. Reply-all to whom? (line 7)

error: HR is cc'd and this email is too curt. Maybe open with `Hope you're well.` (line 2)

error: the backlog is empty. Nothing to pick up, so enjoy the quiet sprint (line 9)

error: we're over time. Let's continue next week (line 12)

error: somewhere between 8 and 3 isn't a range. Did you mean between 3 and 8? (line 5)

error: not sure what `it` refers to. Can you be more specific? (line 5)

error: this jargon goes in circles. Can someone say it in plain English? (line 7)

error: -1 isn't a letter, so there's nothing to spell out (line 5)

error: reading between the lines of nothing in particular (line 5)

error: this email has no text in it. Was it all screenshots?

error: no sign-off. The thread is still open.

Computational class

Regards, is Turing complete, because it can simulate a two-counter Minsky machine.

Integers have no upper limit, so two variables can hold the counters. Good news — we've added another increments one and Quick flag: one … is now closed decrements it. A third variable holds the machine's current state. The program is a single Per my last email, while loop with an If / That said, if branch for each state, and a state that jumps on zero tests its counter with is at zero before setting the next state.

The Brainfuck interpreter below is a more direct demonstration: brainfuck with an unbounded tape is Turing complete, and the backlogs that hold the tape have no size limit.

Examples

Hello, world!

Subject: quick one

Hi team,

Circling back on "Hello, World".

Best,
Ihor

Countdown

Subject: Q3 headcount — quick sync?

Hi Priya,

Just to level-set, we have 5 open reqs.

Per my last email, while we still have open reqs:
> Circling back on open reqs.
> Quick flag: one req is now closed.

+Leadership for visibility.

Best,
Ihor

Output:

5
4
3
2
1

FizzBuzz

Subject: Sprint cadence — recurring invite

Hi all,

Just to level-set, we have 1 sprint.

Per my last email, while we're under 101 on sprint:
> If there's nothing left after splitting sprint across 15:
> > Circling back on "retro + all-hands".
> That said, if there's nothing left after splitting sprint across 3:
> > Circling back on "retro".
> That said, if there's nothing left after splitting sprint across 5:
> > Circling back on "all-hands".
> That said:
> > Circling back on sprint.
> Good news — we've added another sprint.

+Leadership for visibility.

Best,
Ihor

Sent from my iPhone

Factorial of 5

Subject: Re: Re: Fwd: modelling assumptions (was: quick q)

Hi Priya,

Just to level-set, runway is 1.
Just to level-set, we have 5 quarters.

Per my last email, while we still have quarters:
> Scaling runway by quarters.
> Quick flag: one quarter is now closed.

Circling back on runway.
+Leadership for visibility.

Best,
Ihor

Calling a person

Subject: Re: deck

Hi Dave,

As discussed, Dave.

Best,
Ihor

On Mon, 7 Sep 2026, Dave Okonkwo <dave@example.com> wrote:
> Hi Ihor,
>
> Circling back on "the deck is attached".
>
> Best,
> Dave

Recursion

Factorial of 10, computed by a person who asks themselves. Output: 3628800.

Subject: Re: 10-year forecast — can Dave run the numbers?

Hi Dave,

Circling back on Dave's take on 10.

Best,
Ihor

On Mon, 7 Sep 2026, Dave Okonkwo <dave@example.com> wrote:
> Hi Ihor,
>
> If the ask is at zero:
> > Net-net, 1.
>
> Just to level-set, prior year is the ask.
> Quick flag: one year is now closed.
> Just to level-set, forecast is Dave's take on prior year.
> Scaling forecast by the ask.
> Net-net, forecast.
>
> Best,
> Dave

Attachment

finance.rgrd:

Subject: Finance contacts

Hi all,

Circling back on "Please use the thread below.".

Best,
Priya

On Fri, 4 Sep 2026, Priya Raman <priya@example.com> wrote:
> Hi team,
>
> Net-net, 250.
>
> Best,
> Priya

A program next to it that calls Priya. Output: 250.

Subject: Fwd: budget owner

Hi Dave,

Resending with the attachment: finance.rgrd.

Just to level-set, budget is Priya's take.
Circling back on budget.

Best,
Ihor

Reply-all

Dave and Priya reply at the same time, each to a different variable. Output: 4, then 250.

Subject: Q4 planning — please add your numbers
Cc: Dave Okonkwo <dave@example.com>, Priya Raman <priya@example.com>

Hi all,

Just to level-set, headcount is 0.
Just to level-set, budget is 0.

Replying all.

Circling back on headcount.
Circling back on budget.

Best,
Ihor

On Mon, 7 Sep 2026, Dave Okonkwo <dave@example.com> wrote:
> Hi Ihor,
>
> Rolling 4 into headcount.
>
> Best,
> Dave

On Mon, 7 Sep 2026, Priya Raman <priya@example.com> wrote:
> Hi Ihor,
>
> Rolling 250 into budget.
>
> Best,
> Priya

Async standup

A backlog, jargon, a hiring freeze, a pronoun and a mail merge, with HR on cc. Output: 4 engineers, 16 points this sprint.

Subject: Async standup — no call today
Cc: HR <hr@example.com>

Hi team,

Hope you're well.
FYI, this replaces the 9am call.
Going forward, "let's action [ticket]" means "Adding [ticket] to the backlog".

Just to level-set, we have 4 engineers.
We have a hiring freeze on engineers.
Good news — we've added another engineer.

Let's action 3.
Let's action 5.
Let's action 8.

Just to level-set, points is 0.
Per my last email, while we still have a backlog:
> Picking up the next backlog item as ticket.
> Rolling it into points.

Circling back on "[engineers] engineers, [points] points this sprint".
Thanks!
Hope this helps.

Best,
Ihor

Truth-machine

Reads a number. 0 is printed once; any other number is printed forever by Dave, who keeps bumping the thread.

Subject: Quick yes/no — need an answer

Hi Dave,

Just to level-set, answer is 0.
Please advise.
Thanks in advance.

If answer is at zero:
> Circling back on answer.
That said:
> As discussed, Dave.

Best,
Ihor

On Tue, 8 Sep 2026, Dave Okonkwo <dave@example.com> wrote:
> Hi Ihor,
>
> Circling back on answer.
> Bumping this.
>
> Best,
> Dave

99 bottles of beer

The song as 99 unread emails. It begins 99 unread emails in the inbox, 99 unread emails. and ends Check again, and there are 99 unread emails in the inbox.

Subject: Re: Re: Re: inbox zero initiative

Hi all,

Just to level-set, we have 99 unread emails.

Per my last email, while we still have unread emails:
> If we're over 1 on emails:
> > Circling back on "[emails] unread emails in the inbox, [emails] unread emails.".
> That said:
> > Circling back on "1 unread email in the inbox, 1 unread email.".
> Quick flag: one email is now closed.
> If we're over 1 on it:
> > Circling back on "Archive one, mark it as read, [emails] unread emails in the inbox.".
> That said, if we're over 0 on it:
> > Circling back on "Archive one, mark it as read, 1 unread email in the inbox.".
> That said:
> > Circling back on "Archive one, mark it as read, inbox zero.".
> Circling back on "".

Circling back on "No unread emails in the inbox, no unread emails.".
Circling back on "Check again, and there are 99 unread emails in the inbox.".

Best,
Ihor

Cat program

Subject: Fwd: Fwd: Fwd: FW: read this

Hi all,

FYI, forwarding this exactly as I received it.

Just to level-set, letter is 0.
Reading between the lines.

Per my last email, while we're over -1 on letter:
> Let me spell it out.
> Reading between the lines.

Best,
Ihor

Brainfuck interpreter

Input is a brainfuck program, then !, then the program's own input. The program is held in two backlogs used as stacks (instructions ahead and behind), and the tape in two more. Cells wrap at 256, and reading past the end of input gives 0.

Subject: Re: Fwd: Brainfuck — can someone from IT take a look?

Hi IT,

FYI, send the Brainfuck program first, then a !, then whatever it should read.
FYI, the program sits in two backlogs, what's ahead and what's behind. So does the tape.

Just to level-set, letter is 0.
Reading between the lines.
Per my last email, while we're over -1 on letter:
> If we're at 33 on letter:
> > Per the attached, letter is now -1.
> That said:
> > Adding letter to the intake backlog.
> > Reading between the lines.

Per my last email, while we still have an intake backlog:
> Picking up the most urgent intake backlog item as instruction.
> Adding instruction to the ahead backlog.

Just to level-set, cell is 0.

Per my last email, while we still have an ahead backlog:
> Picking up the most urgent ahead backlog item as instruction.
> Adding instruction to the behind backlog.
> If we're at 43 on instruction:
> > Good news — we've added another cell.
> > If we're at 256 on cell:
> > > cell is off the table.
> That said, if we're at 45 on instruction:
> > Quick flag: one cell is now closed.
> > If we're at -1 on cell:
> > > Per the attached, cell is now 255.
> That said, if we're at 62 on instruction:
> > Adding cell to the left backlog.
> > cell is off the table.
> > If we still have a right backlog:
> > > Picking up the most urgent right backlog item as cell.
> That said, if we're at 60 on instruction:
> > Adding cell to the right backlog.
> > cell is off the table.
> > If we still have a left backlog:
> > > Picking up the most urgent left backlog item as cell.
> That said, if we're at 46 on instruction:
> > Let me spell cell out.
> That said, if we're at 44 on instruction:
> > cell is off the table.
> > Reading between the lines.
> > If we're at -1 on cell:
> > > cell is off the table.
> That said, if we're at 91 on instruction:
> > If cell is at zero:
> > > Just to level-set, we have 1 layers.
> > > Per my last email, while we still have layers:
> > > > Picking up the most urgent ahead backlog item as instruction.
> > > > Adding instruction to the behind backlog.
> > > > If we're at 91 on instruction:
> > > > > Good news — we've added another layer.
> > > > That said, if we're at 93 on instruction:
> > > > > Quick flag: one layer is now closed.
> That said, if we're at 93 on instruction:
> > If we still have cell:
> > > Picking up the most urgent behind backlog item as instruction.
> > > Adding instruction to the ahead backlog.
> > > Just to level-set, we have 1 layers.
> > > Per my last email, while we still have layers:
> > > > Picking up the most urgent behind backlog item as instruction.
> > > > Adding instruction to the ahead backlog.
> > > > If we're at 93 on instruction:
> > > > > Good news — we've added another layer.
> > > > That said, if we're at 91 on instruction:
> > > > > Quick flag: one layer is now closed.

Best,
IT

Implementation

The reference interpreter is written in Python 3 and has no dependencies. It also runs saved .eml files directly. It counts the leading > markers on each line to get the quote depth and matches the rest of the line against the statement table, after dropping FYI lines and expanding jargon. Quote depth then becomes a tree of blocks, much as Python turns indentation into INDENT and DEDENT tokens, and the interpreter walks that tree. Variables live in a stack of scopes, with the shared ones at the bottom and any offline ones above. Each reply to a reply-all runs on its own Python thread.

python3 regards.py examples/fizzbuzz.rgrd

Exit codes: 0 for a warm sign-off, 1 for a bare Regards,, 2 for an error in the program, 3 for a bug in the interpreter.

External resources