s-expression-alternatives

star 2

Alternative syntaxes for Lisp-family languages that reduce or eliminate parentheses while preserving homoiconicity and extensibility. Covers sweet-expressions (curly-infix, neoteric, indentation-based), i-expressions (SRFI-49 indentation-sensitive syntax), o-expressions (operator-based AST with currying juxtaposition), and Liso (Racket implementation of o-expressions). Use when designing alternative Lisp syntaxes, building reader macros for readable code, evaluating tradeoffs between parentheses and other grouping mechanisms, or implementing custom s-expression variants.

tangledgroup By tangledgroup schedule Updated 6/11/2026

name: s-expression-alternatives description: Alternative syntaxes for Lisp-family languages that reduce or eliminate parentheses while preserving homoiconicity and extensibility. Covers sweet-expressions (curly-infix, neoteric, indentation-based), i-expressions (SRFI-49 indentation-sensitive syntax), o-expressions (operator-based AST with currying juxtaposition), and Liso (Racket implementation of o-expressions). Use when designing alternative Lisp syntaxes, building reader macros for readable code, evaluating tradeoffs between parentheses and other grouping mechanisms, or implementing custom s-expression variants.

S-Expression Alternatives

Overview

S-expressions are powerful but verbose. Four notable alternatives reduce parentheses while attempting to preserve the properties that make Lisp syntax extensible: homoiconicity, uniformity, and simplicity. Each takes a different approach:

Approach Mechanism AST Model Dialect Support
Sweet-expressions Abbreviations on top of s-expressions S-expression (unchanged) Any Lisp with reader extension
I-expressions Indentation replaces parentheses S-expression (translated) Scheme, Guile
O-expressions Operators + juxtaposition + explicit lists Apply/Op/List/Seq nodes Theoretical (no Lisp-specific bias)
Liso O-expressions implemented for Racket S-expression (translated) Racket only

When to Use

  • Designing a new Lisp dialect with improved readability
  • Building reader macros that translate alternative syntax to s-expressions
  • Evaluating tradeoffs between parentheses, indentation, and operator-based grouping
  • Understanding why no s-expression alternative has achieved widespread adoption
  • Implementing custom syntax layers for existing Lisp projects

Core Concepts

The Problem with S-Expressions

S-expressions use a single data structure (nested lists) for both code and data. This homoiconicity is their greatest strength but also their primary weakness:

  1. Parenthesis overload — Every form needs ( ... ), creating visual noise
  2. Semantic conflation(f g) appears twice in (lambda (f g) (f g)) with different meanings
  3. Nesting collapse incentive — To save parentheses, languages flatten structure (e.g., Clojure's let [x 0 y 1])
  4. No apply/list distinction — Function calls and data lists use identical syntax

Three Strategies

Each alternative attacks the parenthesis problem differently:

Strategy 1: Abbreviate (Sweet-expressions) Add syntactic sugar on top of s-expressions. Curly braces for infix, f(...) for function calls, indentation for automatic grouping. The Lisp still sees s-expressions. Works with any dialect but adds reader complexity.

Strategy 2: Indent (I-expressions) Use whitespace as the grouping mechanism instead of parentheses. INDENT/DEDENT tokens replace ( and ). Purely syntactic — no semantic constructs. Mixes freely with s-expressions for dense data.

Strategy 3: Restructure (O-expressions) Define a new AST with separate Apply, List, Op, and Seq nodes. Use operator syntax and currying juxtaposition. Does not translate to s-expressions directly — the node types carry semantic information that s-expressions erase.

Design Principles (From O-Expressions)

Any viable alternative should satisfy:

  1. Context invariance — Tokens behave identically everywhere
  2. Ubiquity — All syntax rules appear in any moderately sized file
  3. Genericity — Built-in and user-defined constructs are indistinguishable
  4. AST simplicity — The data structure must be easy to manipulate programmatically

Tradeoffs

Aspect S-Expressions Sweet I-Exprs O-Exprs
Parentheses Many Fewer None (indent) Minimal
Homoiconicity Perfect Via translation Via translation Native (new AST)
Dialect support Universal Any with reader Scheme/Guile Theoretical
Macro compatibility Native Translated Translated Racket macros (Liso)
Learning curve Low Incremental Moderate Higher
Extensibility Maximum High Medium High (aggregative ops)

Advanced Topics

  • Sweet-expressions — Three-layer approach: curly-infix, neoteric, and indentation-based parens. See reference/01-sweet-expressions.md
  • I-expressions — SRFI-49 specification with INDENT/DEDENT mechanics and mixed I/S usage. See reference/02-i-expressions.md
  • O-expressions — Operator-based AST design with currying juxtaposition and aggregative operators. See reference/03-o-expressions.md
  • Liso — Racket implementation with fixed operator priority, macro support, and syntax aliases. See reference/04-liso.md
Install via CLI
npx skills add https://github.com/tangledgroup/tangled-skills --skill s-expression-alternatives
Repository Details
star Stars 2
call_split Forks 0
navigation Branch main
article Path SKILL.md
More from Creator
tangledgroup
tangledgroup Explore all skills →