From Esolang
Jump to navigation Jump to search
Paradigm(s) imperative
Designed by User:GingerIndustries
Appeared in 2021
Memory system cell-based
Computational class Unknown
Reference implementation PyPOL
File extension(s) .pol (source), .abf (bytecode)

APOL (Another Polish Golfing Language or APOL's a Poor Golfing Language) is a golfing language that is based off of Lisp and uses entirely polish notation for its instructions (+ 1 1 instead of 1 + 1.)


APOL has three basic parts: Constants, literals (which can only occur within instructions), and instructions.


APOL's constants are as follows:

Symbol Value
The interpreter's version information
T Boolean true
F Boolean false
X None/null
ĥ The string "Hello, World!"
ô 100
õ 1000
ö 10000
ø 100000
ó 1000000
ò 1000000000
π The interpreter's pi constant
ε The interpreter's e constant
The string "qwertyuiop"
The string "aeiou"
The list
["q" "w" "e" "r" "t" "y" "i" "o" "p"]
A string of all lowercase and capital ASCII letters
The list [a-zA-Z]
A string of all lowercase ASCII letters
A string of all capital ASCII letters
The string "0123456789"
The list [0-9]
A string of all numbers, 1-100 (i.e. "12345678910111213" etc.)
The list [1-100]
A string of all numbers, 0-99
The list [0-99]
⒈-⒔ Successive powers of 2, 16-65536 (i.e. ⒈ = 16, ⒉ = 32, ⒊ = 64, etc.)


There are three literals: numbers, strings, and lists. Numbers are simply typed out (ex. 12.34), however strings and lists require special formatting. Single-word strings (with no spaces) that do not start with an instruction or constant symbol can simply be typed out, however this is discouraged. It is better practice to enclose strings in single or double quotes. (ex. "Hello World!") Lists are enclosed within square brackets, with items separated by spaces. Lists can contain strings and numbers, but not other lists due to laziness parsing engine limitations. (ex. [1 2 3 "some text" 4 5.8])


Instructions are split into two parts: the type and the parameters. The type is always one character long, and always comes first. The parameters are right after the type, in curved brackets. Each parameter is separated by a space. Instructions can accept any literal or another instruction as parameters.

Implicit Printing

If the last instruction (which in this case also includes constants) of a program returns a non-None value, APOL will print that value automatically. This means that instead of writing:


You can write:


This instruction will add the numbers 1 and 2, and print the result.

   p(+(1 2))

Instruction table

This table lists APOL's instructions. The instruction column explains the instruction symbol and the parameters it takes. (* for any type, ~ for string, # for number, ! for boolean, @ for cell index (see below), and [ for list. Parameters after the | symbol are optional. ex. *required any input|#optional number input=10.7) The friendly name can be typed instead of the symbol and will be automatically replaced with the symbol before execution. The returns column expains what the instruction will return, the usage column details what the instruction will do, and the notes column lists additional information.

Instruction Friendly name Usage Returns Notes
p(*text|~end="\n") print Prints text to stdout. None
i(|~prompt) input Reads text from stdin. The inputted text as a string
⧤(|~prompt) floatinput Reads text from stdin and returns a float. The inputted text as a float, or None if it can't be parsed
⧣(|~prompt) intinput Reads text from stdin and returns an integer. The inputted text as an integer, or None if it can't be parsed This instruction will also accept floats, but wil truncate them to integers before returning.
+(#n1 #n2) add Adds two numbers together. The sum of the two numbers
-(#n1 #n2) subtract Subtracts n1 from n2. The difference of the numbers
*(#n1 #n2) multiply Multiplies n1 and n2. The product of the numbers Can also be called as x(#n1 #n2).
/(#n1 #n2) divide Divides n1 from n2. The quotient of the numbers
#n2=2) exponent Raises n1 to the power of n2 . The result of the operation
%(#n1 #n2) modulo Returns the remainder of n1 divided by n2. The result of the operation
∸(#n1 #n2) floordiv Returns n1 divided by n2 and truncates the decimal point. (ex. ∸(5 2) returns 2) The result of the operation
*data=0) write Saves data to the cell at address address. None
@(#address) dynamicread Returns the data at the passed address, similar to superscript numbers but allowing for dynamic reading.
I(#n1) castnumber Converts a string containing a number to a number (ex. I("1") returns 1.0) The converted number
L(~data) castlist Returns the passed string as a list, one item for each character.
Ŀ(~[data) castfloatlist Returns the passed string or list as a list, containing each item converted to a float.
Ľ(~[data) castintlist Returns the passed string or list as a list, containing each item converted to a integer.
b(#num) tobinary Convert the passed number to its binary representation.
B(~binary) frombinary Convert the passed binary number (as a string) to its integer representation.
⌬(~[data) reverse Reverses the passed string or list The reversed string or list
l(~[data) length Returns the length of the passed string or list The length of the string or list
c(~string ~find) stringcontains Returns True if string contains find, False otherwise.
C(~[data ~find) count Returns the number of occurences of find in data
⌕(~string ~find) stringfind Returns the index of the first occurrence of find in string, or -1 if it can't be found. The index of the first occurrence
s(~string |~sep=" ") stringsplit Splits the passed string at every occurence of sep. A list of the split strings (not including the seperator) The behavior of this instuction with an empty separator is undefined.
j([list |~sep="") stringjoin Joins the items in list together in a string, seperated by sep. The joined string This instruction will convert all items in the list to strings before joining them.
R(~instr ~toreplace ~replacewith) stringreplace Replaces all occurrences of toreplace in instr with replacewith. The replaced string
V(~input #start |#end=None) substring Returns the characters in the string input starting at start and ending at end. If end is not passed, start will be interpreted as end. (i.e. V("hello" 2) returns "llo")
↑(~input) uppercase Returns the string input with all characters converted to uppercase.
↓(~input) lowercase Returns the string input with all characters converted to lowercase.
↶(~string) tocodepoint Returns the codepoint of the first character in the passed string.
↷(#codepoint) tochar Returns the character corresponding to the passed codepoint. The behavior of this instruction with invalid codepoints is undefined.
t(*data) caststring Returns data represented as a string.
a(@address *value) append Appends value to the list at address address. None This method can append lists to lists, despite this not being possible when lists are created normally.
⊕([#in) sum If the input is a list, return all items in the list added together. If it is an integer (floats will be converted to integers), return the sum of its digits. The total The behavior of this instruction with a list containing non-number values is undefined.
m([in) min Returns the smallest item in the passed list.
M([in) max Returns the largest item in the passed list.
z([in) contig Returns every contiguous sublist of the passed list.
A(~code) apolexec Executes one APOL instruction (passed to it as a string) and returns the result.
g([list |#index=0) listget Returns the item at index index in the passed list.
S([list *value |#index=0) listset Sets the item at inxed index in the passed list The modified list
P([list |#index=0) listpop Removes the item at index index from the passed list The modified list
r([list *value) listremove Removes the first occurence of item from list The modified list
~([list) sort Returns a sorted version of the input list
⭳([list) listflatten Turns a list of lists (a 2d list) into a 1d list. The modified list
w(!condition {instructions}) while While the instruction condition retuns True, execute the passed instructions. None After the condition, a theoretically unlimited number of instructions may be passed, separated by spaces. (ex. w(T p("1") p("2")) will print 1 and 2 for infinity)
W(!condition {instructions}) precheckwhile Works exactly like while, except it checks its condition once before the loop starts. This means this loop can exit immidiately, compared to the normal while which will always run at least once.
f(#[iter {instructions}) for If iter is a number, execute the passed instructions that many times. If it is a list, execute the passed instructions once for each item in the list. (only really useful when used with ∋, see below) None The instructions parameter behaves the same as while. (see above note)
ⅎ(#[iter {instructions}) onefor Works exactly like for, but starts its counter at 1.
ƒ(#[iter *instruction) listfor Works exactly like for, but only takes one instruction and returns each return value of that instruction as a list. (ex. ƒ(10 *(∈ 2)) will return [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]) The list of return values
Ƒ(#[iter *instruction) onelistfor Works exactly like listfor, but starts counting at 1 instead of 0.
ḟ(#start #end {instructions} startendfor Works like for, however it allows you to specify a start and an end to count from. None In this for, forcounter will always start at 0 but foritem will contain the current number. (i.e. ḟ(12 15 p(∈) p(∋)) will print 0 12 1 13 2 14)
ℱ([list *instruction) filter Returns a list composed of every item in the input list which makes the instruction return true.
∈ and ∋ loopcounter (∈) and loopitem (∋) When iterating through a list, ∈ will return the index in the list (starting from 0) and ∋ will return the item at that index. When iterating through a number, both ∈ and ∋ will return the iterations passed (starting at 0.) When used in a while loop, ∈ will return the iterations passed and ∋ will return the loop's condition. The counter and item The behavior of these instructions when outside a loop is undefined.
foriterator Returns the item the for loop containing it is iterating through. (ex. f(3 p(⋒)) will print 3 3 3.
ifitem Inside an if statement, returns the result of the statement passed as the condition. The behavior of these instructions when outside an if statement is undefined.
?(!condition *iftrue |*iffalse=None) if If condition evaluates to True, execute the instruction iftrue, otherwise execute the instruction iffalse. None Because this instruction only can have one other instruction passed to iftrue or iffalse, it is advised to use it with the : instruction.
¿(!condition *iftrue *iffalse=None) returnif Works the same as ?, but returns the value of the instruction (or literal) that got executed.
:({instructions}) function When executed, will execute every instruction passed to it. None
⍭(#delay) delay Pauses program execution for delay seconds. None
<(#n1 #n2) lessthan Returns whether n1 is less than n2.
>(#n1 #n2) greaterthan Returns whether n1 is greater than n2.
≤(#n1 #n2) lessorequal Returns whether n1 is less than or equal to n2.
≥(#n1 #n2) greaterorequal Returns whether n1 is greater than or equal to n2.
=(*n1 *n2) equal Returns whether n1 equals n2.
≠(*n1 *n2) unequal Returns whether n1 does not equal n2.
≬(#n1 #n2 #n3) between Returns whether n1 is between n2 and n3.
∆(@address |#amount=1) increase Increases the value at the passed address by amount. None The behavior of this instruction if the value is not a number is undefined.
∇(@address |#amount=1) decrease Decreases the value at the passed address by 1. None The behavior of this instruction if the value is not a number is undefined.
≐(#number) geteven Returns if the passed number is even.
∓(#number) getsign Returns if the passed number is positive.
⌿(#number) abs Returns the absolute value of the passed number.
∿(#n1 #n2) randnum Returns a random number between n1 and n2 inclusive.
randfloat Returns a number between 0 and 1 inclusive.
≖(#n1) round Rounds the passed number and returns it.


Note that F1 is a space character.

0 1 2 3 4 5 6 7 8 9 A B C D E F
0 a b c d e f g h i j k l m n o p
1 q r s t u v w x y z A B C D E
2 F G H I J K L M N O P Q R S T U
3 V W X Y Z + - * / % ^ ? : < > =
4 & ! | " ' ( ) 0 1 2 3 4 5 6 7 8
5 9 [ ] ¹ ² ³ Ŀ Ľ
6 @ # $ _ \ , ; { } ` ~
7 ƒ ¿
8 \n
9 ĥ ô õ ö ø ó ò π ε


APOL stores data in an infinite list of cells, numbered 0-∞. Each cell can contain any literal data type, and their values are acessed using superscript numbers. For example , to print the value in cell 12 you would write:


However, you do not use superscript numbers to refer to cells. This is valid:

   v(1 "hello")

This is not:

   v(¹ "hello")

Example Programs

Hello World:


Fibonacci sequence: (input what number to print up to)

   v(1 I(i));v(2 0);v(3 1);v(4 0);w(<(² ¹) p(²) v(4 ²) v(2 ³) v(3 +(⁴ ³)))

99 bottles of beer:

   v(0 99);v(1 " bottles of beer");w(>(⁰ 1) p(+(+(t(⁰) +(¹ +(" on the wall, " +(t(⁰) +(¹ "."))))) +("\nTake one down, pass it around, " +(t(-(⁰ 1)) +(¹ " on the wall.\n"))))) ∇(0)) 


   ⅎ(⧣ ?(&(=(%(∈ 3) 0) =(%(∈ 5) 0)) p("FizzBuzz") ?(!(%(∈ 3)) p("Fizz") ?(!(%(∈ 5)) p("Buzz") p(∈)))))

Collatz Conjecture:

   v(0 ⧣);w(>(⁰ 1) p(⁰) ?(≐(⁰) v(0 /(⁰ 2)) v(0 +(*(⁰ 3) 1))))