Programovací jazyky z vývojářského pekla (ABEND)

Pavel Tišnovský 10. 5. 2016

Ve třetím článku o esoterických programovacích jazycích si nejdříve popíšeme jazyky založené na substituci řetězců, dále pak jazyky využívající frontu a nezapomeneme ani na specialitku typu Brainfunct.

Obsah

1. Esoterické programovací jazyky založené na substituci řetězců

2. Jazyk /// – nejjednodušší jazyk na světě?

3. Jazyk REGXY

4. Esoterické programovací jazyky založené na použití fronty (queue)

5. Sceql

6. Fueue

7. Esoterické programovací jazyky, v nichž je algoritmus zapsán číslem či dvěma čísly

8. NULL

9. Seed aneb devátá úroveň programátorského pekla

10. Brainfunct

11. Obsah poslední části článku

12. Odkazy na Internetu

1. Esoterické programovací jazyky založené na substituci řetězců

Programovací jazyky, které jsme si prozatím popsali, byly založeny na několika principech. První princip spočívá v implementaci jazyka s příkazy, které se snaží napodobit Turingův stroj, a to buď zcela přímočaře, nebo různými oklikami (namísto pásky se používá dvourozměrné pole apod.). Pravděpodobně nejznámějším esoterickým jazykem patřícím do této kategorie je slavný Brainfuck. Další princip, který se používal v jazycích typu dc, FALSE, Befunge či Whitespace, je založen na použití zásobníku operandů, popř. dokonce většího množství zásobníků. Existují však i další použitelné principy. Zajímavý a pro většinu programátorů (a vlastně i běžných uživatelů) pochopitelný je princip založený na substituci řetězců. Tuto operaci si dokáže představit prakticky každý, kdo někdy použil textový editor či textový procesor, ovšem je skutečně možné vytvořit programovací jazyk, kde se algoritmus zapisuje jen textovými substitucemi? Odpověď nám částečně dají následující kapitoly.

2. Jazyk /// – nejjednodušší jazyk na světě?

Prvním programovacím jazykem, s nímž se dnes setkáme, je jazyk nazvaný /// (což se má číst „slashes“). Jedná se o jazyk, který byl vytvořen Tannerem Swettem v roce 2006. Slashes je založen pouze na textových substitucích, žádná další operace se při zpracování programů neprovádí. Interpret je ve skutečnosti velmi jednoduchý a jeho činnost se dá shrnout do několika pravidel:

  1. Zdrojový kód se zpracovává po znacích.
  2. Pokud interpret nalezne znak \, vypíše následující znak na standardní výstup a oba dva znaky se z programu odstraní.
  3. Pokud interpret nalezne znak /, získá vzorek (pattern) a náhradu (replacement) a provede substituci. Vzorek končí znakem / a i náhrada končí znakem /, což znamená, že celý příkaz vypadá takto: /pattern/replacement/.
  4. Ostatní znaky se pouze vytisknou a odstraní ze zdrojového textu.
  5. Substituce se provádí neustále dokola a pokud po jedné iteraci nedojde ke změně textu, substituce a tím pádem i celý program skončí.

Zajímavé je, že tento jazyk je Turingovsky úplný.

Podívejme se na několik ukázek programů napsaných v jazyce ///:

Program typu „Hello world!“:

Hello, world!

Poznámka: povšimněte si, že zápis programu Hello world! již prakticky nemůže být jednodušší. Proto je celkem zvláštní, že se jazyk /// nepoužívá na školách při seznamování dětí s programováním :-)

Složitější varianta programu typu „Hello world!“:

/foo/Hello, world!//bar/foo/bar

Poznámka: jak tento program pracuje je asi zřejmé: řetězec „bar“ je nejprve nahrazen za „foo“ a „foo“ je nahrazen za „Hello, world!“.

Konverze mezi binární a unární číselnou soustavou:

/1/0*//*0/0**//0//100010

Nekonečná smyčka (na dalších řádcích je ukázáno postupné aplikování substituce):

/foo/foobar/foo
foobar
foobarbar
foobarbarbar
foobarbarbarbar

Generování Fibonacciho posloupnosti:

