0123 is a foolish language, being so far in a draft state and primarily assembled at 2019-06-15, by User:Arseniiv. Hopefully it’s not a word for word copy of some other eso which I saw and then have forgotten.
0123 programs operate on associative memory with keys and values composed entirely of 0-, 1-, 2- and 3-tuples, and are denoted homoiconically by those same tuple expressions.
Syntax and semantics
Let ⟦code⟧ denote the semantics of the code.
- ⟦0⟧ = ()
- ⟦x 1⟧ = (⟦x⟧,); this is a 1-tuple and it doesn’t equal to ⟦x⟧
- ⟦x 2 y⟧ = (⟦x⟧, ⟦y⟧); 2 is right-associative: ⟦x 2 y 2 z⟧ = (⟦x⟧, (⟦y⟧, ⟦z⟧))
- ⟦3 x y z⟧ = (⟦x⟧, ⟦y⟧, ⟦z⟧)
Precedences: 1 is tighter than 3 than 2.
- A strong suggestion: dots instead of parentheses for grouping?
- . : .: :: .:: …, the more of them surround the outermost constructors
At runtime, there is an unbounded number of registers addressed by arbitrary values like 0, 011, 020, 0120, 02011201, 30010, …. All of them are initialized to 0. We denote value of the register indexed by N as *N.
Many values encode program code and can be evaluated at runtime, dynamically.
Operations and self-encoding
- No action if inside sequencing (at any depth). If used in eval for itself, also exits the current eval (“eval 0” acts as a return statement).
- c 2 c′
- Sequencing: do c then c′.
- 3 0 x y
- Set x to a literal value y.
- 3 (i 2 y) x c
- If i matches 1, 2, 3 set x to resp. 1st, 2nd, 3rd element of *y; if there is no such element, do c.
- If i matches 0, set x to **y.
- 3 (y 1) x c
- Append *y to x (viewed not as a cons list of 2s and 0); else if *x matches 3, do c.
- Namely, if *x = 0 then x := *y1; if *x = p 1 then x := p 2 *y; if *x = p 2 q then x := 3 p q *y; and if *x = 3 p q r then don’t change x and do c instead.
- x 1
- Evals *x as code, translating all addresses z to z 1. E. g. the code says to get from 01120, then (01120)1 is got from, instead.
- 3 (3 0 f y) x c
- Inputs to x according to specification f; if unsuccesful, place the error designator into y and do c.
- 3 (3 0 1 f y) x c
- Outputs *x according to specification f; if unsuccesful, place the error designator into y and do c.
- Undefined behavior.
Running the code
The code is evaluated as in
1 operation above. Arguments could be supplied, and the return value taken, from registers, but beware address translation.
- A single Unicode codepoint is inputted/outputted. OS errors aside, the only input failure is EOF, which is designated by 0, and there are no output failures. OS errors are platform-specific but aren’t designated by 0.
- Codepoints are represented as a1 2 a2 2 … 2 an where ⟦an⟧…⟦a2⟧⟦a1⟧ is the value of a codepoint in binary where ⟦0⟧ is 0 and ⟦01⟧ is 1. In other words, ⟦0⟧ = 0, ⟦x 1⟧ = ⟦x⟧ + 1, ⟦x 2 y⟧ = ⟦x⟧ + 2⟦y⟧.
- Undefined behavior.
Let’s do truth machine?..
"0" = 0x30 = 0b00110000 ~ 02020202012012020
"1" = 0x31 = 0b00110001 ~ 012020202012012020
330 0 (0 2 0) 0 -- input to 0 with potential errors in 020 30 0 0 -- on error, set 0 to 0 2 30 (0 2 0) -- set 020 to equality predicate below -- gets in (020)1, (0120)1, returns in 01 (3 (3000 2 (020)) 3000 -- if 020 has _3, copy to 3000, else (ugh)) -- it means that equality predicates are very hard in general, and I have a solid excuse for not completing the code -- someday...
Almost obvious it should be Turing-complete, but a detailed proof can be added someday.