What a polyglot is
A polyglot program is a single source file that is valid in more than one programming language. Feed the same file to two different interpreters or compilers, and each one accepts it and runs it. Often the goal is for the file to produce the same output in each language; sometimes it is to produce different outputs, with each language “seeing” a different program inside the same text.
The term comes from the word for a person who speaks many languages. A polyglot program is, in a sense, fluent in several at once. It is not a practical technique for everyday software. It is a puzzle, a showcase of how well you understand each language’s grammar, and a source of a particular kind of pleasure.
The key trick: one language’s code is another’s comment
The central idea behind most polyglots is that text one language treats as code can be a comment, a string or something ignored in another. If you can arrange for each language to skip the parts meant for the others, then each sees only its own program.
Common building blocks include:
- Different comment markers. One language might start comments with one symbol, another with a different symbol. A line can be a comment in one and executable in the other.
- Strings and literals. Text inside a string literal is ignored as code. A language can be made to treat the other’s program as inert data.
- Tolerant syntax. Some languages ignore unrecognized text, or treat certain constructs as no-ops. Gaps like that offer room to hide other code.
- Line-based quirks. Differences in how languages treat the first line, indentation, or line endings can decide which parts each language reads.
- Expressions valid in both. Sometimes the same expression means the same thing in both languages, which is the simplest case.
Because every language has its own rules, a polyglot is usually built by studying the grammars of the two languages and finding where their allowed syntax overlaps.
A conceptual example
Suppose language A ignores everything after a certain marker to the end of the line, and language B uses a different marker. Write a line where A’s program comes first, then B’s marker, then B’s program. Language A runs its own program and ignores the rest. Language B, however, sees the first part as a comment only if the first part begins with its own comment marker. So the author arranges the line so that the beginning of the line is valid, harmless code for B and a comment opener for A, and the reverse for the remainder.
The actual details depend entirely on the languages chosen, so treat this as a description of the reasoning rather than a recipe. The working method is always the same: decide what each language should see, then craft the text so that every other part is neutralized.
Why grid languages are good polyglot partners
Esoteric languages are fertile ground. Many ignore characters they do not recognize, or treat them as harmless. A language like Brainfuck commands only eight characters and treats everything else as a comment, which means almost any text can be hidden inside a Brainfuck program, and a Brainfuck program can be tucked inside almost any other file.
Grid languages have their own advantages. In Befunge the pointer moves in two dimensions, so a polyglot can place one language’s code on the first line and arrange for the pointer to skip it, jumping over cells with the trampoline instruction or turning away with an arrow. Conversely, the first line of the file can be the part that the other language reads, while the grid language’s pointer leaves it immediately. Space characters do nothing, so there is plenty of room for padding. The way a source file is loaded into the grid also affects what the pointer sees, so details of program loading matter.
Another interesting area is a polyglot between two esoteric languages, where both have minimal instruction sets. Because the vocabularies are small, collisions are frequent, and finding characters that are useful in both takes careful thought.
Types of polyglot challenge
Challenges vary, and the rules should be spelled out clearly:
- Same output in every language. The most common version. Each language must print the same thing.
- Different output per language. The program prints something specific to each language it is run in.
- N languages. The number of languages becomes the score. Adding one more is much harder than the first two, because every addition has to be compatible with all the previous ones.
- Polyglot with a constraint. For instance, a polyglot that is also a palindromic program, or one that must fit within a size limit.
Details such as language versions, interpreter flags and file names can change whether a polyglot works, so a careful challenge states them. A program that works with one interpreter version may fail with another.
How to build one
- Pick the languages. Choose two to start, and ideally ones with permissive syntax or distinct comment styles.
- Write the small program in each. Keep the task trivial, such as printing a short message.
- Find the overlap. List what each language ignores, and what it requires at the start of the file.
- Interleave. Arrange the text so that each language sees its program as code and the other as comment or data.
- Test each independently. Run the file with every interpreter. Do not assume it works because it looks right.
- Add a language only after the earlier ones are stable. Every new language can break the previous ones.
Limits and honest expectations
Polyglots are brittle. A tiny edit can break one of the languages, and the resulting source tends to be hard to maintain. They are best treated as a puzzle form. They sit alongside obfuscated code as a way to show off mastery of syntax, and as with other playful forms, the main value is learning how languages parse their input.
If you try one, keep notes about which characters do what for each language. It makes debugging far easier, and the notes themselves are a useful compact reference to the grammars you studied.