Poop (pstron)
Poop is a functional esoteric programming language created by pstron, where everything is a poop and computation happens by pooping into other poops. It is based on lambda calculus with a minimal syntax centered around toilet humor metaphors.
The language is implemented as an interpreter written in Haskell. Also, an online web-based interpreter for Poop is available at pstron.github.io/poop/, allowing users to try the language directly in a web browser without installing the Haskell implementation.
Overview
Poop has no assignments, no mutable objects, and no traditional control structures. Instead, programs are built from three core primitives: poop (lambda abstraction), pooping (function application), and macro definitions. Execution proceeds via substitution, expanding macros and replacing parameters until a result is produced. The language uses lazy evaluation (call-by-name) strategy.
Syntax
Tokens and Whitespace
Tokens must be separated by whitespace (spaces, tabs, or newlines).
Escape sequences
Throughout the language, backslash `\` introduces escape sequences in textual content:
\n→ newline character\t→ tab character\r→ carriage return\s→ space character\\→ literal backslash
Escape sequences are processed during tokenization, before any other interpretation.
Comments
- Single‐line:
// comment - Multi‐line:
/* comment */
Identifiers
- Variable names: lowercase letters and underscores (
[a-z_]+). - Macro names: any identifier that is not a valid variable name; commonly written in PascalCase. May include digits and symbols.
Literals
Literals are enclosed between Po and op. The content between them is taken literally, with escape sequences interpreted.
Poop→ an empty string (printing it produces no output).Popoopop→ the string "poop" (used to avoid keyword interpretation).PoHello\sWorld\nop→ the string "Hello World" (Contains a space and newline)
Literals are never expanded as macros or treated as keywords.
Primitives
poop (abstraction)
poop ⟨param⟩ poops ⟨body⟩ qooq
Creates a lambda abstraction. When applied, every occurrence of ⟨param⟩ in ⟨body⟩ is replaced with the argument.
pooping (application)
pooping ⟨expr₁⟩ poopy ⟨expr₂⟩ qooq
Applies ⟨expr₂⟩ to ⟨expr₁⟩. If ⟨expr₁⟩ is not a poop abstraction, the pooping expression remains unevaluated until the target becomes a poop.
Macro definition
poop ⟨name⟩ is ⟨content⟩ qooq
Defines ⟨name⟩ as a macro that expands to ⟨content⟩. Macros are non‑recursive and are expanded during execution.
Built‑in macros
Input
When encountered, the interpreter pauses and reads one line from the user. The line is parsed as Poop code and replaces the Input macro in the program. This allows the user to supply both data and code dynamically.
pooping Print poopy ⟨x⟩ qooq
1. Evaluation: ⟨x⟩ is fully evaluated. 2. String Conversion: The result is converted to a string (multiple adjacent tokens are concatenated without added spaces). 3. Output: The result is written to standard output. 4. Return value: ⟨x⟩ itself is returned (behaving as the identity function with a side effect).
Evaluation Model
Scope and evaluation
- Lexical scope: parameter names are only valid inside the
poops ... qooqin which they are defined. A parameter defined in an innerpoopshadows any parameter of the same name from an outerpoop. - Evaluation strategy: The language uses lazy evaluation (call-by-name). Arguments are substituted into the function body before they are reduced, and are only evaluated when their value is needed. This allows functions to ignore unused arguments and ensures predictable ordering of side-effects like
Print.
Examples
Hello World
// A example Hello World poop program
// Define a macro Greet
poop Greet is
poop name poops
PoHello\sop name
qooq
qooq
// Execute: Print (Greet "World")
pooping Print poopy
pooping Greet poopy
PoWorldop
qooq
qooq
Church numerals
// 0: f -> x -> x
poop 0 is
poop f poops poop x poops x qooq qooq
qooq
// Succ: successor function, n -> f -> x -> f (n f x)
poop Succ is
poop n poops
poop f poops
poop x poops
pooping f poopy
pooping
pooping n poopy f qooq
poopy x
qooq
qooq
qooq
qooq
qooq
qooq
// >: Print a Church numeral as repeated "poop"s
poop > is
poop num poops
pooping
pooping num poopy Print qooq
poopy Popoop\nop
qooq
qooq
qooq
Computational class
Poop is Turing complete because it implements the untyped lambda calculus with lazy evaluation (call-by-name) and macro expansion. Although macros themselves are non‑recursive, recursion is achieved through fixed‑point combinators such as the Y combinator. Church numerals, Boolean logic, and all lambda‑calculus primitives can be expressed, confirming the language’s Turing completeness.
Implementation
The reference implementation is written in Haskell and available on GitHub: pstron/poop. The project is dual‑licensed under the MIT License and a custom "The Poop License" that disclaims all liability.
In addition to the Haskell implementation, a web-based online interpreter is available at pstron.github.io/poop/.