/
///!/\/.\\0\/,\\,0,\\,1\/\/.\\1\/,\\,0\/\/,\\,\/.\/\/+\\+\/=\\=.\\1-\/
\/=\\=\/+\\+\//!!!!!!!!!/.///+\+///-/\\\///0/1//1/*/++.1

3. Jazyk REGXY

Druhý dnes popisovaný esoterický programovací jazyk se jmenuje poměrně příhodně REGXY. Tento jazyk je již poněkud složitější, než výše popsaný jazyk ///, protože se zde vyskytují regulární výrazy a dokonce hned dva typy příkazů – příkaz pro test a příkaz pro změnu textu. Příkaz provádějící test vypadá následovně:

label/regex/target_label

Pokud vstupní řetězec odpovídá regulárnímu výrazu, je proveden skok na zadané návěští.

Příkaz provádějící náhradu (substituci) vypadá prakticky stejně, ovšem na jeho konec je přidáno lomítko:

label/regex/substitute/

V obou typech příkazů je možné používat prakticky všechny možnosti rozšířených regulárních výrazů (minimálně jedna implementace je napsána v Perlu, takže včetně různých rozšíření přidaných právě Perlem). Povšimněte si, že každý příkaz začíná návěštím, což je libovolný řetězec (který však nesmí obsahovat lomítko). Použití návěští bude dobře patrné na příkladech:

Otočení řetězce:

a/$/_/
b/(.)(.*)_/$2_$1/
c/(.)(.*)_/b
d/_//

Součet dvou binárních čísel (viz http://zzo38computer.org/reg­xy/adbinery.txt):

0+0/(.*)0\+(.*)0\=/$1+$2=0/
0+1/(.*)0\+(.*)1\=/$1+$2=1/
1+0/(.*)1\+(.*)0\=/$1+$2=1/
1+1/(.*)1\+(.*)1\=/$1c+$2=0/
0c+0/(.*)0c\+(.*)0\=/$1+$2=1/
0c+1/(.*)0c\+(.*)1\=/$1c+$2=0/
1c+0/(.*)1c\+(.*)0\=/$1c+$2=0/
1c+1/(.*)1c\+(.*)1\=/$1c+$2=1/
caryblank/c\+\=/+=1/
check/.\+/check2
goto1/./fix
check2/\+[^=]/0+0
fix/(.*)\+(.*)\=/$1$2/

4. Esoterické programovací jazyky založené na použití fronty (queue)

Při zmínce o těch programovacích jazycích, které pro řízení běhu programu, volání funkcí a předávání parametrů i pro vyhodnocování všech výrazů používají zásobník (a nemusí se jednat pouze o esoterické jazyky), si možná některý čtenář položil otázku, zda by nebylo možné namísto zásobníku, tj. datové struktury typu LIFO (Last In, First Out) použít frontu, neboli datovou strukturu typu FIFO (First In, First Out). Fronty sice nejsou pro tento účel příliš praktické, neboť u nich nelze (alespoň ne snadno) provádět lokální výpočty, o to „výhodnější“ však může tato vlastnost být při návrhu esoterického jazyka, kde mnohdy platí, že čím složitější tvorba algoritmů, tím lépe :-) Takže vlastně není divu, že vzniklo již několik (málo) desítek jazyků, v nichž se používají právě fronty.

Připomeňme si jen, že u čistě navržené datové struktury fronta (queue) se prvky přidávají na její začátek a vybírají se z konce fronty, tedy skutečně podle zkratky FIFO. Pokud by se prvky mohly přidávat i číst z obou stran, jednalo by se o oboustrannou (obousměrnou?) frontu, pro niž se vžila zkratka deque (a jak asi očekáváte – existují esoterické jazyky založené i na této mnohem „mocnější“ datové struktuře, tyto jazyky však nejsou tématem dnešního článku).

5. Sceql

