Est. 2001 Beginner

GPLZ.easy

The plain, line-oriented syntax of Gerson Kurz's Great Python Language Zoo (2001), a set of esoteric languages that share one interpreter and one internal code representation, so a .easy program can be run directly or translated into its stranger siblings.

Created by Gerson Kurz

Paradigm Procedural
Typing Dynamic (Python values; integers and strings)
First Appeared 2001
Latest Version GPLZ 1.4 (2001)

GPLZ.easy — usually written just .easy — is the “very plain and easy to understand” syntax of GPLZ, the Great Python Language Zoo, a collection of esoteric programming languages written in Python by the German programmer Gerson Kurz in 2001. GPLZ’s central idea is that every one of its languages compiles to the same internal tree of statement objects. A program written in one syntax can therefore be run directly or translated into another. .easy is the one meant to be readable. The rest of the zoo includes a recipe language, a whitespace language, a Gertrude Stein pastiche and a program encoded as a tree of directories on disk.

History & Origins

Gerson Kurz ran p-nand-q.com, a personal site full of obfuscation exercises, Windows utilities and esoteric programming languages. By the time GPLZ appeared he had already written several esolangs. His site describes one of them, Sorted!, as the winner of an “Award for Esoteric Language of the Year 2000”.

GPLZ grew out of a simple engineering idea. Once you have a shared intermediate representation, adding a new “input method” means writing only a parser and a pretty-printer. .easy came first, and every later syntax was built on its statement model. The archive still available from Kurz’s site gives a fairly precise date:

FileTimestamp in archive
fibonacci.easy13 March 2001
easy.py (the .easy parser)19 March 2001
chef.py16 April 2001
gertrude.py, gplz.py5 May 2001
yacuabll.py (latest file)6 May 2001

The Wayback Machine first captured the GPLZ page on 22 April 2001. By then .easy, ((o)), ". " and ./ were in place and CHEF had just been added. The examples run from a C:\Python20\gplz> prompt, which places the work on Python 2.0 under Windows. The page also warned that the ./ directory syntax “currently works only in Win32”. The encyclopedia’s master list gives 1995, but nothing about GPLZ dates from before 2001. 1995 also predates both Python 2.0 and Kurz’s site, whose copyright line begins in 2000.

Design Philosophy

GPLZ is a joke with a real architecture underneath it. Each syntax is a Python class that turns source text into objects from a shared statements module (AssignmentStatement, WhileDoStatement, PrintStatement and so on), and can write such a tree back out. The driver picks the language from the file extension:

1
2
C:\Python20\gplz> gplz.py fibonacci.easy              (run it)
C:\Python20\gplz> gplz.py fibonacci.easy fibonacci./  (translate it into a directory tree)

Within that scheme .easy is the human-facing language, the one you would actually write a program in before converting it to something absurd. Its own page sums up each explanation with a single word: “Easy.”

The Language

Grammar

Kurz published .easy as an EBNF grammar on its page; the easy.py docstring carries the same grammar, except that its BUILTIN line omits 'do'. Abridged here (the NAME, CHAR, DIGIT, FUNCCALL, DECINT and VARIABLE rules are left out):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
SOURCE      = STATEMENT {STATEMENT}.
STATEMENT   = CODE ['.'|'\n'].
CODE        = FUNCTION ':' DESCRIPTION.
FUNCTION    = FUNCNAME '(' [ARG {',' ARG}] ')'.
FUNCNAME    = NAME | BUILTIN.
BUILTIN     = 'if','while','until','do'...
DESCRIPTION = CODEM {'.' CODEM}
CODEM       = ASSIGNMENT | FUNCCALL | PRINT | EXPRESSION.
PRINT       = '<<' EXPRESSION
ASSIGNMENT  = VARIABLE ('='|'+='|'-='|'*='|'/='|'%='|'|='|'&=') EXPRESSION.
EXPRESSION  = OP0 {('<'|'=='|'>'|'<='|'>='|'!=') OP0}.
OP0         = OP1 {('+'|'-')OP1}.
OP1         = OP2 {('*'|'/'|'%')OP2}.
OP2         = OP3 {('|')OP3}.
OP3         = OP4 {('&')OP4}.
OP4         = ['!'] ('(' EXPRESSION ')' | FUNCCALL | VARIABLE | LITERAL).
LITERAL     = DECINT.

Every line has the form head : body. The body is a sequence of small statements separated by full stops. The head is either a user-defined function such as f(x) or one of the built-in control words. The built-ins take no parenthesised arguments; “rather the first element of the sequence is treated as argument.” So while:c<20.<<j means “while c<20, print j”.

Hello, World

1
2
# HELLO, WORLD in .easy
do:<<"Hello, World"

do simply runs its body, and << prints. The grammar only lists decimal integers as literals, but the parser also accepts single- or double-quoted strings, which is what makes this example work.

Fibonacci

The example from the GPLZ distribution prints the first 20 Fibonacci numbers:

1
2
3
4
# FIBONACCI in .easy
f(x):i=x.j=x.c=x-x
do:f(1)
while:c<20.<<j.h=j+i.j=i.i=h.c+=1

