Poop (pstron)

From Esolang
Jump to navigation Jump to search

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.

Print

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 ... qooq in which they are defined. A parameter defined in an inner poop shadows any parameter of the same name from an outer poop.
  • 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/.

See also

External resources