Jazyk nazvaný Sceql, jehož autorem je Scott Feeney, se v určitém ohledu podobá nám již dobře známému jazyku Brainfuck, minimálně proto, že základní operace se omezují na zvýšení či snížení hodnoty. Zatímco se však v jazyku Brainfuck všechny zpracovávané hodnoty ukládaly do pole představujícího (poněkud omezenou) implementaci pásky Turingova stroje, používá se v případě jazyka Sceql fronta. Zajímavé je, že tato fronta se nikdy nezmenšuje, protože všechny operace buď zachovávají počet prvků uložených do fronty (změní se však jejich pořadí) nebo dokonce dokážou do fronty jeden prvek přidat. Na začátku je fronta inicializována, protože obsahuje jediný prvek s hodnotou 0. Podívejme se na dostupné příkazy. Není jich moc a skutečně v nich můžeme vidět podobnost s Brainfuckem:

# Příkaz Význam znaku/příkazu
1 = prvek z konce fronty se odstraní a přidá znovu na její začátek
2 snížení hodnoty prvku na konci fronty o jedničku
3 _ zvýšení hodnoty prvku na konci fronty o jedničku
4 \ přeskočí na odpovídající párovou instrukci / pokud je prvek na konci fronty nulový
5 / skočí (bez testu) na odpovídající párový znak \
6 ! do fronty se přidá nový prvek s hodnotou nula
7 & přečtení ze standardního vstupu a uložení hodnoty do fronty (na začátek)
8 * odpovídá příkazu =, ovšem současně se vytiskne znak odpovídající ASCII kódu prvku

Poznámka: povšimněte si, že pokud by se druhý příkaz – (minus) nahradil například znakem @, mohly by se v jediném zdrojovém kódu zkombinovat hned tři různé programy psané v Brainfucku, Whitespace a Sceql.

Demonstračním příkladem samozřejmě musí být program typu „Hello world“. Na tomto příkladu je patrná určitá ukecanost jazyka Sceql:

________________________________________________________________________*
_____________________________*
_______*
*
___*
!=____________________________________________*
=------------*
________*
=--------*
=___*
=------*
=--------*
_*
!==__________*

6. Fueue

Druhým programovacím jazykem, v němž se používá fronta (queue) je jazyk nazvaný Fueue. Autorem tohoto programovacího jazyka je Nathan von Doorn. Zajímavé je, že ve Fueue se fronta používá jak pro uložení zdrojového kódu programu, tak i pro reprezentaci jeho stavu. Při spuštění interpretru tohoto jazyka je ve frontě uložen celý program (sekvence symbolů představujících příkazy) a fronta se postupně plní i hodnotami představujícími stav programu. Interpretace vypadá následovně:

  1. Z fronty se přečte jeden prvek.
  2. Pokud se jedná o číslo, je převedeno na znak (ASCII hodnota) a tento znak je vytištěn.
  3. Pokud se jedná o příkaz/funkci (viz tabulku níže), je funkce zavolána (argumenty jsou samozřejmě ve frontě).
  4. Další symboly jsou vráceny zpět do fronty na začátek.
  5. Pokud se fronta po celé rotaci (předchozí bod) nezmění, načte se znak ze standardního vstupu a jeho kód se uloží na začátek fronty.

Následuje tabulka s podporovanými funkcemi (příkazy):

# Příkaz Význam znaku/příkazu
1 + součet dvou čísel přečtených z fronty
2 změna znaménka čísla přečteného z fronty
3 * součin dvou čísel přečtených z fronty
4 / celočíselný podíl dvou čísel přečtených z fronty
5 % logická negace (0 na 1, ostatní hodnoty na 0)
6 : duplikace prvku (přidá se na začátek fronty!)
7 ~ prohození dvou prvků (opět se přidají na začátek)
8 ! odstranění prvku
9 $ prvek se zduplikuje n-krát
10 ( změna hodnoty na tzv. blok (vlastně seznam chápaný jako prvek)
11 < přidání další hodnoty do bloku
12 ) z bloku se stane seznam hodnot
13 H okamžité ukončení programu

Demonstračním příkladem samozřejmě musí být opět program typu „Hello world“. Ten je primitivní:

72 101 108 108 111 44 32 119 111 114 108 100 33 10 H

Nekonečnou smyčku lze zapsat například takto:

):[):]

