!~ATH INTERPRETER

an esoteric language where everything is about death
inspired by Homestuck's fictional ~ATH
CODE:
INPUT for HEED(), one line per call:
INPUT for SCRY(VOID), one box per call):
OUTPUT:
EXAMPLE PROGRAMS:
DOWNLOAD: Run !~ATH programs locally with the Python interpreter (found on GitHub). It includes process, connection, watcher entities and file I/O.

LANGUAGE REFERENCE (full spec)

!~ATH (pronounced "until death") is an esoteric programming language where all control flow is predicated on waiting for things to die. Everything is about death. Loops wait for entities to die. Computation happens in death callbacks. The language is deliberately inconvenient.

Inspired by the fictional ~ATH language from Homestuck.

ENTITIES

Entities are mortal things that can be waited upon. Each entity is either alive or dead. Create entities with import:

import timer T(1s);        // dies after 1 second
import timer T2(500ms);    // dies after 500 milliseconds

import process P("cmd"); // dies when process exits [NOT IN BROWSER]
import connection C("host", 80); // dies when connection closes [NOT IN BROWSER]
import watcher W("file.txt"); // dies when file is deleted [NOT IN BROWSER]
import watcher Lib("lib.~ATH"); // loads .~ATH as module [NOT IN BROWSER]

THIS is an implicit entity representing the program itself. Kill entities manually with .DIE(). The program ends when THIS.DIE(); is called.

~ATH LOOPS

The fundamental control structure. Waits for an entity to die, then runs the EXECUTE clause:

import timer T(1s);
~ATH(T) {
} EXECUTE(UTTER("Timer died!"));
THIS.DIE();

Combine entities with && (both must die), || (either dies), or ! (dies immediately when created):

~ATH(T1 && T2) { } EXECUTE(...);  // wait for both
~ATH(T1 || T2) { } EXECUTE(...);  // wait for either
~ATH(!T) { } EXECUTE(...);        // runs immediately

BIFURCATION

Split execution into concurrent branches:

bifurcate THIS[LEFT, RIGHT];

~ATH(LEFT) {
    // code for left branch
} EXECUTE(VOID);

~ATH(RIGHT) {
    // code for right branch
} EXECUTE(VOID);

[LEFT, RIGHT].DIE();

VARIABLES

BIRTH x WITH 5;           // mutable variable
ENTOMB PI WITH 3.14159;   // constant (immutable)
x = x + 1;                // reassignment

DATA TYPES

42, -7                    // INTEGER
3.14, -0.5                // FLOAT
"hello\nworld"            // STRING (escapes: \\ \" \n \t)
ALIVE, DEAD               // BOOLEAN (truthy/falsy)
VOID                      // absence of value
[1, 2, 3]                 // ARRAY
{name: "Karkat", age: 6}  // MAP

OPERATORS

+ - * / %                     // arithmetic (/ is integer div for ints)
& | ^ ~ << >>                 // bitwise (AND, OR, XOR, NOT, shifts)
== != < > <= >=               // comparison
AND OR NOT                    // logical (short-circuit)
arr[0]  map["key"]  map.key   // indexing

CONTROL FLOW

SHOULD condition {
    // if truthy
} LEST {
    // else
}

No loops in the expression language. Use ~ATH for iteration:

RITE countdown(n) {
    SHOULD n > 0 {
        UTTER(n);
        import timer T(1s);
        ~ATH(T) { } EXECUTE(countdown(n - 1));
    }
}
countdown(5);
THIS.DIE();

FUNCTIONS (RITES)

RITE add(a, b) {
    BEQUEATH a + b;       // return value
}
BIRTH sum WITH add(2, 3);

ERROR HANDLING

ATTEMPT {
    BIRTH x WITH PARSE_INT("bad");
} SALVAGE error {
    UTTER("Error: " + error);
}

CONDEMN "Something went wrong";  // throw error

BUILT-IN RITES

I/O:

UTTER("Hello", x);        // print (space-separated, newline appended)
BIRTH line WITH HEED();   // read line from input
BIRTH s WITH SCRY(VOID);  // read STDIN until EOF. in the Python interpreter, can also read files with SCRY("filename")

INSCRIBE("file.txt", s) // write file [NOT IN BROWSER]

Type operations:

TYPEOF(x)                 // "INTEGER", "FLOAT", "STRING", etc.
LENGTH(arr), LENGTH(str)  // length of array or string
PARSE_INT("42")           // string to integer
PARSE_FLOAT("3.14")       // string to float
STRING(42)                // value to string
INT(3.7)                  // float to integer (truncates)
FLOAT(42)                 // integer to float
CHAR(65), CODE("A")       // int to char / char to int code
BIN(10), HEX(255)         // int to binary/hex string

Array operations:

APPEND(arr, val)          // add to end (returns new array)
PREPEND(arr, val)         // add to start
SLICE(arr, start, end)    // subsequence
FIRST(arr), LAST(arr)     // first/last element
CONCAT(arr1, arr2)        // concatenate arrays

Map operations:

KEYS(map), VALUES(map)    // get keys/values as arrays
HAS(map, key)             // check if key exists
SET(map, key, val)        // set key (returns new map)
DELETE(map, key)          // remove key

String operations:

SPLIT("a,b,c", ",")       // split to array
JOIN(arr, ",")            // join array to string
SUBSTRING(s, start, end)  // extract substring
UPPERCASE(s), LOWERCASE(s), TRIM(s)
REPLACE(s, old, new)      // replace all occurrences

Utility:

RANDOM()                  // random float 0 to 1
RANDOM_INT(min, max)      // random integer in range
TIME()                    // Unix timestamp in ms
© 2026 Robin. Licensed under the GNU GPL v2.