"Gershwin: Stack-based, Concatenative Clojure" by Daniel Gregoire (2013)
Presenters detail vulnerability discovery and exploitation in "Gershwin: Stack-based, Concatenative Clojure" by Daniel Gregoire (2013).
Summary
### Overview In this talk presented at the Emerging Languages Camp, the speaker introduces Gershwin, an additive, experimental extension to Clojure that introduces a stack-based, concatenative programming model inspired by languages like Forth and Factor. The project was conceived to scratch two main exploration itches: investigating the concatenative paradigm and achieving a deeper understanding of Clojure's compiler internals. By building directly on top of Clojure, Gershwin enables developers to utilize point-free, data-flow-centric programming while retaining full access to Clojure’s hosted runtime, immutable collections, and concurrency constructs.
### Key Topics - **Concatenative & Stack-Based Paradigm**: Programs operate on an implicit data stack without explicit invocation syntax, parentheses, or formal argument parameters. Execution flows from data directly into operations. - **Vocabulary and Syntax of Gershwin**: Functions are referred to as 'words' defined using Forth-style colons (`:`). Anonymous functions are represented as 'quotations' with custom reader macro syntax. Parentheses are preserved exclusively to fall back to standard Clojure expressions. - **Factoring and Mental Model**: Rather than traditional variable-based abstractions, concatenative programming relies on vigorous factoring—breaking out arbitrary sequences of data and operations into newly named words. When stack shuffling becomes noisy, higher-order data-flow combinators help manage the flow. - **Data-Flow Combinators**: Borrowing directly from Factor, Gershwin avoids excessive low-level stack manipulation (such as `swap`, `dup`, `drop`, `nip`, `pick`, `over`) through combinators categorized into preserving (`dip`, `keep`), cleave (`cleave`, `tri`), spread (`spread`), and apply combinators. - **Clojure as an Extension Base**: Comparing language structure to human linguistic mastery (phonetics, vocabulary, discourse), Clojure provides sound micro-level guarantees around identity, state, values, and time, making it an ideal bedrock for high-level language experiments.
### Technical Details - **Compiler Modifications**: Gershwin compiles unmodified Clojure code and introduces additive changes to `LispReader`. It adds reader macros for quotations and Gershwin var resolution, extends the parser for `:` word definitions, and expands the pushback reader buffer to differentiate between keyword syntax and word definitions. At the compiler level, forms are translated into standard Clojure function invocations that either push values to the stack or execute words against it. - **Stack Implementation**: The stack implements Clojure's `IPersistentStack` interface backed under the hood by Clojure vectors. It is stored as a dynamic var in `gershwin.core`, allowing isolated stacks per thread to prevent race conditions during parallel processing operations (like `pmap`). - **Execution & Conditionals**: While many expressions read in reverse postfix compared to standard Clojure, conditionals such as `if` accept a boolean condition and two quotations (then/else branches) to delay evaluation until invoked.
### Takeaways Concatenative programming acts essentially like Clojure’s thread-macro (`->`) built natively into the core syntax, excelling in data-transformation pipelines, shell scripting pipelines, and UI composition. Rather than replacing Clojure, Gershwin demonstrates how hosted Lisps can serve as flexible, reliable platforms for exploring alternative programming paradigms without sacrificing access to existing ecosystem libraries and runtime semantics.
Related talks
Strange Loop Conference·41 min
Presenters detail vulnerability discovery and exploitation in "Concatenative programming and stack-based languages" by Douglas Creager.
Strange Loop Conference·40 min
Presenters detail vulnerability discovery and exploitation in "Babashka: a meta-circular Clojure interpreter for the command line" by Michiel Borkent.
Strange Loop Conference·34 min
Industry experts analyze emerging threats surrounding "Babel: An Untyped, Stack-based HLL" by Clayton Bauman (2013).