Pro čtenáře se skutečně silnými nervy si ukažme interpretr Brainfucku:

):[)~$)[[)[~~~~()+1])][0]$%~~1)][[)~<[)$%+-~)~~~43[)[~:~~~)<[)~~[)$--1[)~]<~~<)<[)$$7--1]][~~~)%[~~)~:(+-
)(~)+-1*256]+-~)255:]~]]!]~][)~<[)$%+-~)~~~45[)[~:~~~)<[)~~[)$--1[)~]<~~<)<[)$$6-%0]][~~~)*[)~(:+~~-)+1]-
--256%):]~]]!]~][)~<[)$%+-~)~~~62[)[~:~~~)<[)~~[)$--1[)~]<~~<)<[)$--%0]][))(($3~)<(]~]]!]~][)~<[)$%+-~)~~
~60[)[~:~~~)<[)~~[)$--1[)~]<~~<)<[)$--%0]][~~)<~~~(]~]]!]~][)~<[)$%+-~)~~~91[)[)~~[)~<[<<<~(~~~<)~][)[))$
12~[:]<<$4~~~<[)$--1[$8~)$4<[)$$6-%0[)]]<]~)~:~]~[!~)~~[)[)$--1[)~~~[)$4~[~):~~[~:~)~[)$$6-%0~~[$~])~]<~]
<~<]$3~[)$~~~%~~)]<~(~~<]~~<<~[0]]<<<:]]]<<[1)]])(~~)~]~~]<~[[~)~~!]):]]!]~][)~<[)$%+-~)~~~93[)[[85 110
109 97 116 99 104 101 100 32 93 46H][)~[))$11~<<~:(~:<]]~)~~~]!]~][)~<[)$%+-~)~~~46[)[~:~~~)<[)~~[)$--1[)
~]<~~<)<[)$%0]][):]~]]!]~][)~<[)$%+-~)~~~44[)[~:~~~)<[~~~~<)[)))~$([[)[~~~~()+1])][0]$%~~1)][)[)[~[0]~])]
[~!]]]~]]!]~][)~<[)$%+-~)~~~33[)[[)~[)[H]]~!][85 110 109 97 116 99 104 101 100 32 91 46H]~)~~~]!]~][)~<[)
$%+-~)~~~0[)[[)~[)[H]]~!][85 110 109 97 116 99 104 101 100 32 91 46H]~)~~~]!]~][)[~:)~]!]:]:]:]:]:]:]:]:]
:]:][0]~]][[0]:[[0]<:[[0]<:]][73 110 116 101 114 110 97 108 32 101 114 114 111 114 58 32 116 111 112 108
101 118 101 108 32 114 117 110 116 105 109 101 32 93 46H])~!][~)]

7. Esoterické programovací jazyky, v nichž je algoritmus zapsán číslem či dvěma čísly

Zajímavou a přitom poměrně malou skupinu esoterických jazyků tvoří takové jazyky v nichž je algoritmus zapsán jediným číslem popř. dvojicí celých čísel. Záleží pouze na tvůrci jazyka, jakým způsobem zajistí jedinečnost mapování celé_číslo:zápis_algoritmu. Samozřejmě je prakticky vždy možné použít defenzivní přístup, v němž se všechny znaky, z nichž se zdrojový kód skládá, prohlásí za (například) dvě číslice v hexadecimálním kódu, to je však málo „esoterické“ resp. málo „šílené“. Proto se můžeme setkat s odlišnými přístupy, v nichž dokonce nechybí ani použití generátoru pseudonáhodných čísel (PRNG), přičemž celý zápis programu je redukován na zadání hodnoty seed (semínko generátoru) a počtu instrukcí (otázkou samozřejmě zůstává, jestli použitý generátor pseudonáhodných čísel dokáže vygenerovat všechny smysluplné posloupnosti a jak se vůbec hodnota seed nalezne).

8. NULL

NULL je programovací jazyk, v němž se jednotlivé instrukce (příkazy) reprezentují prvočísly. To by ještě nebylo nijak hrozné (ostatně stejně lze jakýkoli bajtkód transformovat na prvočísla), ovšem zajímavé je, že stav programu je v interpretru reprezentován dvěma celočíselnými proměnnými x a y. Proměnná x na začátku obsahuje již zmíněný zápis programu (nějaké číslo), proměnná y je nastavena na jedničku. Prozatím se neděje nic šíleného že? Ovšem pokračujme: interpretace probíhá tak, že se pro x zjistí jeho nejmenší prvočíselný faktor (nejmenší prvočíselný dělitel) a následují operace:

  1. Proměnná x je vydělena zjištěným prvočíslem.
  2. Proměnná y je stejným prvočíslem naopak vynásobena.
  3. Provede se operace odpovídající zjištěnému prvočíslu.
  4. Vše se opakuje od začátku.

Následuje tabulka s dostupnými operacemi (povšimněte si, že se skutečně jedná o prvočísla):

Kód Význam
2 výběr další fronty (operandy jsou uloženy ve třech frontách; proč? proto)
3 výběr předchozí fronty
5 prvek z vybrané fronty je převeden na znak (ASCII) a ten je následně vypsán
7 opak předchozího – vstup od uživatele a zápis kódu znaku do vybrané fronty
11 snížení hodnoty prvku na konci vybrané fronty o jedničku. Nikdy nedojde k podtečení pod hodnotu 0.
13 prvek z vybrané fronty je přičten k proměnné y
17 zvýšení hodnoty prvku o hodnotu y modulo 256
19 odstranění prvku z vybrané fronty a jeho přidání na začátek konec další fronty
23 odstranění prvku z vybrané fronty a jeho přidání na začátek konec předchozí fronty
29 pouhé odstranění prvku z vybrané fronty
31 vložení hodnoty y modulo 256 do vybrané fronty
37 podmínka: pokud je fronta prázdná nebo má její prvek nulovou hodnotu, poděl x jeho nejmenším prvočíselným faktorem a vynásob y stejnou hodnotou
41 prohození hodnot v proměnných x a y
43 ukončení běhu programu

Program typu Hello world vypadá takto:

153609393637869503971282839335995386248921743204830348570033
550157913898858976126298703504031567456769368158187308369080
75646108694411913908753341542249057283074613678144889367

Otázkou zůstává, komu a jakým způsobem se podařilo tento program napsat :-)

9. Seed aneb devátá úroveň programátorského pekla

Pravděpodobně nejšílenějším jazykem, o němž se dnes zmíníme, je jazyk nazvaný Seed. Programy zapsané v tomto jazyku jsou tvořeny pouze dvěma celočíselnými hodnotami. První hodnotou je „semínko“ určené pro inicializaci generátoru pseudonáhodných čísel. Druhou hodnotou je délka programu. Interpretace je vlastně na první pohled triviální – nejprve je provedena inicializace generátoru pseudonáhodných čísel (používá se tento generátor s periodou 219937 – 1) a posléze se nechá vygenerovat n bajtů (pouze ASCII hodnoty 32 až 126 + konec řádku), které jsou převedeny na řetězec (n je ono druhé číslo na vstupu). Takto vytvořený řetězec je následně předán interpretru jazyka Befunge. Nic nemůže být jednoduššího že? Jediným maličkým problémem zůstává, jak napsat nějaký smysluplný program… Ovšem kdy se tvůrce programovacího jazyka zabýval takovými prkotinami…

Ve skutečnosti se programy píšou takto:

  1. Nějakým generátorem se zjistí, které instrukce v jazyku Befunge odpovídají řešenému problému.
  2. Následně se metodou hrubé síly pro původní Befunge program zjistí ony dvě celočíselné hodnoty. Složitost je „pouze“ O(96n), kde n je počet znaků programu v Befunge (96 proto, že se prochází všechny kombinace vygenerovaných ASCII znaků s hodnotami 32 až 126 + konec řádku).

Příklad „programu“:

780 983247832

Vygenerováním získáme program v jazyce Befunge:

