Globální proměnné a působnost proměnných

GEL je jazyk s dynamickým rozsahem platnosti. Co to znamená hned vysvětlíme. Je to to, že normální proměnné a funkce mají dynamicky vymezenou platnost. Výjimkou jsou proměnné parametrů, kterou jsou vždy globální.

Podobně jako většina programovacích jazyků, i GEL má různé typy proměnných. Když je proměnná normálně definována ve funkci, je viditelná z této funkce a ze všech funkcí, které jsou z ní volány (všechny kontexty s vyšším číslem). Například předpokládejme, že funkce f definuje proměnnou a a pak volá funkci g. Potom se funkce g může odkazovat na proměnnou a. Ale jakmile dojde k návratu z funkce f, platnost a zaniká. Např. následují kód vypíše 5. Funkce g nemůže být volána z nejvyšší úrovně (mimo funkci f, protože proměnná a pak není definována).

function f() = (a:=5; g());
function g() = print(a);
f();

Pokud definujete proměnnou uvnitř funkce, přepíše jinou proměnnou definovanou ve volající funkci. Například upravíme předchozí kód a napíšeme:

function f() = (a:=5; g());
function g() = print(a);
a:=10;
f();

Tento kód bude stále vypisovat 5. Ale když zavoláte g mimo funkci f, dostanete ve výpise 10. Všimněte si, že nastavení a na 5 uvnitř funkce f nemění hodnotu a ve nejvyšší (globální) úrovni, takže když si nyní ověříte hodnotu a, bude stále 10.

Argumenty funkce jsou úplně stejné jako proměnné definované uvnitř funkce vyjma toho, že jsou inicializovány na hodnotu, která je funkci předána. Kromě této jediné věci se s nimi zachází úplně stejně, jako se všemi ostatními proměnnými definovanými uvnitř funkce.

S funkcemi je zacházeno stejně jako s proměnnými. Proto také můžete lokálně předefinovávat funkce. Normálně (v nejvyšší úrovni) nemůžete předefinovávat chráněné proměnné a funkce. Ale lokálně to udělat můžete. Uvažujme následující situaci:

genius> function f(x) = sin(x)^2
= (`(x)=(sin(x)^2))
genius> function f(x) = sin(x)^2
= (`(x)=(sin(x)^2))
genius> function g(x) = ((function sin(x)=x^10);f(x))
= (`(x)=((sin:=(`(x)=(x^10)));f(x)))
genius> g(10)
= 1e20

Funkce a proměnné definované v nejvyšší úrovni jsou považovány za globální. Jsou viditelné odkudkoliv. Jak již bylo řečeno, následující funkce f nezmění hodnotu a na 5.

a=6;
function f() = (a:=5);
f();

Občas je ale nutné nastavit globální proměnnou uvnitř funkce. Když je takové chování zapotřebí, použijte funkci set. Předáním řetězce nebo identifikátoru s uvozovkou do této funkce se nastaví globální proměnná (v nejvyšší úrovni). Například pro nastavení a na hodnotu 3 byste mohli zavolat:

set(`a,3)

nebo:

set("a",3)

Funkce set nastavuje vždy globální proměnné v nejvyšší úrovni. Neexistuje žádný způsob, jak nastavit lokální proměnnou v nějaké funkce z podřízené funkce. Pokud něco takového potřebujete, musíte jedině použít předání reference (odkazu).

Viz také funkce SetElement a SetVElement.

Takže sesumírováno do technického jazyka: Genius pracuje s různými očíslovanými kontexty. Nejvyšší úroveň je kontext 0 (nula). Kdykoliv se vstoupí do funkce, je kontext zvýšen a když se funkce opouští, je kontext snížen. Funkce nebo proměnná je vždy viditelná ze všech kontextů, které mají vyšší číslo. Když byla proměnná definována v kontextu s nižším číslem, má nastavení této proměnné vliv na vytváření nové lokální proměnné v aktuálním čísle kontextu a tato proměnná bude nyní viditelná ze všech kontextů s vyšším číslem.

Existují i skutečně lokální proměnné, které nejsou vidět nikde jinde, než v aktuálním kontextu. Rovněž při vracení funkcí hodnotou je možné odkazovat na proměnnou, která není viditelná z vyššího kontextu a to může být problém. Viz oddíl Skutečně lokální proměnné a Vracení funkcí.