Kniha "Pragmatický programátor" (pokud jste ji nečetli, přestaňte číst tento článek a udělejte to hned!) říká, že každý rok bychom se měli naučit jeden nový programovací jazyk.
I když někteří mohou namítat, že je to příliš velké úsilí, všichni bychom se mohli shodnout na tom, že to může být dobrý nápad. Vybrat si nový jazyk, který se chcete naučit, není tak snadné. Nechceme přece věnovat svůj čas něčemu, co možná nikdy v praxi nevyužijeme, nebo ano? Ale možná bychom někdy měli udělat výjimku a naučit se něco jen tak pro radost? Rád bych vám představil jazyk Brainfuck. Je to jazyk, který se naučíte za pár minut, takže není problém investovat příliš mnoho času zbytečně. Také vám mohu slíbit, že řešení jakéhokoli problému pomocí Brainfucku bude stimulovat váš mozek (všechny f*cky jsou jen bonus ;)). Začněme!Podle Wikipedie:
Brainfuck je esoterický programovací jazyk vytvořil v roce 1993 Urban Müller. Jazyk se skládá pouze z osmi jednoduchých příkazů a ukazatele instrukcí. Přestože je plně Turingovsky úplný, není určen k praktickému použití, ale jako výzva a zábava pro programátory.
Přehled jazyků
Představte si nekonečně dlouhou pásku (nebo pásku) složenou z buněk, z nichž každá je inicializována na 0. Existuje také pohyblivý datový ukazatel, který na začátku ukazuje na první buňku. Stejně tak existují dva proudy bajtů pro vstup a výstup. Instrukce se provádějí postupně, jedna po druhé. Po provedení poslední instrukce se stroj zastaví.
přečte jeden bajt ze stdin a uloží jeho hodnotu do aktuální buňky
[
pokud je aktuální buňka 0, přejděte na odpovídající ]
]
přejít na odpovídající [
Všechny znaky kromě ><+-.,[] jsou ignorovány.
Podívejme se na jednoduchý příklad:
,+.
Interpretuje se takto:
přečte jeden bajt a uloží jej do aktuální buňky (buňka0).
zvýšení hodnoty aktuální buňky (buňka0 = buňka0 + 1)
zapsat obsah aktuální buňky na výstup
Výsledkem je načtení jednoho znaku ze vstupu a vypsání dalšího znaku z tabulky ASCII.
Interpret / překladač
Než v Brainfucku napíšeme nějaké užitečné (?) programy, potřebujeme interpret nebo kompilátor. AFAIK žádný oficiální neexistuje, ale to není problém. Neoficiálních jsou na internetu desítky. Mohu doporučit tyto dva:
"Hello World!" by měl být první program, který napíšeme, když se učíme nový jazyk. Napsat ho v Brainfucku je však o něco těžší než v jiných jazycích. Musíme začít něčím jednodušším... Napíšeme program, který na obrazovku vypíše jedno písmeno "H" (tak vzrušující :D):
Jak to funguje? Nastaví hodnotu aktuální buňky na 72 (provede 72 přírůstků) a vypíše ji na obrazovku pomocí "." (H má v ASCII kód 72). Nyní už víte, co máme udělat, abychom na obrazovku vypsali "Hello World!", ale ještě předtím provedeme malou refaktorizaci. Psaní všech těch "+" vyžaduje příliš mnoho psaní a počítání. Můžeme to zkrátit použitím [ a ] pro smyčkování. Pro nastavení hodnoty 72 můžeme např. vytvořit smyčku, která 7x zvýší hodnotu o 10. Tímto způsobem získáme hodnotu 70. Přičtením 2 získáme hodnotu 72. Vypadá to takto:
++++++++++ # nastavte buňku0 na 10
[ # smyčka, dokud buňka0 není 0
- # zmenšit buňku0
> # přesuňte datový ukazatel doprava (buňka1)
+++++++ # zvětšit buňku1 o 7
# přesuňte datový ukazatel doprava (buňka1)
++ # zvýšit o 2
. # vypište výsledek
Připojil jsem komentáře, aby bylo jasné, jak vše funguje. Stejný program bez komentářů:
++++++++++[->+++++++++.
Není to nádhera? 🙂
Ahoj světe!
Vraťme se k našemu programu "Hello World!". Mohli bychom nastavit hodnotu první buňky na 72 (H) a vytisknout ji, hodnotu druhé buňky na 101 (e) a vytisknout ji, hodnotu třetí buňky na 108 a vytisknout ji atd. Zde je implementace tohoto algoritmu:
Ano, jen 1120 bajtů na vypsání "Hello World!"... Ale můžeme to udělat lépe! Místo toho, abychom pro každý znak používali novou buňku, použijeme jen jednu. Pro vytištění písmene "e" (101) můžeme znovu použít hodnotu v buňce0 (72). Můžeme ji zvýšit o jedničku 29krát (101 - 72). Výsledek je následující:
Je to jen 106 bajtů a na konci se vypíše nový řádek! Úžasné.
Obrácení řetězce
Nyní jsme připraveni napsat něco náročnějšího. Napíšeme program, který bude číst řádek ze vstupu a vypisovat ho v opačném pořadí. Prvním problémem je čtení znaků a zastavení na znaku nového řádku. Nezapomeňte, že neexistuje žádný přestávka, pokud nebo jiná podobná prohlášení. Musíme používat [ a ]. Začněme programem, který přečte všechny znaky ze vstupu a vloží je do po sobě jdoucích buněk:
,[>,]
Začíná čtením prvního znaku a pokračuje až do posledního. , operace se vrací 0. V implementaci, která vrací něco jiného než O pro EOF (jazyk toto chování nespecifikuje). Jak tedy můžeme zastavit na znaku nového řádku? Zde je trik:
+[++++++++++>,----------]
Začneme s buňkou0 nastavenou na 1, abychom se ujistili, že se naše smyčka provede alespoň jednou. Ve smyčce zvýšíme hodnotu aktuální buňky o 10, přesuneme datový ukazatel na další buňku, přečteme jeden znak a snížíme jeho hodnotu o 10. Tímto způsobem, pokud je přečten nový znak řádku (10 v ASCII), se program v další iteraci zastaví, jinak se jeho hodnota obnoví přičtením 10.
Po tomto kroku budou naše buňky vypadat takto:
11 C1 C2 C3 0* 0 0 0
Cn je n-tý znak ze vstupu a * je aktuální pozice datového ukazatele. Nyní musíme začít posouvat datový ukazatel doleva a vypisovat všechny buňky, dokud nedosáhneme hodnoty 11. Zde je můj pohled na tuto úlohu:
Doporučuji vám, abyste si to analyzovali sami :-).
Souhrn
Když jsem narazil na Brainfuck, esoterický programovací jazyk, zpočátku jsem ho považoval jen za trik nebo vtip. Tento zvláštní, a jak mnozí možná namítnou, pro mysl obtížný jazyk, mi připadal jako něco, co je určeno pouze pro pobavení. Postupem času se však můj pohled na Brainfuck poměrně výrazně změnil.
Záhadná povaha hry Brainfuck je pro vás výzvou, která vás nutí rozšířit svůj pohled na svět. programovací jazyky. Tento esoterický jazyk umožňuje ocenit krásu a nezbytnost vysokoúrovňových jazyků, na které jsme zvyklí. Upozorňuje na význam abstrakcí, správných konvencí pojmenování a organizovaného uspořádání paměti v oblasti programovacích jazyků. To je něco, co Brainfuck se svým minimalistickým designem sestávajícím z pouhých osmi jednoduchých příkazů neposkytuje.
Brainfuck je kompletní Turingův jazyk, který ještě více zdůrazňuje důležitost jasného a uceleného zdrojového kódu. Přestože je uznáván jako jeden z nejnáročnějších esoterických jazyků pro psaní programů, paradoxně září jako oblíbený jazyk pro začátečníky, kteří si chtějí vytvořit vlastní kompilátor nebo interpret Brainfucku. Důvodem je jednoduchost jeho sady příkazů a skutečnost, že nevyžaduje složité parsování.
Vytvoření programu Brainfuck je jedinečné ve dvou ohledech. Zaprvé si musíte zvyknout na používání jediného ukazatele do paměti, což vás nutí přemýšlet o zdrojovém kódu jinak. A za druhé máte k dispozici "nulovou volbu", což je možnost vynulovat paměťovou buňku, což je vlastnost, která není v jiných formálních programovacích jazycích běžná.
Pokud jde o učení, Brainfuck toho nabízí víc, než se na první pohled zdá. Pokud máte dostatek času a správné myšlení, je možné napsat stejný program mnoha způsoby pomocí různých kódů Brainfucku. Poslední polovina této cesty je o vynalézavosti a hledání nových, kreativních způsobů využití jeho šesti symbolů.
Překladače Brainfuck jsou sice minimalistické, ale umožňují hluboké pochopení toho, jak kód běží, co program tiskne a jaká je základní mechanika Turingova kompletního jazyka. Nakonec Brainfuck není jen další esoterický programovací jazyk. Je to zcela nová dimenze, jiný pohled na to, jak vidíme, chápeme a píšeme programy.