We are currently working on new rules for what content should and shouldn't be allowed on this website, and are looking for feedback! See Esolang:2026 topicality proposal to view and give feedback on the current draft.
Typeid
Typeid is an esolang invented by User:None1, inspired by Brain-Flak and brainf*ck (not brainfuck). It uses Itanium ABI mangled types as programs. It's pronounced /ˈtaɪpeɪd/.
| Paradigm(s) | procedural, imperative |
|---|---|
| Designed by | User:None1 |
| Appeared in | 2026 |
| Type system | untyped |
| Memory system | stack-based |
| Dimensions | one-dimensional |
| Computational class | Turing-complete |
| Major implementations | Python |
| Influenced by | Itanium ABI, Brain-Flak and brainf*ck |
| File extension(s) | .ty |
Memory
It has a stack with unbounded integers. Popping from an empty stack results in 0.
Commands
Built-in Types
Types that aren't mentioned here but valid in Itanium ABI are NOPs which return 0, and so are names in the std namespace (even if they're made up, like std::fuck) that aren't listed in the table.
| Command | Meaning in Typeid | Meaning in Itanium ABI |
|---|---|---|
| a | Input a character and return it | signed char |
| b | Input an integer and return it | bool |
| c | Pop stack and print as ASCII, returns 0 | char |
| d | Pop stack and print as integer, returns 0 | double |
| e | The same as c, but returns the value popped | long double |
| f | The same as d, but returns the value popped | float |
| g | Returns 0 | __float128 |
| h | Returns 1 | unsigned char |
| i | Pop a and b, return b+a | int |
| j | Pop a and b, return b-a | unsigned int |
| l | Pop a and b, return b*a | long |
| m | Pop a and b, return floor(b/a) | unsigned long |
| n | Pop a and b, return b%a | __int128 |
| o | Pop a and b, return ba | unsigned __int128 |
| s | Swap top stack values, return 0 | short |
| t | Perform a left circular shift on the three top stack values (a b c)->(b c a) | unsigned short |
| v | Pop a and b, return a bitwise AND b | void |
| w | Pop a and b, return a bitwise OR b | wchar_t |
| x | Pop a and b, return a XOR b | long long |
| y | Pop a, return ~a | unsigned long long |
| z | Pop a, return -a | ... |
| Sa | Return a random integer within [0,1] | std::allocator |
| Sb | Pop x, Return a random integer within [1,x] | std::basic_string |
| Sd | Return the current UNIX timestamp as an integer | std::iostream |
| Si | Return the length of the stack | std::istream |
| So | Pop x, return sign(x) | std::ostream |
| Ss | Pop a C-style string (Pop all the numbers until top is zero) from the stack and print it, returns 0 | std::string |
Input commands all return 0 when they encounter EOF or invalid input.
A pointer type (Ptype) to a type pushes the return value of that type onto the stack and returns it.
A const type (Ktype) to a type prints the return value of it as an ASCII character and returns it.
A reference type (Rtype) to a type prints the return value of it as an integer and returns it.
Custom types
Namespace names/Types without template arguments
Their names are simply printed when they're executed. 0 is returned.
Types with template arguments
Their exact names don't matter. Instead, the lengths of them do.
The syntax is like this (spaces are just for clarity):
length name I arguments E
| Length | Meaning |
|---|---|
| 1 | Return the sum of all arguments |
| 2 | Return the product of all argments |
| 3 | While top of stack is nonzero, execute the arguments as code. Return the sum of all runs |
| 4 | While top of stack is zero, execute the arguments as code. Return the sum of all runs |
| 5 | While stack is nonempty, execute the arguments as code. Return the sum of all runs |
| 6 | While stack is empty, execute the arguments as code. Return the sum of all runs |
| 7 | If top of stack is nonzero, execute the arguments as code. Return the sum of all arguments |
| 8 | If top of stack is zero, execute the arguments as code. Return the sum of all arguments |
| 9 | If stack is nonempty, execute the arguments as code. Return the sum of all arguments |
| 10 | If stack is empty, execute the arguments as code. Return the sum of all arguments |
| 11 | Execute the arguments as code forever |
| 12 and above | Execute the arguments as code. Return length-12 (regardless of its arguments' results) |
Examples
Cat
4fourIKaE
Demangled:
four<signed char const>
Hello, world!
N5Hello1_IK2aaI1aIhhhhE1bIhhhhhhhhhhhEEK2bbI1cIhhhhE1dIhhhhhhhhEE5worldK2ccI1eIhhhE1fIhhhhhhhhhhhEEEE
Demangled:
Hello::_<aa<a<unsigned char, unsigned char, unsigned char, unsigned char>, b<unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char>> const, bb<c<unsigned char, unsigned char, unsigned char, unsigned char>, d<unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char>> const, world, cc<e<unsigned char, unsigned char, unsigned char>, f<unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char>> const>
A+B
R1_IbbE
Demangled:
_<bool, bool>&
Truth Machine
1_IRPb3aaaIPfEE
Demangled:
_<bool*&, aaa<float*> >
XKCD Random Number
49choosen_by_fair_dice_roll_guaranteed_to_be_randomIR1aIhhhhEE
Demangled:
choosen_by_fair_dice_roll_guaranteed_to_be_random<a<unsigned char, unsigned char, unsigned char, unsigned char>&>
Computational class
Turing complete, because it can be translated from 3-cell brainfuck:
| 3-cell brainfuck | Typeid |
|---|---|
| begin | 1aIPgPgPg |
> |
tt |
< |
t |
+ |
PhPi |
- |
PhPj |
[ |
3aaaI |
] |
E |
| end | E |
Implementations
In Python. Uses the itanium_demangler package:
from itanium_demangler import *
import sys
from random import *
from time import *
from math import prod
sys.setrecursionlimit(2147483647)
code = parse("_Z1_" + input())
if not code:
raise SyntaxError("Invalid code")
code = code.arg_tys[0]
stack = []
pop = lambda: stack.pop() if stack else 0
get = lambda: stack[-1] if stack else 0
def interpret(code):
if code.kind == "builtin": # built-in types, Sx types are in 'qualname'
match code.value:
case "signed char": # a
c = sys.stdin.read(1)
return ord(c) if c else 0
case "bool": # b
try:
z = int(input())
except:
z = 0
return z
case "char": # c
print(chr(pop()), end="", flush=True)
return 0
case "double": # d
print(pop())
return 0
case "__float80": # e
_ = pop()
print(chr(_), end="", flush=True)
return _
case "float": # f
_ = pop()
print(_)
return _
case "__float128":
return 0
case "unsigned char":
return 1
case "int":
a, b = pop(), pop()
return b + a
case "unsigned int":
a, b = pop(), pop()
return b - a
case "long":
a, b = pop(), pop()
return b * a
case "unsigned long":
a, b = pop(), pop()
return b // a
case "__int128":
a, b = pop(), pop()
return b % a
case "unsigned __int128":
a, b = pop(), pop()
return b**a
case "short":
a, b = pop(), pop()
stack.append(a)
stack.append(b)
return 0
case "unsigned short":
c, b, a = pop(), pop(), pop()
stack.append(b)
stack.append(c)
stack.append(a)
return 0
case "void":
a, b = pop(), pop()
return b & a
case "wchar_t":
a, b = pop(), pop()
return b | a
case "long long":
a, b = pop(), pop()
return b ^ a
case "unsigned long long":
a = pop()
return ~a
case "...":
a = pop()
return -a
case _:
return 0
elif code.kind == "pointer":
_ = interpret(code.value)
stack.append(_)
return _
elif code.kind == "lvalue":
_ = interpret(code.value)
print(_)
return _
elif code.kind == "cv_qual" and "const" in code.qual:
_ = interpret(code.value)
print(chr(_), end="", flush=True)
return _
elif code.kind == "name":
print(code.value, end="", flush=True)
return 0
elif code.kind == "qual_name":
if code.value[0] == "std":
if len(code) == 2 or len(code) == 3 and code[2].kind == "tpl_args":
match code.value[1]:
case "allocator":
return randint(0, 1)
case "basic_string":
return randint(1, pop())
case "iostream":
return int(time())
case "istream":
return len(stack)
case "ostream":
x = pop()
if x < 0:
return -1
elif x > 0:
return 1
return 0
case "string":
while get():
z = pop()
if not z:
break
print(chr(z), end="", flush=True)
case _:
return 0
else:
return 0
else:
has_tpl = False
for i in code.value:
if i.kind == "tpl_args":
has_tpl = True
break
if not has_tpl:
for i in code.value:
print(i.value, end="", flush=True)
else:
for i in range(len(code.value) - 2):
print(code.value[i].value,end='', flush=True)
args = code.value[-1].value
match len(code.value[-2].value):
case 1:
return sum(interpret(i) for i in args)
case 2:
return prod(interpret(i) for i in args)
case 3:
result = 0
while get():
result += sum(interpret(i) for i in args)
return result
case 4:
result = 0
while not get():
result += sum(interpret(i) for i in args)
return result
case 5:
result = 0
while len(stack):
result += sum(interpret(i) for i in args)
return result
case 6:
result = 0
while not len(stack):
result += sum(interpret(i) for i in args)
return result
case 7:
result = 0
if get():
result += sum(interpret(i) for i in args)
return result
case 8:
result = 0
if not get():
result += sum(interpret(i) for i in args)
return result
case 9:
result = 0
if len(stack):
result += sum(interpret(i) for i in args)
return result
case 10:
result = 0
if not len(stack):
result += sum(interpret(i) for i in args)
return result
case 11:
while 1:
for i in args:
interpret(i)
case _:
for i in args:
interpret(i)
return len(code.value[-2]) - 12
else:
return 0
interpret(code)