Line one defines f(x), which sets i and j to x and c to zero (written x-x, as there is no other way to get a zero from x). Line two calls f(1). Line three loops while c<20, printing j and stepping the sequence. A program is a flat list of these lines, run top to bottom. A function definition just registers the function and produces no output when it is reached.

Built-in control words

The page names only if, while, until and do, followed by “…”. The parser in the 1.4 archive actually registers eight:

Built-inArguments taken from the bodyMeaning in the archived source
do0Run the body
while1Repeat the rest while the first element is true
until1Run the first element, then repeat while the rest evaluates true
if1Run the rest if the first element is true
while-do-unless2Loop while the first is true and the second is false
if-then-else2Choose between the second element and the rest
if-then-unless2Run the rest if the first is true and the second false
if-then-given2Run the rest if both the first and second are true

Semantics worth knowing

Running the archived 1.4 source (after a mechanical port to Python 3) shows some behaviour the page does not mention:

  • Variables are global and start at zero. Only a function’s parameters are local, so the i, j and c that f(x) assigns in the Fibonacci example are visible to the while line that follows.
  • Operators are Python’s. | and & are Python’s bitwise operators (6|3 is 7, 6&3 is 2), and ! is logical not. Under the Python 2 interpreter GPLZ was written for, / on two integers is integer division.
  • A colon splits the line. Each line is split on : and must yield exactly two parts, so a string literal containing a colon is a syntax error.
  • Translation is one-way. .easy works as a translation source but not as a target: the Easy class has no dump method for the shared DumpToFile path to call. In 1.4 the CHEF writer also returns an empty string. The bundled examples are translated from .easy, not into it.
  • The if family is broken in the shipped code. IfStatement, IfThenElseStatement, IfThenUnlessStatement and IfThenProvidedStatement test the name args instead of self.args, so reaching any of them raises a NameError. do, while, until and while-do-unless work, and they are all the published examples use.

Evolution

.easy itself does not seem to have changed after its first appearance. The grammar on the May 2001 page is identical to the one on the page today. The rest of GPLZ grew around it over a few weeks in spring 2001:

VersionAdded syntax
initial.easy, .((o)), ". " (whitespace), ./ (directory tree)
1.1.chef (an implementation of the CHEF recipe language)
1.2.: (Dot Colon)
1.3.gertrude (Gertrude Stein Memorial Language)
1.4.yacuabll (“Yet Another Completely Useless And Badly Labelled Language”)

The driver also accepts a ninth format, .pickle, which the web pages never describe and only the driver’s usage message lists. It saves or loads the internal statement tree with Python’s cPickle. It is the zoo’s real intermediate representation, made visible.

Current Relevance

GPLZ has not been developed since 2001. The zip on p-nand-q.com is still the version 1.4 archive, with Python 2 print statements and has_key throughout, plus cPickle, so it will not run on a modern Python 3 interpreter without porting. The site notes that its pages were migrated from the original p-nand-q.com, last updated in 2015, and “preserved exactly as it was”. No official or community Docker image exists.

Getting .easy running again is not much work. For this article the .easy parser and the shared statement module were ported mechanically to Python 3 (print calls, in instead of has_key, string.ascii_letters). After that, both the Hello World and the Fibonacci programs ran as documented, the latter printing 1 through 6765.

Why It Matters

.easy is a small, forgettable language, and that is the point: it is the plain base layer of a system built to show that surface syntax is the least important part of a language. GPLZ routes every syntax through a single shared tree of statements, and in practice a program starts life in readable .easy and is then translated into something stranger. A Fibonacci program that can be stored as nested folders on a Windows drive is a joke. It also shows quite clearly what an abstract syntax tree is for.

Timeline

2001
In March, Gerson Kurz writes the first .easy programs and its parser; the surviving archive dates fibonacci.easy to 13 March and easy.py to 19 March 2001
2001
The earliest Wayback Machine capture of the GPLZ page on p-nand-q.com (22 April) lists .easy alongside ((o)), the whitespace syntax '. ', the directory-tree syntax './' and CHEF, offered as an 11,494-byte zip
2001
The dedicated .easy page, with its EBNF grammar and Hello World and Fibonacci examples, is first captured by the Wayback Machine on 26 May
2001
By 4 June the page announces GPLZ 1.4, adding the Dot Colon (1.2), Gertrude Stein Memorial Language (1.3) and YACUABLL (1.4) syntaxes; the latest file in the downloadable archive is dated 6 May 2001
2002
During a reorganisation of p-nand-q.com, the GPLZ pages reappear under the site's /e/ section (first captured 30 August 2002)
2015
The original p-nand-q.com site receives its last update; the GPLZ pages and the 1.4 zip were later carried over unchanged to the redesigned site

Notable Uses & Legacy

GPLZ reference programs

The GPLZ archive's Hello World and Fibonacci programs are written in .easy and serve as the source that the interpreter translates into the zoo's other syntaxes, including the './' form that encodes a program as a tree of directories

p-nand-q.com esoteric language collection

GPLZ, with .easy as its readable entry point, sits alongside Kurz's other esoteric languages such as Java2K, Sorted!, SMITH# and TMMLPTEALPAITAFNFAL on his personal site

Running Today

Run examples using the official Docker image:

docker pull
Last updated: