Exechars
Exechars is a golfing language. It is based on Execode, with much of the features inherited from it.
Paradigm(s) | functional |
---|---|
Designed by | User:iddi01 |
Appeared in | 2024 |
Memory system | stack-based/deque-based |
Dimensions | one-dimensional |
Computational class | Turing complete |
Reference implementation | Original implementation |
Influenced by | Execode |
File extension(s) | .ес |
Exechars is not a pure golfing language, since Execode was designed for a balance of ease for several things. But its focus on functions (which is the only form of control flow in Exechars) gives it advantage over the other golfing languages for more complex programs, as functions means reusable code. Also, its programs are very compact for its simplicity (only 12 commands excluding I/O and termination), and it can do stuff that are impossible for many other esolangs with its unique features.
Exechars can also be treated as a more complete version of Execode, with many of the unintended restrictions fixed by features added in Exechars.
The name Exechars refers to its similarity to Execode, and the fact that its commands are individual characters instead of lines like in Execode.
Syntax
Numbers and ID
In Exechars, anything except the valid commands are treated as number literals, and numbers are in hexadecimal.
The "names" of variables, stacks/deques, and functions must be numbers, which will be referred to as IDs. If a v is appended to the number, it instead loads the value of variable with ID x as the number.
The IDs of variables, stacks, and functions are non-overlapping, so you can for example have both a variable and a stack with ID 135.
The special EOF code is 65535 (ffff
in hexadecimal), when popping from an empty stack or reading EOF from input, it is given.
A number ends with a valid command, in case the end of a program, t
.
Commands
A valid command must be followed by a number, that even includes t
(at least in the original implementation). The 2-number commands such as ?
and ^
counts as 2 commands, so for conditionals and repeats (note that the repeat counts as one command!) a function is needed for them.
Defining
Unlike Execode, there's usually no need to define a variable or stack before usage, but instead they're automatically defined (assuming they're previously 0/empty) when using them. Sometimes a command do require a variable to be defined first, like comparison, in that case you can define it using +x-x
.
Command list
The symbols and letters below are valid commands. Any 'x' in this list refers to a number.
Command | Description |
+x
|
increases the variable with ID x by 1 |
-x
|
decreases the variable with ID x by 1 |
(x
|
begin definition of a function, ends with ) , the code in between are not executed right away, but instead executes when the function ID x is called.
|
^x>y
|
push variable x to stack y |
*x>y
|
pops one item from stack x to variable y |
&x
|
reverses stack x, so it's valid to consider the stacks in Exechars as deques |
/x
|
call function x |
?x=y
|
skip the next instruction if variable x and y are not equal |
?x!y
|
skip the next instruction if variable x and y are equal |
?x<y
|
skip the next instruction if variable x > y |
ix
|
reads one value from input and sets variable x to it |
ox
|
output variable x as character |
nx
|
output variable x as number (without newline, unlike Execode) |
sx
|
output stack x at a string |
lx
|
output stack x as individual numbers |
rx
|
the next command will repeat x times |
t
|
terminates the program, some interpreters force this |
Examples
Most of the current examples listed here are not optimal.
Truth machine
i0+1-1(0n0?0!1/0)/0t
Hello, World!
r48+0o0r65+1o1r6c+2o2o2r6f+3o3r2c+4o4r20+5o5r57+6o6o3r72+7o7o2r64+8o8+5o5t
A second way using input (input 72, 101, 108, 108, 111, 44, 32, 87, 111, 114, 108, 100, 33):
(0i0?0!1/1)(1^0>0/0)rffff+1/0s0t
A third way using a stack:
(0^2>0)r48+0^0>0r65+1^1>0r6c+2r2/0r6f+3^3>0r2c+4^4>0r20+5^5>0r57+6^6>0^3>0r72+7^7>0^2>0r64+8^8>0+5^5>0s0t
Addition-only calculator *
i0i1r2b+ar3d+b+10-10(0+3?3<1/0)(1+4?4!0/1)(2+2-0?0!10/2)(3+2-1?1!10/3)/0/1/2/3n4oan3obn2t
A much shorter way, not possible with Execode:
i0i1r2b+ar3d+br0v+2r1v+2n0oan1obn2t
Modify it trivially to get a subtraction-only calculator:
i0i1r2d+ar3d+b+10-10(0+3?3<1/0)(1+4?4!0/1)(2+2-0?0!10/2)(3-2-1?1!10/3)/0/1/2/3n4oan3obn2t
The shorter way:
i0i1r2d+ar3d+br0v+2r1v-2n0oan1obn2t
Fibonacci sequence
+0+1+a-ara+b(0+2+3-0?0!a/0)(1+2+4-1?1!a/1)(2+0-4?4!a/2)(3+1-2?2!a/3)(4/0/1/2/3n1ob/4)n1obn1ob/4t
Shorter way:
+0+1ra+3(0r0v+2r1v+2r0v-0r1v+0r1v-1r2v+1r2v-2n1o3/0)n0o3n1o3/0t
Looping counter
ra+1+2-2+3(0n2-3+4?3!2/0?3=2/1)(1-4+3?4!2/1)(2/0o1+3/2)/2t
Deadfish interpreter
(64-0)(69+0)(6fn0)(73r0v+5-5r0v+6r5v/2r5v-5r6v-6)(2r6v+0)(0i2?2=at0/2v?0=3/1?0=4+0/0)(1r100-0)r100+3-4rffff+a+0-0/0t
Bitwise Cyclic Tag interpreter **
+0^0>1(0l1*0>0&0^0>0&0?0=b/a/0v)(1*0>1&0^1>0&0*1>2^2>1?2!b/3/0)(3&1^1>1&1)(2i4^4>0?4!c/2)(a*1>a)+b-brffff+c/2*0>a&0/0t
*
Input two numbers, such as 16,35
**
Input the sequence of bits separated by commas as the program, the initial data is always 1
Computational class
Like in Execode, the Bitwise Cyclic Tag interpreter above proves Exechars Turing-complete, since storage is unbounded. The fixed size reading issue is also fixed with the EOF code.
Techniques
To truly bring out the potential of Exechars, you need to know how the commands can be combined to achieve various things.
Functions
As the only form of control flow, functions are very important. If something seems hard to solve, maybe you just need to create more functions.
Conditional function call
?0<1^0>2
How to fix that buggy code? Easy! Just create a new function:
(0^0>2)?0<1/0
Switch statement
Use /xv
and switch statements are so easy:
(0...)(1...)(2...)(xiy/yv)
See Deadfish interpreter above as an example.
While loop
To make a loop like those in bf, just do something like this:
+z-z(x...?y!z/x)
Variables
Variable IDing techniques
For longer programs, it's best to ID the variables (actually constants) set to ASCII values, and those that are actually used (the actual variables) using different schemes.
Variable duplication
The fastest way to duplicate variables is (surprisingly) through stacks, since variables don't get affected when pushed onto a stack:
^x>z*z>y
And here's another short way, not possible with Execode:
rxv+y
Zero a variable
rxv-x
Addition and subtraction
See the addition/subtraction-only calculator and Fibonacci sequence programs above.
Multiplication
See Deadfish interpreter above.
Stacks/deques
Basic operations
PEEK
*x>y^y>x
DUP
*x>y^y>x^y>x
SWAP
*x>y*x>z^y>x^z>x
As a queue
To use the stack/deque as a queue, use &
whenever you're pushing or popping and your previous operation with the stack/deque is the other one:
^y>x&x*x>z&x ...
External resources
- Implementation in Python, based on the Execode original implementation