q
Z?T7yQ
;RyHIw*#{8).'}iN*P{u>z#ok<w\\?!KPrVO7U;b> B
f:rDj':T3'O~J(>BLLxj(>{5n) oM/?nwC{c(OT>Fv?=)tW*`6oL8yCI:D_%4d}:ubmL"6v'(o4^5zi{E3F+vDHk"*}a&nu=S*syIgT>MQ9_vyi'b&i^_xT"WP-"lk=#/r)8%:rG,I?'DTz<)|J]0|^LDakzrx]Gjy=^.0$R<y9#Sl,_K5y@\~z+jSlARiA6D#:gVlmb^>[MQea
(etc)

10. Brainfunct

Dalším zajímavým esoterickým programovacím jazykem, s nímž se dnes ve stručnosti seznámíme, je jazyk nazvaný Brainfunct. Podobnost názvu tohoto jazyka se slavným (a v některých ohledech doposud nepřekonaným) Brainfuckem samozřejmě není náhodná, protože jazyk Brainfunct z originálního Brainfucku převzal šest z osmi původních instrukcí a namísto toho přidal jedinou novou instrukci. Pro porovnání možností obou jazyků si nejdříve v rychlosti zopakujme, kterých osm instrukcí nalezneme v jazyku Brianfuck:

# Příkaz Význam znaku/příkazu
1 > posun ukazatele na „pásce“ doprava na další políčko
2 < posun ukazatele na „pásce“ doleva na předchozí políčko
3 + zvýšení celočíselné hodnoty uložené v aktuálním políčku o 1
4 snížení celočíselné hodnoty uložené v aktuálním políčku o 1
5 . výpis číselné hodnoty (převedené na ASCII znak) uložené v aktuálním políčku
6 , načtení bajtu (znaku) a uložení jeho číselné hodnoty do aktuálního políčka (opět se většinou předpokládá použití ASCII)
7 [ v případě, že je hodnota v aktuálním políčku nulová, přesune se program za odpovídající ]
8 ] v případě, že je hodnota v aktuálním políčku nenulová, přesune se program na odpovídající [

V jazyku Brainfunct došlo k podstatné změně – namísto posledních dvou instrukcí, které vlastně zajišťují možnost řízení běhu programu, tj. tvorbu podmínek (rozvětvení) a programových smyček, byla přidána instrukce @ sloužící pro zavolání určité funkce. Funkce v jazyku Brainfunct však nejsou pojmenované, ovšem současně nejsou ani čistě anonymní, protože každé funkci je přiřazeno celé číslo. Při volání funkce příkazem @ se tedy musí přečíst hodnota z aktuálního políčka na pásce (v poli) a provede se zavolání instrukce, které toto číslo odpovídá. Nová struktura příkazů tedy vypadá následovně:

# Příkaz Význam znaku/příkazu
1 > posun ukazatele na „pásce“ doprava na další políčko
2 < posun ukazatele na „pásce“ doleva na předchozí políčko
3 + zvýšení celočíselné hodnoty uložené v aktuálním políčku o 1
4 snížení celočíselné hodnoty uložené v aktuálním políčku o 1
5 . výpis číselné hodnoty (převedené na ASCII znak) uložené v aktuálním políčku
6 , načtení bajtu (znaku) a uložení jeho číselné hodnoty do aktuálního políčka (opět se většinou předpokládá použití ASCII)
7 @ zavolání funkce, jejíž číslo se nachází na aktuálním políčku

Jakým způsobem se však mohou v jazyce Brainfunct zapisovat funkce? Existují dva způsoby a tím pádem je vlastně možné říci, že existují i dvě varianty tohoto programovacího jazyka. První způsob spočívá v tom, že deklarace funkcí jsou ve zdrojovém kódu (tedy ve shluku znaků <, >, +, -, ., , a @) odděleny znakem lomítka /. Při čtení zdrojového kódu je první funkci (před prvním lomítkem) přiřazeno číslo 1, druhé funkci číslo 2 atd. Poslední funkce, která se ve zdrojovém kódu nalezne, se automaticky spustí při startu programu, tj. jedná se vlastně o funkci „main“:

funkce_číslo_1/funkce_číslo_2/funkce_číslo_3/.../main

Poznámka: těla funkcí jsou samozřejmě tvořena výše zmíněnými sedmi příkazy a volání funkcí je ve skutečnosti skok – žádné parametry se nepředávají a ani se neočekává návrat z volané funkce (tudíž ani žádná návratová hodnota). Ve skutečnosti se tedy funkce spíše podobají pouhým návěštím (labels).

Jak vypadá program psaný tímto způsobem? Podívejme se na implementaci utility cat sloužící pro opisování standardního vstupu na standardní výstup:

>,.<@/+@

Druhý způsob zápisu programů je nepatrně složitější, ale pro psaní složitějších algoritmů pravděpodobně lepší. Při použití tohoto způsobu se těla funkcí uzavírají do kulatých závorek (trošku podobně jako v LISPu) a zajímavé je především to, že se funkce při čtení zdrojového kódu číslují podle své úrovně rekurzivního vnoření. To mj. znamená, že existují funkce, jimž je přiřazeno stejné číslo; to však ve skutečnosti nevadí, protože je vždy zavolána ta funkce, která se nachází ve stejné části „stromu“. Číslování může vypadat takto:

(1) (2) (((5)4)3) (4) (((8)6)(7)5) main

Povšimněte si toho, že funkce na nejvyšší úrovni jsou postupně očíslovány 1, 2, 3, 4 a 5 a navíc žádná funkce, která se nachází ve stejném podstromu, nemá nižší číslo, než funkce nadřazená.

Poznámka: technicky vzato to znamená, že v programovacím jazyku Brainfunct se používá osm či dokonce devět znaků, protože znaky / popř. dvojice ( a ) je nutné využít pro zápis jednotlivých funkcí. Ovšem příkazů je skutečně pouze sedm.

widgety

11. Obsah poslední části článku

Čtvrtý a současně i poslední díl tohoto miniseriálku bude rozdělen na tři části. V části první si popíšeme některé esoterické funkcionální jazyky (resp. jazyky založené na Lambda kalkulu), z nichž nejdůležitějším a nejznámějším je bezesporu jazyk nazvaný příznačně Unlambda. Druhá část bude věnována jazykům simulujícím práci Turingova stroje, ovšem s tím omezením, že se používají pouze binární symboly zapisované na pásku Turingova stroje. Tím pádem se omezuje i množství možných operací prováděných se symboly, většinou je k dispozici jen test na nulu a operace pro inverzi bitu. Mezi takové jazyky patří Boolfuck, Smallfuck a BitChanger. Ve třetí části článku se seznámíme s některými koncepty virtuálních strojů s mnohdy velmi minimalisticky pojatými instrukčními sadami. Takové virtuální stroje se samozřejmě programují v assembleru (nebo v jazyce velmi blízkém assembleru), ovšem vzhledem k použití minimálního počtu instrukcí se může programování stát poměrně složitou (ale tím pádem vlastně i zábavnou) záležitostí.

Mimochodem: víte, že i v balíčku s Vimem se nachází interpret esoterického jazyka? Jedná se o URM neboli Universal Register Machine, což je struktura duální k Turingovu stroji. Více viz (alespoň prozatím):

:e $VIMRUNTIME/macros/urm/examples

12. Odkazy na Internetu

  1. Programming Puzzles & Code Golf – Interpret ///
    http://codegolf.stackexchan­ge.com/questions/37014/in­terpret-pronounced-slashes
  2. Reg Xy
    http://c2.com/cgi/wiki?RegXy
  3. Queue (abstract data type)
    https://en.wikipedia.org/wi­ki/Queue_%28abstract_data_ty­pe%29
  4. Register Machine
    https://en.wikipedia.org/wi­ki/Register_machine
  5. Fueue
    http://esolangs.org/wiki/Fueue
  6. ///
    http://esolangs.org/wiki////
  7. Esolang, the esoteric programming languages wiki
    https://esolangs.org/wiki/Main_Page
  8. Esoteric Topics in Computer Programming
    http://web.archive.org/web/20020609152409/www­.catseye.mb.ca/esoteric/in­dex.html
  9. Programming Languages designed by Wouter von Oortmerssen
    http://strlen.com/programming-languages
  10. Two-dimensional languages
    https://esolangs.org/wiki/Category:Two-dimensional_languages
  11. Piet (homepage)
    http://www.dangermouse.net/e­soteric/piet.html
  12. Piet (na Esolang)
    https://esolangs.org/wiki/Piet
  13. Piet IDE
    http://www.rapapaing.com/blog/?pa­ge_id=6
  14. JSFuck (homepage)
    http://www.jsfuck.com/
  15. JSFuck (na Esolang)
    https://esolangs.org/wiki/JSFuck
  16. JSFuck (na Wikipedii)
    https://en.wikipedia.org/wiki/JSFuck
  17. Malbolge (na Esolang)
    https://esolangs.org/wiki/Malbolge
  18. Malbolge (na Wikipedii)
    https://en.wikipedia.org/wi­ki/Malbolge
  19. Befunge (na Esolang)
    https://esolangs.org/wiki/Befunge
  20. Befunge (na Wikipedii)
    https://en.wikipedia.org/wiki/Befunge
  21. Minifuck
    https://esolangs.org/wiki/Minifuck
  22. XMLfuck
    https://esolangs.org/wiki/XMLfuck
  23. The False Programming Language
    http://strlen.com/false-language
  24. The FALSE Programming Language Manual
    http://strlen.com/false/false.txt
  25. Wouter van Oortmerssen
    http://esolangs.org/wiki/Wou­ter_van_Oortmerssen
  26. dc (computer program)
    https://en.wikipedia.org/wi­ki/Dc_%28computer_program%29
  27. dc (na Esolang)
    http://esolangs.org/wiki/Dc
  28. Whitespace – tutorial
    http://compsoc.dur.ac.uk/whi­tespace/tutorial.html
  29. Programovací jazyk Forth a zásobníkové procesory
    http://www.root.cz/clanky/programovaci-jazyk-forth-a-zasobnikove-procesory/
  30. Seriál Programovací jazyk Forth
    http://www.root.cz/serialy/pro­gramovaci-jazyk-forth/
  31. Programovací jazyk Factor
    http://www.root.cz/clanky/programovaci-jazyk-factor/
  32. Grafický metaformát PostScript
    http://www.root.cz/clanky/graficky-metaformat-postscript/
Našli jste v článku chybu?
Podnikatel.cz: Babišovi se nedá věřit, stěžovali si hospodští

Babišovi se nedá věřit, stěžovali si hospodští

Vitalia.cz: Voda z Vltavy před a po úpravě na pitnou

Voda z Vltavy před a po úpravě na pitnou

Podnikatel.cz: ČSSZ posílá přehled o důchodovém kontě

ČSSZ posílá přehled o důchodovém kontě

Měšec.cz: TEST: Vyzkoušeli jsme pražské taxikáře

TEST: Vyzkoušeli jsme pražské taxikáře

Vitalia.cz: Výživový poradce: Tyhle fešáky jedu celoročně

Výživový poradce: Tyhle fešáky jedu celoročně

120na80.cz: Galerie: Čínští policisté testují českou minerálku

Galerie: Čínští policisté testují českou minerálku

Vitalia.cz: Antibakteriální mýdla nepomáhají, spíš škodí

Antibakteriální mýdla nepomáhají, spíš škodí

Lupa.cz: Jak se prodává firma za miliardu?

Jak se prodává firma za miliardu?

DigiZone.cz: Regionální tele­vize CZ vysílá "Mapu úspěchu"

Regionální tele­vize CZ vysílá "Mapu úspěchu"

Vitalia.cz: Běháte a nehubnete? 6 častých chyb

Běháte a nehubnete? 6 častých chyb

DigiZone.cz: DVB-T2 ověřeno: seznam TV zveřejněn

DVB-T2 ověřeno: seznam TV zveřejněn

Lupa.cz: Proč jsou firemní počítače pomalé?

Proč jsou firemní počítače pomalé?

Vitalia.cz: dTest odhalil ten nejlepší kečup

dTest odhalil ten nejlepší kečup

DigiZone.cz: Budoucnost TV vysílání ve Visegrádu

Budoucnost TV vysílání ve Visegrádu

Lupa.cz: Blíží se konec Wi-Fi sítí bez hesla?

Blíží se konec Wi-Fi sítí bez hesla?

Podnikatel.cz: Udělali jsme velkou chybu, napsal Čupr

Udělali jsme velkou chybu, napsal Čupr

Měšec.cz: „Ukradli“ jsme peníze z bezkontaktních karet

„Ukradli“ jsme peníze z bezkontaktních karet

DigiZone.cz: Sat novinky: NASA Ultra HD (4K)

Sat novinky: NASA Ultra HD (4K)

120na80.cz: Co je padesátkrát sladší než cukr?

Co je padesátkrát sladší než cukr?

Lupa.cz: Jak levné procesory změnily svět?

Jak levné procesory změnily svět?