A reversible programming language
One program.
Both directions.
call transforms state. uncall runs the same Janus program backward—no separate decoder, unsorter, or undo implementation.
Watch information move instead of disappear. The array becomes sorted while six trace bits remember the swaps. uncall reads those bits backward to restore the input.
Reversible sort
Sort forward.
Restore backward.
An ordinary sort forgets where values came from. This one leaves six branch bits behind—just enough information to retrace every swap.
sort.janus · editable
change it and run againArray and trace
inputCall sorts the array. Uncall follows the recorded decisions in reverse and reconstructs the input.
values[4]
edit initial statetrace[6]
branch historyv0↔v10emptyv1↔v20emptyv2↔v30emptyv0↔v10emptyv1↔v20emptyv0↔v10empty
Ready. Call the program forward.
The array changes into ascending order.
Each trace bit says whether one comparison swapped.
Reading those bits backward recreates the original order.
One-procedure codec
Write encode.
Uncall is decode.
Five additions turn plain text into coded text. Run the same procedure backward and those additions become subtractions.
encode.janus · editable
only encode()What uncall does:
message[4] -= shift
…
message[0] -= shift
Message
plain textThe code contains only encode(). Reverse execution supplies the decoding behavior.
HELLO
- H
72 - E
69 - L
76 - L
76 - O
79
Ready. Call encode. Then uncall the same procedure to decode.
Tree path codec
Climb to encode.
Descend to restore.
Climbing from a leaf stores each left or right turn. Reverse the loop and that path becomes directions back down the tree.
encode_path.janus · editable
one loop · both directionsWhere the leaf goes:
each upward step moves one left/right decision into path. Nothing has to be guessed on the way back.
Leaf and path
leaf selectedAt the root, the path holds the leaf's identity. Uncall consumes that path to choose each child.
path[3]
first step → last steppath[0]path[1]path[2]
Ready. Choose a leaf, then call the loop to encode its route.
Start from any of the four leaves.
Each step pushes one left/right decision into the path.
Uncall pops those decisions and returns to a leaf.